]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveTPCSector2DGL.cxx
Temporary fix to avoid xrootd thrashing
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTPCSector2DGL.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
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  **************************************************************************/
9
10 #include "AliEveTPCSector2DGL.h"
11
12 #include <EveDet/AliEveTPCData.h>
13
14 #include <TGLRnrCtx.h>
15 #include <TGLSelectRecord.h>
16 #include <TGLIncludes.h>
17
18 using namespace std;
19
20 //______________________________________________________________________________
21 // AliEveTPCSector2DGL
22 //
23
24 ClassImp(AliEveTPCSector2DGL)
25
26 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
27
28 const Int_t AliEveTPCSector2DGL::fgkTextureWidth    = 256;
29 const Int_t AliEveTPCSector2DGL::fgkTextureHeight   = 128;
30 const Int_t AliEveTPCSector2DGL::fgkTextureByteSize = 4*256*128;
31
32 /******************************************************************************/
33
34 AliEveTPCSector2DGL::AliEveTPCSector2DGL() :
35   TGLObject(),
36
37   fSector     (0),
38   fSectorData (0),
39
40   fImage   (0),
41   fTexture (0),
42   fRTS     (0)
43 {}
44
45 AliEveTPCSector2DGL::~AliEveTPCSector2DGL()
46 {
47   if(fImage)   delete fImage;
48   if(fTexture) glDeleteTextures(1, &fTexture);
49 }
50
51 /******************************************************************************/
52
53 Bool_t AliEveTPCSector2DGL::SetModel(TObject* obj, const Option_t* /*opt*/)
54 {
55   if(SetModelCheckClass(obj, AliEveTPCSector2D::Class())) {
56     fSector = (AliEveTPCSector2D*) fExternalObj;
57     return kTRUE;
58   }
59   return kFALSE;
60 }
61
62 void AliEveTPCSector2DGL::SetBBox()
63 {
64   SetAxisAlignedBBox(((AliEveTPCSector2D*)fExternalObj)->AssertBBox());
65 }
66
67 /******************************************************************************/
68
69 void AliEveTPCSector2DGL::ProcessSelection(TGLRnrCtx       & /*rnrCtx*/,
70                                      TGLSelectRecord & rec)
71 {
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);
78 }
79
80 /******************************************************************************/
81
82 void AliEveTPCSector2DGL::DirectDraw(TGLRnrCtx& rnrCtx) const
83 {
84   // Actual GL drawing.
85
86   // printf("AliEveTPCSector2DGL::DirectDraw \n");
87
88   fSectorData = fSector->GetSectorData();
89
90   if(fRTS < fSector->fRTS && fSectorData != 0) {
91     CreateTexture();
92     fRTS = fSector->fRTS;
93   }
94
95   glPushAttrib(GL_CURRENT_BIT      | GL_DEPTH_BUFFER_BIT |
96                GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT       | GL_POLYGON_BIT);
97
98   glDisable(GL_LIGHTING);
99   glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
100   glEnable(GL_COLOR_MATERIAL);
101   glDisable(GL_CULL_FACE);
102
103   // Display digits
104   if(fSectorData != 0) {
105
106     const AliEveTPCSectorData::SegmentInfo&  iSeg = AliEveTPCSectorData::GetInnSeg();
107     const AliEveTPCSectorData::SegmentInfo& o1Seg = AliEveTPCSectorData::GetOut1Seg();
108     const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg();
109
110     if(rnrCtx.SecSelection()) {
111
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());
115
116     } else {
117
118       if(fSector->fUseTexture) {
119         //texture
120         glEnable(GL_BLEND);
121         glDepthMask(GL_FALSE);
122         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
123
124         glPolygonOffset(2,2);
125         glEnable(GL_POLYGON_OFFSET_FILL);
126
127         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
128         glBindTexture(GL_TEXTURE_2D, fTexture);
129         glEnable(GL_TEXTURE_2D);
130
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());
134
135         glDisable(GL_TEXTURE_2D);
136       } else {
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());
140       }
141       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
142       DisplayFrame();
143     }
144
145   }
146
147   glPopAttrib();
148 }
149
150 /******************************************************************************/
151 // Data import
152 /******************************************************************************/
153
154 void AliEveTPCSector2DGL::LoadPadrow(AliEveTPCSectorData::RowIterator& iter,
155                                Int_t row, Int_t col_off) const
156 {
157   Int_t    padVal;
158   Int_t    time, val;
159
160   Int_t    minTime = fSector->fMinTime;
161   Int_t    maxTime = fSector->fMaxTime;
162   Bool_t   halfBorderTime = ((maxTime - minTime) % 2 == 0);
163
164   UChar_t* img_pos = GetRowCol(row, col_off);
165   while (iter.NextPad()) {
166     padVal = 0;
167
168     while (iter.Next()) {
169       time = iter.Time();
170       val  = iter.Signal();
171
172       if(time < minTime || time > maxTime)
173         continue;
174
175       if(fSector->fShowMax) {
176         if(val > padVal) {
177           padVal = val;
178         }
179       } else {
180         if(halfBorderTime && (time == minTime || time == maxTime))
181           padVal += val/2;
182         else
183           padVal += val;
184       }
185     }
186
187     if(fSector->fShowMax == kFALSE && fSector->fAverage) {
188       padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
189     }
190     padVal = TMath::Min(padVal, fSector->fMaxVal);
191     if(padVal > fSector->fThreshold)
192       fSector->ColorFromArray(padVal, img_pos);
193     img_pos += 4;
194   }
195 }
196
197 /******************************************************************************/
198
199 void AliEveTPCSector2DGL::CreateTexture() const
200 {
201   if (fImage == 0 ) {
202     fImage = new UChar_t[fgkTextureByteSize];
203     glGenTextures(1, &fTexture);
204   }
205   memset(fImage, 0, fgkTextureByteSize);
206
207   Int_t rowOff[3], colOff[3];
208   Bool_t isOn[3];
209   rowOff[0] = 0;
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;
216
217   fSector->SetupColorArray();
218
219   // Loop over 3 main segments
220   for (Int_t sId = 0; sId <= 2; ++sId) {
221     if(isOn[sId] == kFALSE)
222       continue;
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]);
228     }
229   }
230
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);
239
240 }
241
242 /******************************************************************************/
243 // Data display
244 /******************************************************************************/
245
246 void AliEveTPCSector2DGL::DisplayTexture(const AliEveTPCSectorData::SegmentInfo& seg,
247                                    Int_t startCol, Int_t startRow) const
248 {
249   Float_t w  = seg.GetNMaxPads()*seg.GetPadWidth()/2;
250   Float_t y1 = seg.GetRLow();
251   Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
252
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;
257
258   glBegin(GL_QUADS);
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);
263   glEnd();
264 }
265
266 /******************************************************************************/
267
268 void AliEveTPCSector2DGL::DisplayQuads(const AliEveTPCSectorData::SegmentInfo& seg,
269                                  Int_t startCol, Int_t startRow) const
270 {
271   Float_t y_d, y_u;
272   Float_t x_off, x;
273   Float_t padW = seg.GetPadWidth();
274   Float_t padH = seg.GetPadHeight();
275
276   glBegin(GL_QUADS);
277   for (Int_t row=0; row<seg.GetNRows(); row++) {
278     y_d = seg.GetRLow() + row*padH;
279     y_u = y_d + 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;
287       if (pix[3] != 0) {
288         glColor4ubv(pix);
289         glVertex2f(x+padW, y_d);
290         glVertex2f(x,      y_d);
291         glVertex2f(x,      y_u);
292         glVertex2f(x+padW, y_u);
293       }
294     }
295   }
296   glEnd();
297 }
298
299 void AliEveTPCSector2DGL::DisplayNamedQuads(const AliEveTPCSectorData::SegmentInfo& seg,
300                                       Int_t startCol, Int_t startRow) const
301 {
302   Float_t y_d, y_u;
303   Float_t x_off, x;
304   Float_t padW = seg.GetPadWidth();
305   Float_t padH = seg.GetPadHeight();
306
307   glPushName(0);
308   for (Int_t row=0; row<seg.GetNRows(); row++) {
309     y_d = seg.GetRLow() + row*padH;
310     y_u = y_d + padH;
311     x_off = -seg.GetNMaxPads()*padW/2;
312     Int_t tpcRow = row + seg.GetFirstRow();
313     glLoadName(tpcRow);
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);
317     glPushName(0);
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);
322         glBegin(GL_QUADS);
323         glVertex2f(x+padW, y_d);
324         glVertex2f(x,      y_d);
325         glVertex2f(x,      y_u);
326         glVertex2f(x+padW, y_u);
327         glEnd();
328       }
329     }
330     glPopName();
331   }
332   glPopName();
333 }
334
335 /******************************************************************************/
336 // Frame drawing
337 /******************************************************************************/
338
339 void AliEveTPCSector2DGL::TraceStepsUp(const AliEveTPCSectorData::SegmentInfo& s)
340 {
341   Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
342   Float_t y  = s.GetRLow();
343   glVertex2f(x, y);
344   for (Int_t i=0; i<s.GetNYSteps(); ++i) {
345     y = s.GetYStep(i);
346     glVertex2f(x, y);
347     x -= s.GetPadWidth();
348     glVertex2f(x, y);
349   }
350   y =  s.GetRLow() + s.GetNRows()*s.GetPadHeight();
351   glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
352 }
353
354 void AliEveTPCSector2DGL::TraceStepsDown(const AliEveTPCSectorData::SegmentInfo& s)
355 {
356   Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
357   Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
358   glVertex2f(x, y);
359   for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
360     y =  s.GetYStep(i);
361     glVertex2f(x, y);
362     x -= s.GetPadWidth();
363     glVertex2f(x, y);
364   }
365   y = s.GetRLow();
366   glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
367 }
368
369 void AliEveTPCSector2DGL::DisplayFrame() const
370 {
371   UChar_t col[4];
372   TEveUtil::TEveUtil::ColorFromIdx(fSector->fFrameColor, col);
373   glColor4ubv(col);
374
375   if(fSector->fRnrInn) {
376     glBegin(GL_POLYGON);
377     TraceStepsUp  (AliEveTPCSectorData::GetInnSeg());
378     TraceStepsDown(AliEveTPCSectorData::GetInnSeg());
379     glEnd();
380   }
381   if(fSector->fRnrOut1) {
382     glBegin(GL_POLYGON);
383     TraceStepsUp  (AliEveTPCSectorData::GetOut1Seg());
384     TraceStepsDown(AliEveTPCSectorData::GetOut1Seg());
385     glEnd();
386   }
387   if(fSector->fRnrOut2) {
388     glBegin(GL_POLYGON);
389     TraceStepsUp  (AliEveTPCSectorData::GetOut2Seg());
390     TraceStepsDown(AliEveTPCSectorData::GetOut2Seg());
391     glEnd();
392   }
393 }