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