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