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