]>
Commit | Line | Data |
---|---|---|
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 | ||
12 | #include <Alieve/AliEveTPCData.h> | |
915dabe1 | 13 | |
19208112 | 14 | #include <TGLRnrCtx.h> |
15 | #include <TGLSelectRecord.h> | |
16 | #include <TGLIncludes.h> | |
d810d0de | 17 | |
915dabe1 | 18 | using namespace std; |
19 | ||
57ffa5fb | 20 | //______________________________________________________________________________ |
d810d0de | 21 | // AliEveTPCSector2DGL |
68084553 | 22 | // |
23 | ||
d810d0de | 24 | ClassImp(AliEveTPCSector2DGL) |
68084553 | 25 | |
26 | // This can be optimized to non-pow-2 values once everybody has GL 1.4. | |
915dabe1 | 27 | |
d810d0de | 28 | const Int_t AliEveTPCSector2DGL::fgkTextureWidth = 256; |
29 | const Int_t AliEveTPCSector2DGL::fgkTextureHeight = 128; | |
30 | const Int_t AliEveTPCSector2DGL::fgkTextureByteSize = 4*256*128; | |
915dabe1 | 31 | |
57ffa5fb | 32 | /******************************************************************************/ |
915dabe1 | 33 | |
d810d0de | 34 | AliEveTPCSector2DGL::AliEveTPCSector2DGL() : |
265ecb21 | 35 | TGLObject(), |
51346b82 | 36 | |
265ecb21 | 37 | fSector (0), |
38 | fSectorData (0), | |
39 | ||
40 | fImage (0), | |
41 | fTexture (0), | |
42 | fRTS (0) | |
43 | {} | |
915dabe1 | 44 | |
d810d0de | 45 | AliEveTPCSector2DGL::~AliEveTPCSector2DGL() |
915dabe1 | 46 | { |
47 | if(fImage) delete fImage; | |
48 | if(fTexture) glDeleteTextures(1, &fTexture); | |
49 | } | |
50 | ||
57ffa5fb | 51 | /******************************************************************************/ |
915dabe1 | 52 | |
d810d0de | 53 | Bool_t AliEveTPCSector2DGL::SetModel(TObject* obj, const Option_t* /*opt*/) |
915dabe1 | 54 | { |
d810d0de | 55 | if(SetModelCheckClass(obj, AliEveTPCSector2D::Class())) { |
56 | fSector = (AliEveTPCSector2D*) fExternalObj; | |
891e4bb4 | 57 | return kTRUE; |
915dabe1 | 58 | } |
891e4bb4 | 59 | return kFALSE; |
915dabe1 | 60 | } |
61 | ||
d810d0de | 62 | void AliEveTPCSector2DGL::SetBBox() |
915dabe1 | 63 | { |
d810d0de | 64 | SetAxisAlignedBBox(((AliEveTPCSector2D*)fExternalObj)->AssertBBox()); |
915dabe1 | 65 | } |
66 | ||
57ffa5fb | 67 | /******************************************************************************/ |
915dabe1 | 68 | |
d810d0de | 69 | void AliEveTPCSector2DGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, |
19208112 | 70 | TGLSelectRecord & rec) |
a8600b56 | 71 | { |
19208112 | 72 | if (rec.GetN() != 3) return; |
73 | Int_t row = rec.GetItem(1); | |
74 | Int_t pad = rec.GetItem(2); | |
d810d0de | 75 | if (row < 0 || row >= AliEveTPCSectorData::GetNAllRows()) return; |
76 | if (pad < 0 || pad >= AliEveTPCSectorData::GetNPadsInRow(row)) return; | |
96ff1952 | 77 | fSector->PadSelected(row, pad); |
a8600b56 | 78 | } |
79 | ||
57ffa5fb | 80 | /******************************************************************************/ |
a8600b56 | 81 | |
d810d0de | 82 | void AliEveTPCSector2DGL::DirectDraw(TGLRnrCtx& rnrCtx) const |
915dabe1 | 83 | { |
84 | // Actual GL drawing. | |
85 | ||
d810d0de | 86 | // printf("AliEveTPCSector2DGL::DirectDraw \n"); |
915dabe1 | 87 | |
fa3a3795 | 88 | fSectorData = fSector->GetSectorData(); |
915dabe1 | 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 | ||
d810d0de | 106 | const AliEveTPCSectorData::SegmentInfo& iSeg = AliEveTPCSectorData::GetInnSeg(); |
107 | const AliEveTPCSectorData::SegmentInfo& o1Seg = AliEveTPCSectorData::GetOut1Seg(); | |
108 | const AliEveTPCSectorData::SegmentInfo& o2Seg = AliEveTPCSectorData::GetOut2Seg(); | |
915dabe1 | 109 | |
19208112 | 110 | if(rnrCtx.SecSelection()) { |
426530cc | 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 | ||
b56d8877 | 116 | } else { |
426530cc | 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(); | |
915dabe1 | 143 | } |
915dabe1 | 144 | |
426530cc | 145 | } |
915dabe1 | 146 | |
147 | glPopAttrib(); | |
148 | } | |
149 | ||
57ffa5fb | 150 | /******************************************************************************/ |
915dabe1 | 151 | // Data import |
57ffa5fb | 152 | /******************************************************************************/ |
915dabe1 | 153 | |
d810d0de | 154 | void AliEveTPCSector2DGL::LoadPadrow(AliEveTPCSectorData::RowIterator& iter, |
915dabe1 | 155 | Int_t row, Int_t col_off) const |
156 | { | |
b56d8877 | 157 | Int_t padVal; |
51346b82 | 158 | Int_t time, val; |
915dabe1 | 159 | |
b56d8877 | 160 | Int_t minTime = fSector->fMinTime; |
161 | Int_t maxTime = fSector->fMaxTime; | |
162 | Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0); | |
915dabe1 | 163 | |
164 | UChar_t* img_pos = GetRowCol(row, col_off); | |
165 | while (iter.NextPad()) { | |
51346b82 | 166 | padVal = 0; |
915dabe1 | 167 | |
168 | while (iter.Next()) { | |
169 | time = iter.Time(); | |
170 | val = iter.Signal(); | |
171 | ||
b56d8877 | 172 | if(time < minTime || time > maxTime) |
173 | continue; | |
174 | ||
915dabe1 | 175 | if(fSector->fShowMax) { |
b56d8877 | 176 | if(val > padVal) { |
177 | padVal = val; | |
915dabe1 | 178 | } |
179 | } else { | |
b56d8877 | 180 | if(halfBorderTime && (time == minTime || time == maxTime)) |
181 | padVal += val/2; | |
182 | else | |
183 | padVal += val; | |
915dabe1 | 184 | } |
185 | } | |
186 | ||
b56d8877 | 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) | |
891e4bb4 | 192 | fSector->ColorFromArray(padVal, img_pos); |
915dabe1 | 193 | img_pos += 4; |
194 | } | |
195 | } | |
196 | ||
57ffa5fb | 197 | /******************************************************************************/ |
915dabe1 | 198 | |
d810d0de | 199 | void AliEveTPCSector2DGL::CreateTexture() const |
915dabe1 | 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]; | |
b56d8877 | 208 | Bool_t isOn[3]; |
209 | rowOff[0] = 0; | |
d810d0de | 210 | rowOff[1] = rowOff[2] = -AliEveTPCSectorData::GetSeg(1).GetFirstRow(); |
b56d8877 | 211 | colOff[0] = colOff[2] = 0; |
d810d0de | 212 | colOff[1] = AliEveTPCSectorData::GetSeg(0).GetNMaxPads(); |
b56d8877 | 213 | isOn[0] = fSector->fRnrInn; |
214 | isOn[1] = fSector->fRnrOut1; | |
215 | isOn[2] = fSector->fRnrOut2; | |
915dabe1 | 216 | |
891e4bb4 | 217 | fSector->SetupColorArray(); |
218 | ||
915dabe1 | 219 | // Loop over 3 main segments |
220 | for (Int_t sId = 0; sId <= 2; ++sId) { | |
b56d8877 | 221 | if(isOn[sId] == kFALSE) |
222 | continue; | |
d810d0de | 223 | const AliEveTPCSectorData::SegmentInfo& sInfo = AliEveTPCSectorData::GetSeg(sId); |
915dabe1 | 224 | for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) { |
d810d0de | 225 | AliEveTPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row); |
226 | Int_t offset = (sInfo.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(row))/2; | |
915dabe1 | 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); | |
426530cc | 236 | glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); |
915dabe1 | 237 | glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight, |
238 | 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage); | |
239 | ||
240 | } | |
241 | ||
57ffa5fb | 242 | /******************************************************************************/ |
915dabe1 | 243 | // Data display |
57ffa5fb | 244 | /******************************************************************************/ |
915dabe1 | 245 | |
d810d0de | 246 | void AliEveTPCSector2DGL::DisplayTexture(const AliEveTPCSectorData::SegmentInfo& seg, |
426530cc | 247 | Int_t startCol, Int_t startRow) const |
915dabe1 | 248 | { |
426530cc | 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 | ||
915dabe1 | 253 | Float_t u1 = (Float_t) startCol / fgkTextureWidth; |
254 | Float_t v1 = (Float_t) startRow / fgkTextureHeight; | |
426530cc | 255 | Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth; |
256 | Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight; | |
915dabe1 | 257 | |
51346b82 | 258 | glBegin(GL_QUADS); |
426530cc | 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); | |
915dabe1 | 263 | glEnd(); |
264 | } | |
265 | ||
57ffa5fb | 266 | /******************************************************************************/ |
915dabe1 | 267 | |
d810d0de | 268 | void AliEveTPCSector2DGL::DisplayQuads(const AliEveTPCSectorData::SegmentInfo& seg, |
426530cc | 269 | Int_t startCol, Int_t startRow) const |
915dabe1 | 270 | { |
915dabe1 | 271 | Float_t y_d, y_u; |
272 | Float_t x_off, x; | |
426530cc | 273 | Float_t padW = seg.GetPadWidth(); |
274 | Float_t padH = seg.GetPadHeight(); | |
915dabe1 | 275 | |
276 | glBegin(GL_QUADS); | |
426530cc | 277 | for (Int_t row=0; row<seg.GetNRows(); row++) { |
278 | y_d = seg.GetRLow() + row*padH; | |
915dabe1 | 279 | y_u = y_d + padH; |
426530cc | 280 | x_off = -seg.GetNMaxPads()*padW/2; |
281 | Int_t tpcRow = row + seg.GetFirstRow(); | |
d810d0de | 282 | Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2; |
426530cc | 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) { | |
915dabe1 | 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 | ||
d810d0de | 299 | void AliEveTPCSector2DGL::DisplayNamedQuads(const AliEveTPCSectorData::SegmentInfo& seg, |
426530cc | 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); | |
d810d0de | 314 | Int_t deltaPad = (seg.GetNMaxPads() - AliEveTPCSectorData::GetNPadsInRow(tpcRow))/2; |
426530cc | 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; | |
a8600b56 | 320 | if (pix[3] != 0 || fSector->fPickEmpty) { |
426530cc | 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 | ||
57ffa5fb | 335 | /******************************************************************************/ |
915dabe1 | 336 | // Frame drawing |
57ffa5fb | 337 | /******************************************************************************/ |
915dabe1 | 338 | |
d810d0de | 339 | void AliEveTPCSector2DGL::TraceStepsUp(const AliEveTPCSectorData::SegmentInfo& s) |
915dabe1 | 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 | ||
51346b82 | 354 | void AliEveTPCSector2DGL::TraceStepsDown(const AliEveTPCSectorData::SegmentInfo& s) |
915dabe1 | 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 | ||
d810d0de | 369 | void AliEveTPCSector2DGL::DisplayFrame() const |
915dabe1 | 370 | { |
092578a7 | 371 | UChar_t col[4]; |
d810d0de | 372 | TEveUtil::TEveUtil::ColorFromIdx(fSector->fFrameColor, col); |
092578a7 | 373 | glColor4ubv(col); |
915dabe1 | 374 | |
b56d8877 | 375 | if(fSector->fRnrInn) { |
376 | glBegin(GL_POLYGON); | |
d810d0de | 377 | TraceStepsUp (AliEveTPCSectorData::GetInnSeg()); |
378 | TraceStepsDown(AliEveTPCSectorData::GetInnSeg()); | |
b56d8877 | 379 | glEnd(); |
380 | } | |
381 | if(fSector->fRnrOut1) { | |
382 | glBegin(GL_POLYGON); | |
d810d0de | 383 | TraceStepsUp (AliEveTPCSectorData::GetOut1Seg()); |
384 | TraceStepsDown(AliEveTPCSectorData::GetOut1Seg()); | |
b56d8877 | 385 | glEnd(); |
386 | } | |
387 | if(fSector->fRnrOut2) { | |
388 | glBegin(GL_POLYGON); | |
d810d0de | 389 | TraceStepsUp (AliEveTPCSectorData::GetOut2Seg()); |
390 | TraceStepsDown(AliEveTPCSectorData::GetOut2Seg()); | |
b56d8877 | 391 | glEnd(); |
392 | } | |
915dabe1 | 393 | } |