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