2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
4 /**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
7 * full copyright notice. *
8 **************************************************************************/
10 #include "AliEveTPCSector2DGL.h"
12 #include <EveDet/AliEveTPCData.h>
14 #include <TGLRnrCtx.h>
15 #include <TGLSelectRecord.h>
16 #include <TGLIncludes.h>
20 //______________________________________________________________________________
21 // AliEveTPCSector2DGL
24 ClassImp(AliEveTPCSector2DGL)
26 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
28 const Int_t AliEveTPCSector2DGL::fgkTextureWidth = 256;
29 const Int_t AliEveTPCSector2DGL::fgkTextureHeight = 128;
30 const Int_t AliEveTPCSector2DGL::fgkTextureByteSize = 4*256*128;
32 /******************************************************************************/
34 AliEveTPCSector2DGL::AliEveTPCSector2DGL() :
45 AliEveTPCSector2DGL::~AliEveTPCSector2DGL()
47 if(fImage) delete fImage;
48 if(fTexture) glDeleteTextures(1, &fTexture);
51 /******************************************************************************/
53 Bool_t AliEveTPCSector2DGL::SetModel(TObject* obj, const Option_t* /*opt*/)
55 if(SetModelCheckClass(obj, AliEveTPCSector2D::Class())) {
56 fSector = (AliEveTPCSector2D*) fExternalObj;
62 void AliEveTPCSector2DGL::SetBBox()
64 SetAxisAlignedBBox(((AliEveTPCSector2D*)fExternalObj)->AssertBBox());
67 /******************************************************************************/
69 void AliEveTPCSector2DGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/,
70 TGLSelectRecord & rec)
72 if (rec.GetN() != 3) return;
73 Int_t row = rec.GetItem(1);
74 Int_t pad = rec.GetItem(2);
75 if (row < 0 || row >= AliEveTPCSectorData::GetNAllRows()) return;
76 if (pad < 0 || pad >= AliEveTPCSectorData::GetNPadsInRow(row)) return;
77 fSector->PadSelected(row, pad);
80 /******************************************************************************/
82 void AliEveTPCSector2DGL::DirectDraw(TGLRnrCtx& rnrCtx) const
86 // printf("AliEveTPCSector2DGL::DirectDraw \n");
88 fSectorData = fSector->GetSectorData();
90 if(fRTS < fSector->fRTS && fSectorData != 0) {
95 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
96 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
98 glDisable(GL_LIGHTING);
99 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
100 glEnable(GL_COLOR_MATERIAL);
101 glDisable(GL_CULL_FACE);
104 if(fSectorData != 0) {
106 const AliEveTPCSectorData::SegmentInfo& iSeg = AliEveTPCSectorData::GetInnSeg();
107 const AliEveTPCSectorData::SegmentInfo& o1Seg = AliEveTPCSectorData::GetOut1Seg();
108 const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg();
110 if(rnrCtx.SecSelection()) {
112 if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0);
113 if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0);
114 if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows());
118 if(fSector->fUseTexture) {
121 glDepthMask(GL_FALSE);
122 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
124 glPolygonOffset(2,2);
125 glEnable(GL_POLYGON_OFFSET_FILL);
127 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
128 glBindTexture(GL_TEXTURE_2D, fTexture);
129 glEnable(GL_TEXTURE_2D);
131 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
132 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
133 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
135 glDisable(GL_TEXTURE_2D);
137 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
138 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
139 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
141 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
150 /******************************************************************************/
152 /******************************************************************************/
154 void AliEveTPCSector2DGL::LoadPadrow(AliEveTPCSectorData::RowIterator& iter,
155 Int_t row, Int_t col_off) const
160 Int_t minTime = fSector->fMinTime;
161 Int_t maxTime = fSector->fMaxTime;
162 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
164 UChar_t* img_pos = GetRowCol(row, col_off);
165 while (iter.NextPad()) {
168 while (iter.Next()) {
172 if(time < minTime || time > maxTime)
175 if(fSector->fShowMax) {
180 if(halfBorderTime && (time == minTime || time == maxTime))
187 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
188 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
190 padVal = TMath::Min(padVal, fSector->fMaxVal);
191 if(padVal > fSector->fThreshold)
192 fSector->ColorFromArray(padVal, img_pos);
197 /******************************************************************************/
199 void AliEveTPCSector2DGL::CreateTexture() const
202 fImage = new UChar_t[fgkTextureByteSize];
203 glGenTextures(1, &fTexture);
205 memset(fImage, 0, fgkTextureByteSize);
207 Int_t rowOff[3], colOff[3];
210 rowOff[1] = rowOff[2] = -AliEveTPCSectorData::GetSeg(1).GetFirstRow();
211 colOff[0] = colOff[2] = 0;
212 colOff[1] = AliEveTPCSectorData::GetSeg(0).GetNMaxPads();
213 isOn[0] = fSector->fRnrInn;
214 isOn[1] = fSector->fRnrOut1;
215 isOn[2] = fSector->fRnrOut2;
217 fSector->SetupColorArray();
219 // Loop over 3 main segments
220 for (Int_t sId = 0; sId <= 2; ++sId) {
221 if(isOn[sId] == kFALSE)
223 const AliEveTPCSectorData::SegmentInfo& sInfo = AliEveTPCSectorData::GetSeg(sId);
224 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
225 AliEveTPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
226 Int_t offset = (sInfo.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(row))/2;
227 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
231 glBindTexture (GL_TEXTURE_2D, fTexture);
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
236 glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
237 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
238 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
242 /******************************************************************************/
244 /******************************************************************************/
246 void AliEveTPCSector2DGL::DisplayTexture(const AliEveTPCSectorData::SegmentInfo& seg,
247 Int_t startCol, Int_t startRow) const
249 Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2;
250 Float_t y1 = seg.GetRLow();
251 Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
253 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
254 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
255 Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth;
256 Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight;
259 glTexCoord2f(u1, v1); glVertex2f(-w, y1);
260 glTexCoord2f(u1, v2); glVertex2f(-w, y2);
261 glTexCoord2f(u2, v2); glVertex2f( w, y2);
262 glTexCoord2f(u2, v1); glVertex2f( w, y1);
266 /******************************************************************************/
268 void AliEveTPCSector2DGL::DisplayQuads(const AliEveTPCSectorData::SegmentInfo& seg,
269 Int_t startCol, Int_t startRow) const
273 Float_t padW = seg.GetPadWidth();
274 Float_t padH = seg.GetPadHeight();
277 for (Int_t row=0; row<seg.GetNRows(); row++) {
278 y_d = seg.GetRLow() + row*padH;
280 x_off = -seg.GetNMaxPads()*padW/2;
281 Int_t tpcRow = row + seg.GetFirstRow();
282 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
283 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
284 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
285 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
286 x = x_off + pad*padW;
289 glVertex2f(x+padW, y_d);
292 glVertex2f(x+padW, y_u);
299 void AliEveTPCSector2DGL::DisplayNamedQuads(const AliEveTPCSectorData::SegmentInfo& seg,
300 Int_t startCol, Int_t startRow) const
304 Float_t padW = seg.GetPadWidth();
305 Float_t padH = seg.GetPadHeight();
308 for (Int_t row=0; row<seg.GetNRows(); row++) {
309 y_d = seg.GetRLow() + row*padH;
311 x_off = -seg.GetNMaxPads()*padW/2;
312 Int_t tpcRow = row + seg.GetFirstRow();
314 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
315 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
316 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
318 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
319 x = x_off + pad*padW;
320 if (pix[3] != 0 || fSector->fPickEmpty) {
321 glLoadName(pad - deltaPad);
323 glVertex2f(x+padW, y_d);
326 glVertex2f(x+padW, y_u);
335 /******************************************************************************/
337 /******************************************************************************/
339 void AliEveTPCSector2DGL::TraceStepsUp(const AliEveTPCSectorData::SegmentInfo& s)
341 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
342 Float_t y = s.GetRLow();
344 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
347 x -= s.GetPadWidth();
350 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
351 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
354 void AliEveTPCSector2DGL::TraceStepsDown(const AliEveTPCSectorData::SegmentInfo& s)
356 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
357 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
359 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
362 x -= s.GetPadWidth();
366 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
369 void AliEveTPCSector2DGL::DisplayFrame() const
372 TEveUtil::TEveUtil::ColorFromIdx(fSector->fFrameColor, col);
375 if(fSector->fRnrInn) {
377 TraceStepsUp (AliEveTPCSectorData::GetInnSeg());
378 TraceStepsDown(AliEveTPCSectorData::GetInnSeg());
381 if(fSector->fRnrOut1) {
383 TraceStepsUp (AliEveTPCSectorData::GetOut1Seg());
384 TraceStepsDown(AliEveTPCSectorData::GetOut1Seg());
387 if(fSector->fRnrOut2) {
389 TraceStepsUp (AliEveTPCSectorData::GetOut2Seg());
390 TraceStepsDown(AliEveTPCSectorData::GetOut2Seg());