This commit was generated by cvs2svn to compensate for changes in r13732,
[u/mrichter/AliRoot.git] / EVE / Alieve / TPCSegmentGL.cxx
1 // $Header$
2
3 #include "TPCSegmentGL.h"
4
5 #include <TStyle.h>
6 #include <TColor.h>
7 #include <TStopwatch.h>
8
9 using namespace Reve;
10 using namespace Alieve;
11 using namespace std;
12
13 /**************************************************************************/
14
15 TPCSegmentGL::TPCSegmentGL() : TGLObject()
16 {
17   fImage   = 0;
18   fTexture = 0;
19   fRTS     = 0;
20 }
21
22 TPCSegmentGL::~TPCSegmentGL()
23 {
24   if(fImage) delete fImage;
25   if(fTexture) glDeleteTextures(1, &fTexture);
26 }
27  
28
29 /**************************************************************************/
30
31 Bool_t TPCSegmentGL::SetModel(TObject* obj)
32 {
33   if( set_model(obj, "Alieve::TPCSegment")){
34     fSegment = (TPCSegment*) fExternalObj;
35     return true;
36   }
37   return false;
38 }
39
40 void TPCSegmentGL::SetBBox()
41 {
42   set_axis_aligned_bbox(((TPCSegment*)fExternalObj)->AssertBBox());
43 }
44
45 /**************************************************************************/
46
47 void TPCSegmentGL::DirectDraw(const TGLDrawFlags & ) const
48 {
49   // printf("TPCSegmentGL::DirectDraw \n");
50
51   if(fSegment->fInfo == 0 ) return;
52   TPCDigitsInfo* info = fSegment->fInfo;
53
54   if(fRTS < fSegment->fRTS) {
55     CreateTexture(info);
56     fRTS = fSegment->fRTS;
57   }
58
59   glPushAttrib(GL_CURRENT_BIT      | GL_DEPTH_BUFFER_BIT |
60                GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT       | GL_POLYGON_BIT);
61
62   glDisable(GL_LIGHTING);
63   glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
64   glEnable(GL_COLOR_MATERIAL);
65   glDisable(GL_CULL_FACE);
66
67
68   // rnr digits
69   if(fSegment->fUseTexture) {
70     //texture
71     glEnable(GL_BLEND);
72     glDepthMask(GL_FALSE);
73     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
74     glShadeModel(GL_FLAT);
75
76     glBindTexture  (GL_TEXTURE_2D, fTexture);
77
78     glPolygonOffset(2,2);
79     glEnable(GL_POLYGON_OFFSET_FILL);
80
81     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
82     glBindTexture(GL_TEXTURE_2D, fTexture);
83     glEnable(GL_TEXTURE_2D);
84
85     DisplayTexture(info->fInnSeg.fPadWidth, info->fInnSeg.fPadLength, info->fInnSeg.fRlow,
86                     info->fInnSeg.fNMaxPads, info->fInnSeg.fNRows, 0,0);
87     DisplayTexture(info->fOut1Seg.fPadWidth, info->fOut1Seg.fPadLength, info->fOut1Seg.fRlow,
88                     info->fOut1Seg.fNMaxPads,info->fOut1Seg.fNRows,info->fInnSeg.fNMaxPads,0);
89     DisplayTexture(info->fOut2Seg.fPadWidth, info->fOut2Seg.fPadLength, info->fOut2Seg.fRlow,
90                     info->fOut2Seg.fNMaxPads, info->fOut2Seg.fNRows,0,info->fOut1Seg.fNRows);
91
92     glDisable(GL_TEXTURE_2D);
93   } else {
94     DisplayQuads(info->fInnSeg.fPadWidth, info->fInnSeg.fPadLength, info->fInnSeg.fRlow,
95                   info->fInnSeg.fNMaxPads, info->fInnSeg.fNRows, 0,0);
96     DisplayQuads(info->fOut1Seg.fPadWidth, info->fOut1Seg.fPadLength, info->fOut1Seg.fRlow,
97                   info->fOut1Seg.fNMaxPads,info->fOut1Seg.fNRows,info->fInnSeg.fNMaxPads,0);
98     DisplayQuads(info->fOut2Seg.fPadWidth, info->fOut2Seg.fPadLength, info->fOut2Seg.fRlow,
99                   info->fOut2Seg.fNMaxPads, info->fOut2Seg.fNRows,0,info->fOut1Seg.fNRows);
100   }
101
102   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
103   DisplayFrame(info);
104
105   glPopAttrib();
106 }
107
108 /**************************************************************************/
109
110 void TPCSegmentGL::LoadPadrow(Int_t row, Int_t col_off) const
111 {
112   AliSimDigits *digit =  &fSegment->fInfo->fSimDigits;
113
114   Int_t    pad_var = 0;
115   Int_t    time, pad, val;   
116   UChar_t* img_pos;
117
118   Int_t  min_time = fSegment->fMinTime;
119   Int_t max_time = fSegment->fMaxTime;
120   Bool_t half_border_time = ((fSegment->fMaxTime - fSegment->fMinTime) % 2 == 0);
121
122   Bool_t done_p = false;
123   Bool_t save_p = false;
124
125   digit->First();
126   do {
127
128     time = digit->CurrentRow();
129     pad  = digit->CurrentColumn();
130     val  = digit->CurrentDigit();
131
132     Bool_t use_digit = true;
133     if(use_digit) {
134       if(fSegment->fShowMax) {
135         if(val > pad_var) {
136           pad_var = val;
137         }
138       } else {
139         // Integrate int max_val.
140         if(time >= min_time && time <= max_time) {
141           if(half_border_time && (time == min_time || time == max_time))
142             pad_var += val/2;
143           else
144             pad_var += val;
145         }
146       }
147     }
148
149     if(digit->Next()) {
150       if(pad != digit->CurrentColumn())
151         save_p = true;
152     } else {
153       done_p = true;
154       save_p = true;
155     }
156
157     if(save_p) {
158       pad_var = TMath::Min(pad_var, fSegment->fMaxVal);
159       if(pad_var > fSegment->fTreshold) {
160         img_pos = GetRowCol(row, pad + col_off);
161         SetCol(pad_var, img_pos);
162       }
163       pad_var = 0; 
164     }
165
166   } while (!done_p);
167 }
168  
169 /**************************************************************************/
170
171 void TPCSegmentGL::SetCol(Float_t z, UChar_t* pixel) const
172 {
173  
174   Int_t n_col = gStyle->GetNumberOfColors();
175
176   Int_t ci = gStyle->GetColorPalette
177     (TMath::Min(n_col - 1,
178                 Int_t((n_col*(z - fSegment->fTreshold))/(fSegment->fMaxVal - fSegment->fTreshold))));
179
180   TColor* c = gROOT->GetColor(ci);
181
182   if(c) {
183     //    UChar_t *x = (UChar_t*) &c;
184     pixel[0] = (UChar_t)(255*c->GetRed());
185     pixel[1] = (UChar_t)(255*c->GetGreen());
186     pixel[2] = (UChar_t)(255*c->GetBlue());
187     pixel[3] = 255;
188   }
189 }
190
191 /**************************************************************************/
192
193 void TPCSegmentGL::CreateTexture(TPCDigitsInfo* info) const
194 {
195   AliSimDigits *digit = &info->fSimDigits;
196   AliTPCParam  *par   = info->fParameter;
197
198   TTree* t = info->fTree;
199   Int_t s, row, ent, off;
200
201   TStopwatch* sw = new  TStopwatch();
202   sw->Start();
203
204   // init fImage table
205   if (fImage == 0 ){
206     fImage = new UChar_t[ImageWidth*ImageHeight*4];
207     glGenTextures(1, &fTexture);
208   }
209   memset(fImage, 0, ImageWidth*ImageHeight*4);
210
211   ent = info->fSegEnt[fSegment->fID];
212   if(ent != -1) {
213     row=0;
214     // info->fInnSeg.Dump();
215     while(ent < t->GetEntriesFast()) {
216       t->GetEntry(ent);
217       par->AdjustSectorRow(digit->GetID(),s,row);
218       // printf("AdjustSectorRow DigitID %d sector %d row %d \n",digit->GetID(),s,row );
219       if(s != fSegment->fID) break;
220       off =  (info->fInnSeg.fNMaxPads - par->GetNPadsLow(row))/2;
221       LoadPadrow(row, off);
222       ent++;
223     }
224   }
225   ent = info->fSegEnt[fSegment->fID + 36];
226   if(ent != -1) {
227     row=0;
228     // info->fOut1Seg.Dump();
229     while(ent < t->GetEntriesFast()) {
230       t->GetEntry(ent);
231       par->AdjustSectorRow(digit->GetID(),s,row);
232       // printf("AdjustSectorRow DigitID %d sector %d row %d \n",digit->GetID(),s,row );
233       if(s != (fSegment->fID+36)) break;
234
235       if(row < par->GetNRowUp1()) {
236         off =  (info->fOut1Seg.fNMaxPads - par->GetNPadsUp(row))/2;
237         LoadPadrow(row, off + info->fInnSeg.fNMaxPads);
238       } else {
239         off =  (info->fOut2Seg.fNMaxPads - par->GetNPadsUp(row))/2;
240         LoadPadrow(row, off); // info->fInnSeg.fNRows - info->fOut1Seg.fNRows);
241       }
242       ent++;
243     }
244   }
245   sw->Stop();
246   // printf("TPCSegment::CreateTexture timer %f\n", sw->RealTime());
247   // sw->Dump();
248
249   glBindTexture  (GL_TEXTURE_2D, fTexture);
250   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
251   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
252   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
253   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
254   // glTexEnvf      (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,   GL_MODULATE); // Lightning is off anyway.
255   glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, ImageWidth, ImageHeight,
256                   0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
257
258 }
259
260 void TPCSegmentGL::DisplayTexture(Float_t pw, Float_t pl, Float_t vR,
261                                   Int_t fNMaxPads, Int_t fNRows, 
262                                   Int_t startCol, Int_t startRow) const
263 {
264   Float_t w  = fNMaxPads*pw/2;
265   Float_t v1 = 1.0*startRow/ImageHeight;
266   Float_t v2 = v1 + 1.0*fNRows/ImageHeight;
267   Float_t u1 = 1.0 *startCol/ImageWidth;
268   Float_t u2 = u1 + 1.0 *fNMaxPads/ImageWidth;
269   // printf("tex coord u1,v1: (%f, %f), v2,u2: (%f,%f) \n", v1, u1, v2, u2);
270   // printf("vertex coord >>> nPads %d pw %f, w: %f, y1: %f, y2: %f \n",fNMaxPads,pw, w, vR, vR+fNRows*pl);
271   // glColor4f(1.,1.,1.,fSegment->mAlpha); 
272   // glColor4f(1.,1.,1.,1); 
273   glBegin (GL_QUADS);
274   
275   glTexCoord2f(u1, v1);  glVertex3f (-w, vR,           0.0);
276   glTexCoord2f(u1, v2);  glVertex3f (-w, vR+fNRows*pl, 0.0);
277   glTexCoord2f(u2, v2);  glVertex3f ( w, vR+fNRows*pl, 0.0);
278   glTexCoord2f(u2, v1);  glVertex3f ( w, vR,           0.0);
279
280   glEnd();
281 }
282
283 /**************************************************************************/
284
285 void TPCSegmentGL::DisplayQuads(Float_t pw, Float_t pl, Float_t vR,
286                                 Int_t fNMaxPads, Int_t fNRows, 
287                                 Int_t startCol, Int_t startRow) const
288 {
289   UChar_t *pix;
290   Float_t y_d, y_u;
291   Float_t x_off, x;
292
293   glBegin(GL_QUADS);
294   for(Int_t row = 0; row<fNRows; row++){
295     y_d = vR + row*pl;
296     y_u = y_d + pl;
297     x_off = -fNMaxPads*pw/2;
298     for(Int_t pad = 0; pad<fNMaxPads; pad++){
299       pix = GetRowCol(row + startRow, pad + startCol);
300       x = x_off + pad*pw;
301       if(pix[3] != 0){
302         glColor4ubv(pix);
303         glVertex3f(x+pw, y_d, 0);
304         glVertex3f(x,    y_d, 0);
305         glVertex3f(x,    y_u, 0);
306         glVertex3f(x+pw, y_u, 0);
307       }
308     }
309   }
310   glEnd();
311 }
312
313 /**************************************************************************/
314
315 void TPCSegmentGL::DisplayFrame(TPCDigitsInfo* info) const
316 {
317   TPCSeg* seg;
318
319   TColor* c = gROOT->GetColor(fSegment->fFrameCol);
320   if(c == 0) return; 
321
322   //  x[0] = (UChar_t)(255*c->GetRed());  x[1] = (UChar_t)(255*c->GetGreen());
323   // x[2] = (UChar_t)(255*c->GetBlue()); x[3] = 255;
324
325   glColor3ub((UChar_t)(255*c->GetRed()), 
326              (UChar_t)(255*c->GetGreen()),
327              (UChar_t)(255*c->GetBlue()));
328
329   seg = &info->fInnSeg;
330   glBegin(GL_LINE_LOOP);
331   LoopStepsUp(seg);
332   LoopStepsDown(seg);
333   glEnd();
334
335   // outer1 segment
336   seg = &info->fOut1Seg;
337   glBegin(GL_LINE_LOOP);
338   LoopStepsUp(seg);
339   LoopStepsDown(seg);
340   glEnd();
341
342   // outer2 segment
343   seg = &info->fOut2Seg;
344   glBegin(GL_LINE_STRIP);
345   LoopStepsUp(seg);
346   LoopStepsDown(seg);
347   glEnd();
348 }