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