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