]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVE/EveDet/AliEveTPCSector2DGL.cxx
Coverity
[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
a15e6d7d 12#include <EveDet/AliEveTPCSector2D.h>
915dabe1 13
19208112 14#include <TGLRnrCtx.h>
15#include <TGLSelectRecord.h>
16#include <TGLIncludes.h>
d810d0de 17
57ffa5fb 18//______________________________________________________________________________
68084553 19//
a15e6d7d 20// GL renderer for AliEveTPCSector2D.
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
36956ab0 50 if (fImage) delete [] fImage;
a97abca8 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
68ca2fe7 100 if (fRTS < fSector->fRTS && fSectorData != 0) {
915dabe1 101 CreateTexture();
102 fRTS = fSector->fRTS;
103 }
104
68ca2fe7 105 glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT | GL_ENABLE_BIT);
915dabe1 106
107 glDisable(GL_LIGHTING);
915dabe1 108 glDisable(GL_CULL_FACE);
109
110 // Display digits
68ca2fe7 111 if (fSectorData != 0)
112 {
d810d0de 113 const AliEveTPCSectorData::SegmentInfo& iSeg = AliEveTPCSectorData::GetInnSeg();
114 const AliEveTPCSectorData::SegmentInfo& o1Seg = AliEveTPCSectorData::GetOut1Seg();
115 const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg();
915dabe1 116
68ca2fe7 117 if (rnrCtx.SecSelection())
118 {
426530cc 119
120 if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0);
121 if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0);
122 if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows());
68ca2fe7 123 }
124 else
125 {
126 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
127 if (fSector->fUseTexture)
128 {
426530cc 129 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
68ca2fe7 130 glEnable(GL_BLEND);
426530cc 131
68ca2fe7 132 glAlphaFunc(GL_GREATER, 0.2);
133 glEnable(GL_ALPHA_TEST);
426530cc 134
426530cc 135 glBindTexture(GL_TEXTURE_2D, fTexture);
136 glEnable(GL_TEXTURE_2D);
137
138 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
139 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
140 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
141
142 glDisable(GL_TEXTURE_2D);
68ca2fe7 143 }
144 else
145 {
426530cc 146 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
147 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
148 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
149 }
150 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
151 DisplayFrame();
915dabe1 152 }
426530cc 153 }
915dabe1 154
155 glPopAttrib();
156}
157
57ffa5fb 158/******************************************************************************/
915dabe1 159// Data import
57ffa5fb 160/******************************************************************************/
915dabe1 161
d810d0de 162void AliEveTPCSector2DGL::LoadPadrow(AliEveTPCSectorData::RowIterator& iter,
a15e6d7d 163 Int_t row, Int_t colOff) const
915dabe1 164{
a97abca8 165 // Load data for one pad-row into the texture.
166
b56d8877 167 Int_t padVal;
51346b82 168 Int_t time, val;
915dabe1 169
b56d8877 170 Int_t minTime = fSector->fMinTime;
171 Int_t maxTime = fSector->fMaxTime;
172 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
915dabe1 173
a15e6d7d 174 UChar_t* imgPos = GetRowCol(row, colOff);
915dabe1 175 while (iter.NextPad()) {
51346b82 176 padVal = 0;
915dabe1 177
178 while (iter.Next()) {
179 time = iter.Time();
180 val = iter.Signal();
181
b56d8877 182 if(time < minTime || time > maxTime)
183 continue;
184
915dabe1 185 if(fSector->fShowMax) {
b56d8877 186 if(val > padVal) {
187 padVal = val;
915dabe1 188 }
189 } else {
b56d8877 190 if(halfBorderTime && (time == minTime || time == maxTime))
191 padVal += val/2;
192 else
193 padVal += val;
915dabe1 194 }
195 }
196
68ca2fe7 197 if (fSector->fShowMax == kFALSE && fSector->fAverage) {
b56d8877 198 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
199 }
200 padVal = TMath::Min(padVal, fSector->fMaxVal);
68ca2fe7 201 if (padVal > fSector->fThreshold) {
a15e6d7d 202 fSector->ColorFromArray(padVal, imgPos);
68ca2fe7 203 }
a15e6d7d 204 imgPos += 4;
915dabe1 205 }
206}
207
57ffa5fb 208/******************************************************************************/
915dabe1 209
d810d0de 210void AliEveTPCSector2DGL::CreateTexture() const
915dabe1 211{
a97abca8 212 // Create texture that holds pad data.
213
68ca2fe7 214 if (fImage == 0)
215 {
915dabe1 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
a15e6d7d 234 for (Int_t sId = 0; sId <= 2; ++sId)
235 {
236 if (isOn[sId] == kFALSE)
b56d8877 237 continue;
d810d0de 238 const AliEveTPCSectorData::SegmentInfo& sInfo = AliEveTPCSectorData::GetSeg(sId);
a15e6d7d 239 for (Int_t row = sInfo.GetFirstRow(); row <= sInfo.GetLastRow(); ++row)
240 {
d810d0de 241 AliEveTPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
242 Int_t offset = (sInfo.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(row))/2;
915dabe1 243 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
244 }
245 }
246
247 glBindTexture (GL_TEXTURE_2D, fTexture);
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
426530cc 252 glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
915dabe1 253 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
254 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
255
256}
257
57ffa5fb 258/******************************************************************************/
915dabe1 259// Data display
57ffa5fb 260/******************************************************************************/
915dabe1 261
d810d0de 262void AliEveTPCSector2DGL::DisplayTexture(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 263 Int_t startCol, Int_t startRow) const
915dabe1 264{
a97abca8 265 // Display segment data via one textured rectangle.
266
426530cc 267 Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2;
268 Float_t y1 = seg.GetRLow();
269 Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
270
915dabe1 271 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
272 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
426530cc 273 Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth;
274 Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight;
915dabe1 275
51346b82 276 glBegin(GL_QUADS);
426530cc 277 glTexCoord2f(u1, v1); glVertex2f(-w, y1);
278 glTexCoord2f(u1, v2); glVertex2f(-w, y2);
279 glTexCoord2f(u2, v2); glVertex2f( w, y2);
280 glTexCoord2f(u2, v1); glVertex2f( w, y1);
915dabe1 281 glEnd();
282}
283
57ffa5fb 284/******************************************************************************/
915dabe1 285
d810d0de 286void AliEveTPCSector2DGL::DisplayQuads(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 287 Int_t startCol, Int_t startRow) const
915dabe1 288{
a97abca8 289 // Display segment data by rendering one quad per pad.
290
a15e6d7d 291 Float_t yD, yU;
292 Float_t xOff, x;
426530cc 293 Float_t padW = seg.GetPadWidth();
294 Float_t padH = seg.GetPadHeight();
915dabe1 295
296 glBegin(GL_QUADS);
a15e6d7d 297 for (Int_t row = 0; row < seg.GetNRows(); row++)
298 {
299 yD = seg.GetRLow() + row*padH;
300 yU = yD + padH;
301 xOff = -seg.GetNMaxPads()*padW/2;
426530cc 302 Int_t tpcRow = row + seg.GetFirstRow();
d810d0de 303 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
426530cc 304 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
305 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
a15e6d7d 306 for (Int_t pad = deltaPad; pad < maxPad; pad++, pix+=4)
307 {
308 x = xOff + pad*padW;
309 if (pix[3] != 0)
310 {
311 TGLUtil::Color4ubv(pix);
312 glVertex2f(x+padW, yD);
313 glVertex2f(x, yD);
314 glVertex2f(x, yU);
315 glVertex2f(x+padW, yU);
915dabe1 316 }
317 }
318 }
319 glEnd();
320}
321
d810d0de 322void AliEveTPCSector2DGL::DisplayNamedQuads(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 323 Int_t startCol, Int_t startRow) const
426530cc 324{
a97abca8 325 // Display segmen data as one quad per pad.
326 // Tag the rows and pads for selection.
327
a15e6d7d 328 Float_t yD, yU;
329 Float_t xOff, x;
426530cc 330 Float_t padW = seg.GetPadWidth();
331 Float_t padH = seg.GetPadHeight();
332
333 glPushName(0);
a15e6d7d 334 for (Int_t row = 0; row < seg.GetNRows(); row++)
335 {
336 yD = seg.GetRLow() + row*padH;
337 yU = yD + padH;
338 xOff = -seg.GetNMaxPads()*padW/2;
426530cc 339 Int_t tpcRow = row + seg.GetFirstRow();
340 glLoadName(tpcRow);
d810d0de 341 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
426530cc 342 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
343 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
344 glPushName(0);
a15e6d7d 345 for (Int_t pad = deltaPad; pad < maxPad; pad++, pix+=4)
346 {
347 x = xOff + pad*padW;
348 if (pix[3] != 0 || fSector->fPickEmpty)
349 {
426530cc 350 glLoadName(pad - deltaPad);
351 glBegin(GL_QUADS);
a15e6d7d 352 glVertex2f(x+padW, yD);
353 glVertex2f(x, yD);
354 glVertex2f(x, yU);
355 glVertex2f(x+padW, yU);
426530cc 356 glEnd();
357 }
358 }
359 glPopName();
360 }
361 glPopName();
362}
363
57ffa5fb 364/******************************************************************************/
915dabe1 365// Frame drawing
57ffa5fb 366/******************************************************************************/
915dabe1 367
d810d0de 368void AliEveTPCSector2DGL::TraceStepsUp(const AliEveTPCSectorData::SegmentInfo& s)
915dabe1 369{
a97abca8 370 // Trace border of segment upwards.
371
915dabe1 372 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
373 Float_t y = s.GetRLow();
374 glVertex2f(x, y);
a15e6d7d 375 for (Int_t i = 0; i < s.GetNYSteps(); ++i)
376 {
915dabe1 377 y = s.GetYStep(i);
378 glVertex2f(x, y);
379 x -= s.GetPadWidth();
380 glVertex2f(x, y);
381 }
382 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
383 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
384}
385
51346b82 386void AliEveTPCSector2DGL::TraceStepsDown(const AliEveTPCSectorData::SegmentInfo& s)
915dabe1 387{
a97abca8 388 // Trace border of segment downwards.
389
915dabe1 390 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
391 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
392 glVertex2f(x, y);
a15e6d7d 393 for (Int_t i = s.GetNYSteps() - 1; i >= 0; --i)
394 {
915dabe1 395 y = s.GetYStep(i);
396 glVertex2f(x, y);
397 x -= s.GetPadWidth();
398 glVertex2f(x, y);
399 }
400 y = s.GetRLow();
401 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
402}
403
d810d0de 404void AliEveTPCSector2DGL::DisplayFrame() const
915dabe1 405{
a97abca8 406 // Display frame of the sector.
407 // Each segment's frame is drawn only if its data is drawn, too.
408
a15e6d7d 409 TGLUtil::Color(fSector->fFrameColor);
915dabe1 410
a15e6d7d 411 if(fSector->fRnrInn)
412 {
b56d8877 413 glBegin(GL_POLYGON);
d810d0de 414 TraceStepsUp (AliEveTPCSectorData::GetInnSeg());
415 TraceStepsDown(AliEveTPCSectorData::GetInnSeg());
b56d8877 416 glEnd();
417 }
a15e6d7d 418 if(fSector->fRnrOut1)
419 {
b56d8877 420 glBegin(GL_POLYGON);
d810d0de 421 TraceStepsUp (AliEveTPCSectorData::GetOut1Seg());
422 TraceStepsDown(AliEveTPCSectorData::GetOut1Seg());
b56d8877 423 glEnd();
424 }
a15e6d7d 425 if(fSector->fRnrOut2)
426 {
b56d8877 427 glBegin(GL_POLYGON);
d810d0de 428 TraceStepsUp (AliEveTPCSectorData::GetOut2Seg());
429 TraceStepsDown(AliEveTPCSectorData::GetOut2Seg());
b56d8877 430 glEnd();
431 }
915dabe1 432}