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