]>
Commit | Line | Data |
---|---|---|
915dabe1 | 1 | // $Header$ |
2 | ||
3 | #include "TPCSector2DGL.h" | |
4 | ||
5 | #include <Alieve/TPCData.h> | |
6 | ||
915dabe1 | 7 | #include <TStopwatch.h> |
8 | ||
426530cc | 9 | #include <TGLDrawFlags.h> |
915dabe1 | 10 | #include <GL/gl.h> |
11 | ||
12 | using namespace Reve; | |
13 | using namespace Alieve; | |
14 | using namespace std; | |
15 | ||
68084553 | 16 | //______________________________________________________________________ |
17 | // TPCSector2DGL | |
18 | // | |
19 | ||
20 | ClassImp(TPCSector2DGL) | |
21 | ||
22 | // This can be optimized to non-pow-2 values once everybody has GL 1.4. | |
915dabe1 | 23 | |
24 | const Int_t TPCSector2DGL::fgkTextureWidth = 256; | |
25 | const Int_t TPCSector2DGL::fgkTextureHeight = 128; | |
26 | const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128; | |
27 | ||
28 | /**************************************************************************/ | |
29 | ||
30 | TPCSector2DGL::TPCSector2DGL() : TGLObject() | |
31 | { | |
32 | fSector = 0; | |
33 | fSectorData = 0; | |
34 | ||
35 | fImage = 0; | |
36 | fTexture = 0; | |
37 | fRTS = 0; | |
38 | } | |
39 | ||
40 | TPCSector2DGL::~TPCSector2DGL() | |
41 | { | |
42 | if(fImage) delete fImage; | |
43 | if(fTexture) glDeleteTextures(1, &fTexture); | |
44 | } | |
45 | ||
46 | /**************************************************************************/ | |
47 | ||
48 | Bool_t TPCSector2DGL::SetModel(TObject* obj) | |
49 | { | |
606c4ed7 | 50 | #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2) |
51 | if(set_model(obj, "Alieve::TPCSector2D")) { | |
426530cc | 52 | #elif ROOT_VERSION_CODE <= ROOT_VERSION(5,13,0) |
606c4ed7 | 53 | if(SetModelCheckClass(obj, "Alieve::TPCSector2D")) { |
426530cc | 54 | #else |
55 | if(SetModelCheckClass(obj, Alieve::TPCSector2D::Class())) { | |
606c4ed7 | 56 | #endif |
915dabe1 | 57 | fSector = (TPCSector2D*) fExternalObj; |
891e4bb4 | 58 | return kTRUE; |
915dabe1 | 59 | } |
891e4bb4 | 60 | return kFALSE; |
915dabe1 | 61 | } |
62 | ||
63 | void TPCSector2DGL::SetBBox() | |
64 | { | |
606c4ed7 | 65 | #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2) |
915dabe1 | 66 | set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox()); |
606c4ed7 | 67 | #else |
68 | SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox()); | |
69 | #endif | |
915dabe1 | 70 | } |
71 | ||
72 | /**************************************************************************/ | |
73 | ||
426530cc | 74 | void TPCSector2DGL::DirectDraw(const TGLDrawFlags& flags) const |
915dabe1 | 75 | { |
76 | // Actual GL drawing. | |
77 | ||
78 | // printf("TPCSector2DGL::DirectDraw \n"); | |
79 | ||
fa3a3795 | 80 | fSectorData = fSector->GetSectorData(); |
915dabe1 | 81 | |
82 | if(fRTS < fSector->fRTS && fSectorData != 0) { | |
83 | CreateTexture(); | |
84 | fRTS = fSector->fRTS; | |
85 | } | |
86 | ||
87 | glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | | |
88 | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT); | |
89 | ||
90 | glDisable(GL_LIGHTING); | |
91 | glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |
92 | glEnable(GL_COLOR_MATERIAL); | |
93 | glDisable(GL_CULL_FACE); | |
94 | ||
95 | // Display digits | |
96 | if(fSectorData != 0) { | |
97 | ||
98 | const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg(); | |
99 | const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg(); | |
100 | const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg(); | |
101 | ||
426530cc | 102 | if(flags.SecSelection()) { |
103 | ||
104 | if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0); | |
105 | if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0); | |
106 | if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows()); | |
107 | ||
b56d8877 | 108 | } else { |
426530cc | 109 | |
110 | if(fSector->fUseTexture) { | |
111 | //texture | |
112 | glEnable(GL_BLEND); | |
113 | glDepthMask(GL_FALSE); | |
114 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
115 | ||
116 | glPolygonOffset(2,2); | |
117 | glEnable(GL_POLYGON_OFFSET_FILL); | |
118 | ||
119 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
120 | glBindTexture(GL_TEXTURE_2D, fTexture); | |
121 | glEnable(GL_TEXTURE_2D); | |
122 | ||
123 | if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0); | |
124 | if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0); | |
125 | if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows()); | |
126 | ||
127 | glDisable(GL_TEXTURE_2D); | |
128 | } else { | |
129 | if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0); | |
130 | if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0); | |
131 | if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows()); | |
132 | } | |
133 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
134 | DisplayFrame(); | |
915dabe1 | 135 | } |
915dabe1 | 136 | |
426530cc | 137 | } |
915dabe1 | 138 | |
139 | glPopAttrib(); | |
140 | } | |
141 | ||
142 | /**************************************************************************/ | |
143 | // Data import | |
144 | /**************************************************************************/ | |
145 | ||
146 | void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter, | |
147 | Int_t row, Int_t col_off) const | |
148 | { | |
b56d8877 | 149 | Int_t padVal; |
915dabe1 | 150 | Int_t time, val; |
151 | ||
b56d8877 | 152 | Int_t minTime = fSector->fMinTime; |
153 | Int_t maxTime = fSector->fMaxTime; | |
154 | Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0); | |
915dabe1 | 155 | |
156 | UChar_t* img_pos = GetRowCol(row, col_off); | |
157 | while (iter.NextPad()) { | |
b56d8877 | 158 | padVal = 0; |
915dabe1 | 159 | |
160 | while (iter.Next()) { | |
161 | time = iter.Time(); | |
162 | val = iter.Signal(); | |
163 | ||
b56d8877 | 164 | if(time < minTime || time > maxTime) |
165 | continue; | |
166 | ||
915dabe1 | 167 | if(fSector->fShowMax) { |
b56d8877 | 168 | if(val > padVal) { |
169 | padVal = val; | |
915dabe1 | 170 | } |
171 | } else { | |
b56d8877 | 172 | if(halfBorderTime && (time == minTime || time == maxTime)) |
173 | padVal += val/2; | |
174 | else | |
175 | padVal += val; | |
915dabe1 | 176 | } |
177 | } | |
178 | ||
b56d8877 | 179 | if(fSector->fShowMax == kFALSE && fSector->fAverage) { |
180 | padVal = (Int_t)((Float_t)padVal / (maxTime - minTime)); | |
181 | } | |
182 | padVal = TMath::Min(padVal, fSector->fMaxVal); | |
183 | if(padVal > fSector->fThreshold) | |
891e4bb4 | 184 | fSector->ColorFromArray(padVal, img_pos); |
915dabe1 | 185 | img_pos += 4; |
186 | } | |
187 | } | |
188 | ||
189 | /**************************************************************************/ | |
190 | ||
191 | void TPCSector2DGL::CreateTexture() const | |
192 | { | |
193 | if (fImage == 0 ) { | |
194 | fImage = new UChar_t[fgkTextureByteSize]; | |
195 | glGenTextures(1, &fTexture); | |
196 | } | |
197 | memset(fImage, 0, fgkTextureByteSize); | |
198 | ||
199 | Int_t rowOff[3], colOff[3]; | |
b56d8877 | 200 | Bool_t isOn[3]; |
201 | rowOff[0] = 0; | |
202 | rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow(); | |
203 | colOff[0] = colOff[2] = 0; | |
092578a7 | 204 | colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads(); |
b56d8877 | 205 | isOn[0] = fSector->fRnrInn; |
206 | isOn[1] = fSector->fRnrOut1; | |
207 | isOn[2] = fSector->fRnrOut2; | |
915dabe1 | 208 | |
891e4bb4 | 209 | fSector->SetupColorArray(); |
210 | ||
915dabe1 | 211 | // Loop over 3 main segments |
212 | for (Int_t sId = 0; sId <= 2; ++sId) { | |
b56d8877 | 213 | if(isOn[sId] == kFALSE) |
214 | continue; | |
915dabe1 | 215 | const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId); |
216 | for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) { | |
217 | TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row); | |
218 | Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2; | |
219 | LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]); | |
220 | } | |
221 | } | |
222 | ||
223 | glBindTexture (GL_TEXTURE_2D, fTexture); | |
224 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT); | |
225 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT); | |
226 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
227 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
426530cc | 228 | glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); |
915dabe1 | 229 | glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight, |
230 | 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage); | |
231 | ||
232 | } | |
233 | ||
234 | /**************************************************************************/ | |
235 | // Data display | |
236 | /**************************************************************************/ | |
237 | ||
426530cc | 238 | void TPCSector2DGL::DisplayTexture(const TPCSectorData::SegmentInfo& seg, |
239 | Int_t startCol, Int_t startRow) const | |
915dabe1 | 240 | { |
426530cc | 241 | Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2; |
242 | Float_t y1 = seg.GetRLow(); | |
243 | Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight(); | |
244 | ||
915dabe1 | 245 | Float_t u1 = (Float_t) startCol / fgkTextureWidth; |
246 | Float_t v1 = (Float_t) startRow / fgkTextureHeight; | |
426530cc | 247 | Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth; |
248 | Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight; | |
915dabe1 | 249 | |
250 | glBegin(GL_QUADS); | |
426530cc | 251 | glTexCoord2f(u1, v1); glVertex2f(-w, y1); |
252 | glTexCoord2f(u1, v2); glVertex2f(-w, y2); | |
253 | glTexCoord2f(u2, v2); glVertex2f( w, y2); | |
254 | glTexCoord2f(u2, v1); glVertex2f( w, y1); | |
915dabe1 | 255 | glEnd(); |
256 | } | |
257 | ||
258 | /**************************************************************************/ | |
259 | ||
426530cc | 260 | void TPCSector2DGL::DisplayQuads(const TPCSectorData::SegmentInfo& seg, |
261 | Int_t startCol, Int_t startRow) const | |
915dabe1 | 262 | { |
915dabe1 | 263 | Float_t y_d, y_u; |
264 | Float_t x_off, x; | |
426530cc | 265 | Float_t padW = seg.GetPadWidth(); |
266 | Float_t padH = seg.GetPadHeight(); | |
915dabe1 | 267 | |
268 | glBegin(GL_QUADS); | |
426530cc | 269 | for (Int_t row=0; row<seg.GetNRows(); row++) { |
270 | y_d = seg.GetRLow() + row*padH; | |
915dabe1 | 271 | y_u = y_d + padH; |
426530cc | 272 | x_off = -seg.GetNMaxPads()*padW/2; |
273 | Int_t tpcRow = row + seg.GetFirstRow(); | |
274 | Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2; | |
275 | Int_t maxPad = seg.GetNMaxPads() - deltaPad; | |
276 | UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad); | |
277 | for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) { | |
915dabe1 | 278 | x = x_off + pad*padW; |
279 | if (pix[3] != 0) { | |
280 | glColor4ubv(pix); | |
281 | glVertex2f(x+padW, y_d); | |
282 | glVertex2f(x, y_d); | |
283 | glVertex2f(x, y_u); | |
284 | glVertex2f(x+padW, y_u); | |
285 | } | |
286 | } | |
287 | } | |
288 | glEnd(); | |
289 | } | |
290 | ||
426530cc | 291 | void TPCSector2DGL::DisplayNamedQuads(const TPCSectorData::SegmentInfo& seg, |
292 | Int_t startCol, Int_t startRow) const | |
293 | { | |
294 | Float_t y_d, y_u; | |
295 | Float_t x_off, x; | |
296 | Float_t padW = seg.GetPadWidth(); | |
297 | Float_t padH = seg.GetPadHeight(); | |
298 | ||
299 | glPushName(0); | |
300 | for (Int_t row=0; row<seg.GetNRows(); row++) { | |
301 | y_d = seg.GetRLow() + row*padH; | |
302 | y_u = y_d + padH; | |
303 | x_off = -seg.GetNMaxPads()*padW/2; | |
304 | Int_t tpcRow = row + seg.GetFirstRow(); | |
305 | glLoadName(tpcRow); | |
306 | Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2; | |
307 | Int_t maxPad = seg.GetNMaxPads() - deltaPad; | |
308 | UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad); | |
309 | glPushName(0); | |
310 | for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) { | |
311 | x = x_off + pad*padW; | |
312 | // !!! Potentially replace following 'if', add an option to TPCSector2D. | |
313 | // !!! Details depend on how data is processed during extraction. | |
314 | if (pix[3] != 0) { | |
315 | glLoadName(pad - deltaPad); | |
316 | glBegin(GL_QUADS); | |
317 | glVertex2f(x+padW, y_d); | |
318 | glVertex2f(x, y_d); | |
319 | glVertex2f(x, y_u); | |
320 | glVertex2f(x+padW, y_u); | |
321 | glEnd(); | |
322 | } | |
323 | } | |
324 | glPopName(); | |
325 | } | |
326 | glPopName(); | |
327 | } | |
328 | ||
915dabe1 | 329 | /**************************************************************************/ |
330 | // Frame drawing | |
331 | /**************************************************************************/ | |
332 | ||
333 | void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s) | |
334 | { | |
335 | Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth(); | |
336 | Float_t y = s.GetRLow(); | |
337 | glVertex2f(x, y); | |
338 | for (Int_t i=0; i<s.GetNYSteps(); ++i) { | |
339 | y = s.GetYStep(i); | |
340 | glVertex2f(x, y); | |
341 | x -= s.GetPadWidth(); | |
342 | glVertex2f(x, y); | |
343 | } | |
344 | y = s.GetRLow() + s.GetNRows()*s.GetPadHeight(); | |
345 | glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y); | |
346 | } | |
347 | ||
348 | void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s) | |
349 | { | |
350 | Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2; | |
351 | Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight(); | |
352 | glVertex2f(x, y); | |
353 | for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) { | |
354 | y = s.GetYStep(i); | |
355 | glVertex2f(x, y); | |
356 | x -= s.GetPadWidth(); | |
357 | glVertex2f(x, y); | |
358 | } | |
359 | y = s.GetRLow(); | |
360 | glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y); | |
361 | } | |
362 | ||
363 | void TPCSector2DGL::DisplayFrame() const | |
364 | { | |
092578a7 | 365 | UChar_t col[4]; |
366 | ColorFromIdx(fSector->fFrameColor, col); | |
367 | glColor4ubv(col); | |
915dabe1 | 368 | |
b56d8877 | 369 | if(fSector->fRnrInn) { |
370 | glBegin(GL_POLYGON); | |
371 | TraceStepsUp (TPCSectorData::GetInnSeg()); | |
372 | TraceStepsDown(TPCSectorData::GetInnSeg()); | |
373 | glEnd(); | |
374 | } | |
375 | if(fSector->fRnrOut1) { | |
376 | glBegin(GL_POLYGON); | |
377 | TraceStepsUp (TPCSectorData::GetOut1Seg()); | |
378 | TraceStepsDown(TPCSectorData::GetOut1Seg()); | |
379 | glEnd(); | |
380 | } | |
381 | if(fSector->fRnrOut2) { | |
382 | glBegin(GL_POLYGON); | |
383 | TraceStepsUp (TPCSectorData::GetOut2Seg()); | |
384 | TraceStepsDown(TPCSectorData::GetOut2Seg()); | |
385 | glEnd(); | |
386 | } | |
915dabe1 | 387 | } |