]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVE/EveDet/AliEveTPCSector2DGL.cxx
Added class documentation.
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTPCSector2DGL.cxx
CommitLineData
d810d0de 1// $Id$
2// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
915dabe1 3
d810d0de 4/**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
51346b82 7 * full copyright notice. *
d810d0de 8 **************************************************************************/
915dabe1 9
d810d0de 10#include "AliEveTPCSector2DGL.h"
11
cb4245bb 12#include <EveDet/AliEveTPCData.h>
915dabe1 13
19208112 14#include <TGLRnrCtx.h>
15#include <TGLSelectRecord.h>
16#include <TGLIncludes.h>
d810d0de 17
57ffa5fb 18//______________________________________________________________________________
68084553 19//
a97abca8 20// GL renderer for TPCSector2D.
68084553 21
d810d0de 22ClassImp(AliEveTPCSector2DGL)
68084553 23
24// This can be optimized to non-pow-2 values once everybody has GL 1.4.
915dabe1 25
d810d0de 26const Int_t AliEveTPCSector2DGL::fgkTextureWidth = 256;
27const Int_t AliEveTPCSector2DGL::fgkTextureHeight = 128;
28const Int_t AliEveTPCSector2DGL::fgkTextureByteSize = 4*256*128;
915dabe1 29
57ffa5fb 30/******************************************************************************/
915dabe1 31
d810d0de 32AliEveTPCSector2DGL::AliEveTPCSector2DGL() :
265ecb21 33 TGLObject(),
51346b82 34
265ecb21 35 fSector (0),
36 fSectorData (0),
37
38 fImage (0),
39 fTexture (0),
40 fRTS (0)
a97abca8 41{
42 // Constructor.
43}
915dabe1 44
d810d0de 45AliEveTPCSector2DGL::~AliEveTPCSector2DGL()
915dabe1 46{
a97abca8 47 // Destructor.
48 // !!!! Should unregister texture via ContextIdentity!
49
50 if (fImage) delete fImage;
51 if (fTexture) glDeleteTextures(1, &fTexture);
915dabe1 52}
53
57ffa5fb 54/******************************************************************************/
915dabe1 55
d810d0de 56Bool_t AliEveTPCSector2DGL::SetModel(TObject* obj, const Option_t* /*opt*/)
915dabe1 57{
a97abca8 58 // Set model object.
59
60 if (SetModelCheckClass(obj, AliEveTPCSector2D::Class())) {
d810d0de 61 fSector = (AliEveTPCSector2D*) fExternalObj;
891e4bb4 62 return kTRUE;
915dabe1 63 }
891e4bb4 64 return kFALSE;
915dabe1 65}
66
d810d0de 67void AliEveTPCSector2DGL::SetBBox()
915dabe1 68{
a97abca8 69 // Set bounding-box.
70
d810d0de 71 SetAxisAlignedBBox(((AliEveTPCSector2D*)fExternalObj)->AssertBBox());
915dabe1 72}
73
57ffa5fb 74/******************************************************************************/
915dabe1 75
d810d0de 76void AliEveTPCSector2DGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/,
a97abca8 77 TGLSelectRecord & rec)
a8600b56 78{
a97abca8 79 // Process selection record.
80 // Determine row and pad, call PadSelected() in model object.
81
19208112 82 if (rec.GetN() != 3) return;
83 Int_t row = rec.GetItem(1);
84 Int_t pad = rec.GetItem(2);
d810d0de 85 if (row < 0 || row >= AliEveTPCSectorData::GetNAllRows()) return;
86 if (pad < 0 || pad >= AliEveTPCSectorData::GetNPadsInRow(row)) return;
96ff1952 87 fSector->PadSelected(row, pad);
a8600b56 88}
89
57ffa5fb 90/******************************************************************************/
a8600b56 91
d810d0de 92void AliEveTPCSector2DGL::DirectDraw(TGLRnrCtx& rnrCtx) const
915dabe1 93{
94 // Actual GL drawing.
95
d810d0de 96 // printf("AliEveTPCSector2DGL::DirectDraw \n");
915dabe1 97
fa3a3795 98 fSectorData = fSector->GetSectorData();
915dabe1 99
100 if(fRTS < fSector->fRTS && fSectorData != 0) {
101 CreateTexture();
102 fRTS = fSector->fRTS;
103 }
104
105 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
106 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
107
108 glDisable(GL_LIGHTING);
109 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
110 glEnable(GL_COLOR_MATERIAL);
111 glDisable(GL_CULL_FACE);
112
113 // Display digits
114 if(fSectorData != 0) {
115
d810d0de 116 const AliEveTPCSectorData::SegmentInfo& iSeg = AliEveTPCSectorData::GetInnSeg();
117 const AliEveTPCSectorData::SegmentInfo& o1Seg = AliEveTPCSectorData::GetOut1Seg();
118 const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg();
915dabe1 119
19208112 120 if(rnrCtx.SecSelection()) {
426530cc 121
122 if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0);
123 if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0);
124 if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows());
125
b56d8877 126 } else {
426530cc 127
128 if(fSector->fUseTexture) {
129 //texture
130 glEnable(GL_BLEND);
131 glDepthMask(GL_FALSE);
132 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133
134 glPolygonOffset(2,2);
135 glEnable(GL_POLYGON_OFFSET_FILL);
136
137 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
138 glBindTexture(GL_TEXTURE_2D, fTexture);
139 glEnable(GL_TEXTURE_2D);
140
141 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
142 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
143 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
144
145 glDisable(GL_TEXTURE_2D);
146 } else {
147 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
148 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
149 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
150 }
151 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
152 DisplayFrame();
915dabe1 153 }
915dabe1 154
426530cc 155 }
915dabe1 156
157 glPopAttrib();
158}
159
57ffa5fb 160/******************************************************************************/
915dabe1 161// Data import
57ffa5fb 162/******************************************************************************/
915dabe1 163
d810d0de 164void AliEveTPCSector2DGL::LoadPadrow(AliEveTPCSectorData::RowIterator& iter,
a97abca8 165 Int_t row, Int_t col_off) const
915dabe1 166{
a97abca8 167 // Load data for one pad-row into the texture.
168
b56d8877 169 Int_t padVal;
51346b82 170 Int_t time, val;
915dabe1 171
b56d8877 172 Int_t minTime = fSector->fMinTime;
173 Int_t maxTime = fSector->fMaxTime;
174 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
915dabe1 175
176 UChar_t* img_pos = GetRowCol(row, col_off);
177 while (iter.NextPad()) {
51346b82 178 padVal = 0;
915dabe1 179
180 while (iter.Next()) {
181 time = iter.Time();
182 val = iter.Signal();
183
b56d8877 184 if(time < minTime || time > maxTime)
185 continue;
186
915dabe1 187 if(fSector->fShowMax) {
b56d8877 188 if(val > padVal) {
189 padVal = val;
915dabe1 190 }
191 } else {
b56d8877 192 if(halfBorderTime && (time == minTime || time == maxTime))
193 padVal += val/2;
194 else
195 padVal += val;
915dabe1 196 }
197 }
198
b56d8877 199 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
200 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
201 }
202 padVal = TMath::Min(padVal, fSector->fMaxVal);
203 if(padVal > fSector->fThreshold)
891e4bb4 204 fSector->ColorFromArray(padVal, img_pos);
915dabe1 205 img_pos += 4;
206 }
207}
208
57ffa5fb 209/******************************************************************************/
915dabe1 210
d810d0de 211void AliEveTPCSector2DGL::CreateTexture() const
915dabe1 212{
a97abca8 213 // Create texture that holds pad data.
214
915dabe1 215 if (fImage == 0 ) {
216 fImage = new UChar_t[fgkTextureByteSize];
217 glGenTextures(1, &fTexture);
218 }
219 memset(fImage, 0, fgkTextureByteSize);
220
221 Int_t rowOff[3], colOff[3];
b56d8877 222 Bool_t isOn[3];
223 rowOff[0] = 0;
d810d0de 224 rowOff[1] = rowOff[2] = -AliEveTPCSectorData::GetSeg(1).GetFirstRow();
b56d8877 225 colOff[0] = colOff[2] = 0;
d810d0de 226 colOff[1] = AliEveTPCSectorData::GetSeg(0).GetNMaxPads();
b56d8877 227 isOn[0] = fSector->fRnrInn;
228 isOn[1] = fSector->fRnrOut1;
229 isOn[2] = fSector->fRnrOut2;
915dabe1 230
891e4bb4 231 fSector->SetupColorArray();
232
915dabe1 233 // Loop over 3 main segments
234 for (Int_t sId = 0; sId <= 2; ++sId) {
b56d8877 235 if(isOn[sId] == kFALSE)
236 continue;
d810d0de 237 const AliEveTPCSectorData::SegmentInfo& sInfo = AliEveTPCSectorData::GetSeg(sId);
915dabe1 238 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
d810d0de 239 AliEveTPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
240 Int_t offset = (sInfo.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(row))/2;
915dabe1 241 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
242 }
243 }
244
245 glBindTexture (GL_TEXTURE_2D, fTexture);
246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
426530cc 250 glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
915dabe1 251 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
252 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
253
254}
255
57ffa5fb 256/******************************************************************************/
915dabe1 257// Data display
57ffa5fb 258/******************************************************************************/
915dabe1 259
d810d0de 260void AliEveTPCSector2DGL::DisplayTexture(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 261 Int_t startCol, Int_t startRow) const
915dabe1 262{
a97abca8 263 // Display segment data via one textured rectangle.
264
426530cc 265 Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2;
266 Float_t y1 = seg.GetRLow();
267 Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
268
915dabe1 269 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
270 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
426530cc 271 Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth;
272 Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight;
915dabe1 273
51346b82 274 glBegin(GL_QUADS);
426530cc 275 glTexCoord2f(u1, v1); glVertex2f(-w, y1);
276 glTexCoord2f(u1, v2); glVertex2f(-w, y2);
277 glTexCoord2f(u2, v2); glVertex2f( w, y2);
278 glTexCoord2f(u2, v1); glVertex2f( w, y1);
915dabe1 279 glEnd();
280}
281
57ffa5fb 282/******************************************************************************/
915dabe1 283
d810d0de 284void AliEveTPCSector2DGL::DisplayQuads(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 285 Int_t startCol, Int_t startRow) const
915dabe1 286{
a97abca8 287 // Display segment data by rendering one quad per pad.
288
915dabe1 289 Float_t y_d, y_u;
290 Float_t x_off, x;
426530cc 291 Float_t padW = seg.GetPadWidth();
292 Float_t padH = seg.GetPadHeight();
915dabe1 293
294 glBegin(GL_QUADS);
426530cc 295 for (Int_t row=0; row<seg.GetNRows(); row++) {
296 y_d = seg.GetRLow() + row*padH;
915dabe1 297 y_u = y_d + padH;
426530cc 298 x_off = -seg.GetNMaxPads()*padW/2;
299 Int_t tpcRow = row + seg.GetFirstRow();
d810d0de 300 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
426530cc 301 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
302 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
303 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
915dabe1 304 x = x_off + pad*padW;
305 if (pix[3] != 0) {
306 glColor4ubv(pix);
307 glVertex2f(x+padW, y_d);
308 glVertex2f(x, y_d);
309 glVertex2f(x, y_u);
310 glVertex2f(x+padW, y_u);
311 }
312 }
313 }
314 glEnd();
315}
316
d810d0de 317void AliEveTPCSector2DGL::DisplayNamedQuads(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 318 Int_t startCol, Int_t startRow) const
426530cc 319{
a97abca8 320 // Display segmen data as one quad per pad.
321 // Tag the rows and pads for selection.
322
426530cc 323 Float_t y_d, y_u;
324 Float_t x_off, x;
325 Float_t padW = seg.GetPadWidth();
326 Float_t padH = seg.GetPadHeight();
327
328 glPushName(0);
329 for (Int_t row=0; row<seg.GetNRows(); row++) {
330 y_d = seg.GetRLow() + row*padH;
331 y_u = y_d + padH;
332 x_off = -seg.GetNMaxPads()*padW/2;
333 Int_t tpcRow = row + seg.GetFirstRow();
334 glLoadName(tpcRow);
d810d0de 335 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
426530cc 336 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
337 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
338 glPushName(0);
339 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
340 x = x_off + pad*padW;
a8600b56 341 if (pix[3] != 0 || fSector->fPickEmpty) {
426530cc 342 glLoadName(pad - deltaPad);
343 glBegin(GL_QUADS);
344 glVertex2f(x+padW, y_d);
345 glVertex2f(x, y_d);
346 glVertex2f(x, y_u);
347 glVertex2f(x+padW, y_u);
348 glEnd();
349 }
350 }
351 glPopName();
352 }
353 glPopName();
354}
355
57ffa5fb 356/******************************************************************************/
915dabe1 357// Frame drawing
57ffa5fb 358/******************************************************************************/
915dabe1 359
d810d0de 360void AliEveTPCSector2DGL::TraceStepsUp(const AliEveTPCSectorData::SegmentInfo& s)
915dabe1 361{
a97abca8 362 // Trace border of segment upwards.
363
915dabe1 364 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
365 Float_t y = s.GetRLow();
366 glVertex2f(x, y);
367 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
368 y = s.GetYStep(i);
369 glVertex2f(x, y);
370 x -= s.GetPadWidth();
371 glVertex2f(x, y);
372 }
373 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
374 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
375}
376
51346b82 377void AliEveTPCSector2DGL::TraceStepsDown(const AliEveTPCSectorData::SegmentInfo& s)
915dabe1 378{
a97abca8 379 // Trace border of segment downwards.
380
915dabe1 381 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
382 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
383 glVertex2f(x, y);
384 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
385 y = s.GetYStep(i);
386 glVertex2f(x, y);
387 x -= s.GetPadWidth();
388 glVertex2f(x, y);
389 }
390 y = s.GetRLow();
391 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
392}
393
d810d0de 394void AliEveTPCSector2DGL::DisplayFrame() const
915dabe1 395{
a97abca8 396 // Display frame of the sector.
397 // Each segment's frame is drawn only if its data is drawn, too.
398
092578a7 399 UChar_t col[4];
d810d0de 400 TEveUtil::TEveUtil::ColorFromIdx(fSector->fFrameColor, col);
092578a7 401 glColor4ubv(col);
915dabe1 402
b56d8877 403 if(fSector->fRnrInn) {
404 glBegin(GL_POLYGON);
d810d0de 405 TraceStepsUp (AliEveTPCSectorData::GetInnSeg());
406 TraceStepsDown(AliEveTPCSectorData::GetInnSeg());
b56d8877 407 glEnd();
408 }
409 if(fSector->fRnrOut1) {
410 glBegin(GL_POLYGON);
d810d0de 411 TraceStepsUp (AliEveTPCSectorData::GetOut1Seg());
412 TraceStepsDown(AliEveTPCSectorData::GetOut1Seg());
b56d8877 413 glEnd();
414 }
415 if(fSector->fRnrOut2) {
416 glBegin(GL_POLYGON);
d810d0de 417 TraceStepsUp (AliEveTPCSectorData::GetOut2Seg());
418 TraceStepsDown(AliEveTPCSectorData::GetOut2Seg());
b56d8877 419 glEnd();
420 }
915dabe1 421}