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