Add missing [] to array-delete.
[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
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);
915dabe1 109 glDisable(GL_CULL_FACE);
110
111 // Display digits
112 if(fSectorData != 0) {
113
d810d0de 114 const AliEveTPCSectorData::SegmentInfo& iSeg = AliEveTPCSectorData::GetInnSeg();
115 const AliEveTPCSectorData::SegmentInfo& o1Seg = AliEveTPCSectorData::GetOut1Seg();
116 const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg();
915dabe1 117
19208112 118 if(rnrCtx.SecSelection()) {
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());
123
b56d8877 124 } else {
426530cc 125
126 if(fSector->fUseTexture) {
127 //texture
128 glEnable(GL_BLEND);
129 glDepthMask(GL_FALSE);
130 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
131
132 glPolygonOffset(2,2);
133 glEnable(GL_POLYGON_OFFSET_FILL);
134
135 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
136 glBindTexture(GL_TEXTURE_2D, fTexture);
137 glEnable(GL_TEXTURE_2D);
138
139 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
140 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
141 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
142
143 glDisable(GL_TEXTURE_2D);
144 } else {
145 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
146 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
147 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
148 }
149 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
150 DisplayFrame();
915dabe1 151 }
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
b56d8877 197 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
198 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
199 }
200 padVal = TMath::Min(padVal, fSector->fMaxVal);
201 if(padVal > fSector->fThreshold)
a15e6d7d 202 fSector->ColorFromArray(padVal, imgPos);
203 imgPos += 4;
915dabe1 204 }
205}
206
57ffa5fb 207/******************************************************************************/
915dabe1 208
d810d0de 209void AliEveTPCSector2DGL::CreateTexture() const
915dabe1 210{
a97abca8 211 // Create texture that holds pad data.
212
36956ab0 213 if (fImage == 0) {
915dabe1 214 fImage = new UChar_t[fgkTextureByteSize];
215 glGenTextures(1, &fTexture);
216 }
217 memset(fImage, 0, fgkTextureByteSize);
218
219 Int_t rowOff[3], colOff[3];
b56d8877 220 Bool_t isOn[3];
221 rowOff[0] = 0;
d810d0de 222 rowOff[1] = rowOff[2] = -AliEveTPCSectorData::GetSeg(1).GetFirstRow();
b56d8877 223 colOff[0] = colOff[2] = 0;
d810d0de 224 colOff[1] = AliEveTPCSectorData::GetSeg(0).GetNMaxPads();
b56d8877 225 isOn[0] = fSector->fRnrInn;
226 isOn[1] = fSector->fRnrOut1;
227 isOn[2] = fSector->fRnrOut2;
915dabe1 228
891e4bb4 229 fSector->SetupColorArray();
230
915dabe1 231 // Loop over 3 main segments
a15e6d7d 232 for (Int_t sId = 0; sId <= 2; ++sId)
233 {
234 if (isOn[sId] == kFALSE)
b56d8877 235 continue;
d810d0de 236 const AliEveTPCSectorData::SegmentInfo& sInfo = AliEveTPCSectorData::GetSeg(sId);
a15e6d7d 237 for (Int_t row = sInfo.GetFirstRow(); row <= sInfo.GetLastRow(); ++row)
238 {
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
a15e6d7d 289 Float_t yD, yU;
290 Float_t xOff, x;
426530cc 291 Float_t padW = seg.GetPadWidth();
292 Float_t padH = seg.GetPadHeight();
915dabe1 293
294 glBegin(GL_QUADS);
a15e6d7d 295 for (Int_t row = 0; row < seg.GetNRows(); row++)
296 {
297 yD = seg.GetRLow() + row*padH;
298 yU = yD + padH;
299 xOff = -seg.GetNMaxPads()*padW/2;
426530cc 300 Int_t tpcRow = row + seg.GetFirstRow();
d810d0de 301 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
426530cc 302 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
303 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
a15e6d7d 304 for (Int_t pad = deltaPad; pad < maxPad; pad++, pix+=4)
305 {
306 x = xOff + pad*padW;
307 if (pix[3] != 0)
308 {
309 TGLUtil::Color4ubv(pix);
310 glVertex2f(x+padW, yD);
311 glVertex2f(x, yD);
312 glVertex2f(x, yU);
313 glVertex2f(x+padW, yU);
915dabe1 314 }
315 }
316 }
317 glEnd();
318}
319
d810d0de 320void AliEveTPCSector2DGL::DisplayNamedQuads(const AliEveTPCSectorData::SegmentInfo& seg,
a97abca8 321 Int_t startCol, Int_t startRow) const
426530cc 322{
a97abca8 323 // Display segmen data as one quad per pad.
324 // Tag the rows and pads for selection.
325
a15e6d7d 326 Float_t yD, yU;
327 Float_t xOff, x;
426530cc 328 Float_t padW = seg.GetPadWidth();
329 Float_t padH = seg.GetPadHeight();
330
331 glPushName(0);
a15e6d7d 332 for (Int_t row = 0; row < seg.GetNRows(); row++)
333 {
334 yD = seg.GetRLow() + row*padH;
335 yU = yD + padH;
336 xOff = -seg.GetNMaxPads()*padW/2;
426530cc 337 Int_t tpcRow = row + seg.GetFirstRow();
338 glLoadName(tpcRow);
d810d0de 339 Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2;
426530cc 340 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
341 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
342 glPushName(0);
a15e6d7d 343 for (Int_t pad = deltaPad; pad < maxPad; pad++, pix+=4)
344 {
345 x = xOff + pad*padW;
346 if (pix[3] != 0 || fSector->fPickEmpty)
347 {
426530cc 348 glLoadName(pad - deltaPad);
349 glBegin(GL_QUADS);
a15e6d7d 350 glVertex2f(x+padW, yD);
351 glVertex2f(x, yD);
352 glVertex2f(x, yU);
353 glVertex2f(x+padW, yU);
426530cc 354 glEnd();
355 }
356 }
357 glPopName();
358 }
359 glPopName();
360}
361
57ffa5fb 362/******************************************************************************/
915dabe1 363// Frame drawing
57ffa5fb 364/******************************************************************************/
915dabe1 365
d810d0de 366void AliEveTPCSector2DGL::TraceStepsUp(const AliEveTPCSectorData::SegmentInfo& s)
915dabe1 367{
a97abca8 368 // Trace border of segment upwards.
369
915dabe1 370 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
371 Float_t y = s.GetRLow();
372 glVertex2f(x, y);
a15e6d7d 373 for (Int_t i = 0; i < s.GetNYSteps(); ++i)
374 {
915dabe1 375 y = s.GetYStep(i);
376 glVertex2f(x, y);
377 x -= s.GetPadWidth();
378 glVertex2f(x, y);
379 }
380 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
381 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
382}
383
51346b82 384void AliEveTPCSector2DGL::TraceStepsDown(const AliEveTPCSectorData::SegmentInfo& s)
915dabe1 385{
a97abca8 386 // Trace border of segment downwards.
387
915dabe1 388 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
389 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
390 glVertex2f(x, y);
a15e6d7d 391 for (Int_t i = s.GetNYSteps() - 1; i >= 0; --i)
392 {
915dabe1 393 y = s.GetYStep(i);
394 glVertex2f(x, y);
395 x -= s.GetPadWidth();
396 glVertex2f(x, y);
397 }
398 y = s.GetRLow();
399 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
400}
401
d810d0de 402void AliEveTPCSector2DGL::DisplayFrame() const
915dabe1 403{
a97abca8 404 // Display frame of the sector.
405 // Each segment's frame is drawn only if its data is drawn, too.
406
a15e6d7d 407 TGLUtil::Color(fSector->fFrameColor);
915dabe1 408
a15e6d7d 409 if(fSector->fRnrInn)
410 {
b56d8877 411 glBegin(GL_POLYGON);
d810d0de 412 TraceStepsUp (AliEveTPCSectorData::GetInnSeg());
413 TraceStepsDown(AliEveTPCSectorData::GetInnSeg());
b56d8877 414 glEnd();
415 }
a15e6d7d 416 if(fSector->fRnrOut1)
417 {
b56d8877 418 glBegin(GL_POLYGON);
d810d0de 419 TraceStepsUp (AliEveTPCSectorData::GetOut1Seg());
420 TraceStepsDown(AliEveTPCSectorData::GetOut1Seg());
b56d8877 421 glEnd();
422 }
a15e6d7d 423 if(fSector->fRnrOut2)
424 {
b56d8877 425 glBegin(GL_POLYGON);
d810d0de 426 TraceStepsUp (AliEveTPCSectorData::GetOut2Seg());
427 TraceStepsDown(AliEveTPCSectorData::GetOut2Seg());
b56d8877 428 glEnd();
429 }
915dabe1 430}