Added preprocessor conditionals to support ROOT > 5.11.2.
[u/mrichter/AliRoot.git] / EVE / Alieve / TPCSector2DGL.cxx
1 // $Header$
2
3 #include "TPCSector2DGL.h"
4
5 #include <Alieve/TPCData.h>
6
7 #include <TStopwatch.h>
8
9 #include <GL/gl.h>
10
11 using namespace Reve;
12 using namespace Alieve;
13 using namespace std;
14
15   // This can be optimized to non-pow-2 values once everybody has GL 1.4.
16
17 const Int_t TPCSector2DGL::fgkTextureWidth    = 256;
18 const Int_t TPCSector2DGL::fgkTextureHeight   = 128;
19 const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128;
20
21 /**************************************************************************/
22
23 TPCSector2DGL::TPCSector2DGL() : TGLObject()
24 {
25   fSector     = 0;
26   fSectorData = 0;
27
28   fImage   = 0;
29   fTexture = 0;
30   fRTS     = 0;
31 }
32
33 TPCSector2DGL::~TPCSector2DGL()
34 {
35   if(fImage)   delete fImage;
36   if(fTexture) glDeleteTextures(1, &fTexture);
37 }
38
39 /**************************************************************************/
40
41 Bool_t TPCSector2DGL::SetModel(TObject* obj)
42 {
43 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
44   if(set_model(obj, "Alieve::TPCSector2D")) {
45 #else
46   if(SetModelCheckClass(obj, "Alieve::TPCSector2D")) {
47 #endif
48     fSector = (TPCSector2D*) fExternalObj;
49     return true;
50   }
51   return false;
52 }
53
54 void TPCSector2DGL::SetBBox()
55 {
56 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
57   set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
58 #else
59   SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
60 #endif
61 }
62
63 /**************************************************************************/
64
65 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& /*flags*/) const
66 {
67   // Actual GL drawing.
68
69   // printf("TPCSector2DGL::DirectDraw \n");
70
71   if(fSector->fTPCData == 0)
72     fSectorData = 0;
73   else
74     fSectorData = fSector->fTPCData->GetSectorData(fSector->fSectorID);
75
76   if(fRTS < fSector->fRTS && fSectorData != 0) {
77     CreateTexture();
78     fRTS = fSector->fRTS;
79   }
80
81   glPushAttrib(GL_CURRENT_BIT      | GL_DEPTH_BUFFER_BIT |
82                GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT       | GL_POLYGON_BIT);
83
84   glDisable(GL_LIGHTING);
85   glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
86   glEnable(GL_COLOR_MATERIAL);
87   glDisable(GL_CULL_FACE);
88
89   // Display digits
90   if(fSectorData != 0) {
91
92     const TPCSectorData::SegmentInfo&  iSeg = TPCSectorData::GetInnSeg();
93     const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
94     const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
95
96     if(fSector->fUseTexture) {
97       //texture
98       glEnable(GL_BLEND);
99       glDepthMask(GL_FALSE);
100       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
101
102       glPolygonOffset(2,2);
103       glEnable(GL_POLYGON_OFFSET_FILL);
104
105       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
106       glBindTexture(GL_TEXTURE_2D, fTexture);
107       glEnable(GL_TEXTURE_2D);
108
109       if(fSector->fRnrInn)
110         DisplayTexture(iSeg.GetPadWidth(),  iSeg.GetPadHeight(),  iSeg.GetRLow(),
111                        iSeg.GetNMaxPads(),  iSeg.GetNRows(),
112                        0,                   0);
113       if(fSector->fRnrOut1)
114         DisplayTexture(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
115                        o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
116                        iSeg.GetNMaxPads(),  0);
117       if(fSector->fRnrOut2)
118         DisplayTexture(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
119                        o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
120                        0,                   o1Seg.GetNRows());
121
122       glDisable(GL_TEXTURE_2D);
123     } else {
124       if(fSector->fRnrInn)
125         DisplayQuads(iSeg.GetPadWidth(),  iSeg.GetPadHeight(),  iSeg.GetRLow(),
126                      iSeg.GetNMaxPads(),  iSeg.GetNRows(),
127                      0,                   0);
128       if(fSector->fRnrOut1)
129         DisplayQuads(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
130                      o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
131                      iSeg.GetNMaxPads(),    0);
132       if(fSector->fRnrOut2)
133         DisplayQuads(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
134                      o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
135                      0,                   o1Seg.GetNRows());
136     }
137   }
138
139   // Display frame
140   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
141   DisplayFrame();
142
143   glPopAttrib();
144 }
145
146 /**************************************************************************/
147 // Data import
148 /**************************************************************************/
149
150 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
151                                Int_t row, Int_t col_off) const
152 {
153   Int_t    padVal;
154   Int_t    time, val;   
155
156   Int_t    minTime = fSector->fMinTime;
157   Int_t    maxTime = fSector->fMaxTime;
158   Bool_t   halfBorderTime = ((maxTime - minTime) % 2 == 0);
159
160   UChar_t* img_pos = GetRowCol(row, col_off);
161   while (iter.NextPad()) {
162     padVal = 0; 
163
164     while (iter.Next()) {
165       time = iter.Time();
166       val  = iter.Signal();
167
168       if(time < minTime || time > maxTime)
169         continue;
170
171       if(fSector->fShowMax) {
172         if(val > padVal) {
173           padVal = val;
174         }
175       } else {
176         if(halfBorderTime && (time == minTime || time == maxTime))
177           padVal += val/2;
178         else
179           padVal += val;
180       }
181     }
182
183     if(fSector->fShowMax == kFALSE && fSector->fAverage) {
184       padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
185     }
186     padVal = TMath::Min(padVal, fSector->fMaxVal);
187     if(padVal > fSector->fThreshold)
188       fSector->SetupColor(padVal, img_pos);
189     img_pos += 4;
190   }
191 }
192
193 /**************************************************************************/
194
195 void TPCSector2DGL::CreateTexture() const
196 {
197   if (fImage == 0 ) {
198     fImage = new UChar_t[fgkTextureByteSize];
199     glGenTextures(1, &fTexture);
200   }
201   memset(fImage, 0, fgkTextureByteSize);
202
203   Int_t rowOff[3], colOff[3];
204   Bool_t isOn[3];
205   rowOff[0] = 0;
206   rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
207   colOff[0] = colOff[2] = 0;
208   colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
209   isOn[0] = fSector->fRnrInn;
210   isOn[1] = fSector->fRnrOut1;
211   isOn[2] = fSector->fRnrOut2;
212
213   // Loop over 3 main segments
214   for (Int_t sId = 0; sId <= 2; ++sId) {
215     if(isOn[sId] == kFALSE)
216       continue;
217     const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId);
218     for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
219       TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
220       Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2;
221       LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
222     }
223   }
224
225   glBindTexture  (GL_TEXTURE_2D, fTexture);
226   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
227   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
228   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
229   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
230   // glTexEnvf      (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,   GL_MODULATE); // Lightning is off anyway.
231   glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
232                   0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
233
234 }
235
236 /**************************************************************************/
237 // Data display
238 /**************************************************************************/
239
240 void TPCSector2DGL::DisplayTexture(Float_t padW,     Float_t padH, Float_t startR,
241                                    Int_t numMaxPads, Int_t numRows, 
242                                    Int_t startCol,   Int_t startRow) const
243 {
244   Float_t w  = numMaxPads*padW/2;
245   Float_t u1 = (Float_t) startCol / fgkTextureWidth;
246   Float_t v1 = (Float_t) startRow / fgkTextureHeight;
247   Float_t u2 = u1 + (Float_t) numMaxPads / fgkTextureWidth;
248   Float_t v2 = v1 + (Float_t) numRows    / fgkTextureHeight;
249
250   glBegin(GL_QUADS);  
251   glTexCoord2f(u1, v1);  glVertex2f(-w, startR);
252   glTexCoord2f(u1, v2);  glVertex2f(-w, startR + numRows*padH);
253   glTexCoord2f(u2, v2);  glVertex2f( w, startR + numRows*padH);
254   glTexCoord2f(u2, v1);  glVertex2f( w, startR);
255   glEnd();
256 }
257
258 /**************************************************************************/
259
260 void TPCSector2DGL::DisplayQuads(Float_t padW,     Float_t padH, Float_t startR,
261                                  Int_t numMaxPads, Int_t numRows, 
262                                  Int_t startCol,   Int_t startRow) const
263 {
264   UChar_t *pix;
265   Float_t y_d, y_u;
266   Float_t x_off, x;
267
268   glBegin(GL_QUADS);
269   for (Int_t row=0; row<numRows; row++) {
270     y_d = startR + row*padH;
271     y_u = y_d + padH;
272     x_off = -numMaxPads*padW/2;
273     pix = GetRowCol(row + startRow, startCol);
274     for (Int_t pad=0; pad<numMaxPads; pad++, pix+=4) {
275       x = x_off + pad*padW;
276       if (pix[3] != 0) {
277         glColor4ubv(pix);
278         glVertex2f(x+padW, y_d);
279         glVertex2f(x,      y_d);
280         glVertex2f(x,      y_u);
281         glVertex2f(x+padW, y_u);
282       }
283     }
284   }
285   glEnd();
286 }
287
288 /**************************************************************************/
289 // Frame drawing
290 /**************************************************************************/
291
292 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
293 {
294   Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
295   Float_t y  = s.GetRLow();
296   glVertex2f(x, y);
297   for (Int_t i=0; i<s.GetNYSteps(); ++i) {
298     y = s.GetYStep(i);
299     glVertex2f(x, y);
300     x -= s.GetPadWidth();
301     glVertex2f(x, y);
302   }
303   y =  s.GetRLow() + s.GetNRows()*s.GetPadHeight();
304   glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
305 }
306
307 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s) 
308 {
309   Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
310   Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
311   glVertex2f(x, y);
312   for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
313     y =  s.GetYStep(i);
314     glVertex2f(x, y);
315     x -= s.GetPadWidth();
316     glVertex2f(x, y);
317   }
318   y = s.GetRLow();
319   glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
320 }
321
322 void TPCSector2DGL::DisplayFrame() const
323 {
324   UChar_t col[4];
325   ColorFromIdx(fSector->fFrameColor, col);
326   glColor4ubv(col);
327
328   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
329   if(fSector->fRnrInn) {
330     glBegin(GL_POLYGON);
331     TraceStepsUp  (TPCSectorData::GetInnSeg());
332     TraceStepsDown(TPCSectorData::GetInnSeg());
333     glEnd();
334   }
335   if(fSector->fRnrOut1) {
336     glBegin(GL_POLYGON);
337     TraceStepsUp  (TPCSectorData::GetOut1Seg());
338     TraceStepsDown(TPCSectorData::GetOut1Seg());
339     glEnd();
340   }
341   if(fSector->fRnrOut2) {
342     glBegin(GL_POLYGON);
343     TraceStepsUp  (TPCSectorData::GetOut2Seg());
344     TraceStepsDown(TPCSectorData::GetOut2Seg());
345     glEnd();
346   }
347 }