3 #include "TPCSector2DGL.h"
5 #include <Alieve/TPCData.h>
7 #include <TStopwatch.h>
12 using namespace Alieve;
15 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
17 const Int_t TPCSector2DGL::fgkTextureWidth = 256;
18 const Int_t TPCSector2DGL::fgkTextureHeight = 128;
19 const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128;
21 /**************************************************************************/
23 TPCSector2DGL::TPCSector2DGL() : TGLObject()
33 TPCSector2DGL::~TPCSector2DGL()
35 if(fImage) delete fImage;
36 if(fTexture) glDeleteTextures(1, &fTexture);
39 /**************************************************************************/
41 Bool_t TPCSector2DGL::SetModel(TObject* obj)
43 if (set_model(obj, "Alieve::TPCSector2D")) {
44 fSector = (TPCSector2D*) fExternalObj;
50 void TPCSector2DGL::SetBBox()
52 set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
55 /**************************************************************************/
57 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& /*flags*/) const
61 // printf("TPCSector2DGL::DirectDraw \n");
63 if(fSector->fTPCData == 0)
66 fSectorData = fSector->fTPCData->GetSectorData(fSector->fSectorID);
68 if(fRTS < fSector->fRTS && fSectorData != 0) {
73 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
74 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
76 glDisable(GL_LIGHTING);
77 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
78 glEnable(GL_COLOR_MATERIAL);
79 glDisable(GL_CULL_FACE);
82 if(fSectorData != 0) {
84 const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg();
85 const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
86 const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
88 if(fSector->fUseTexture) {
91 glDepthMask(GL_FALSE);
92 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
95 glEnable(GL_POLYGON_OFFSET_FILL);
97 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
98 glBindTexture(GL_TEXTURE_2D, fTexture);
99 glEnable(GL_TEXTURE_2D);
102 DisplayTexture(iSeg.GetPadWidth(), iSeg.GetPadHeight(), iSeg.GetRLow(),
103 iSeg.GetNMaxPads(), iSeg.GetNRows(),
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());
114 glDisable(GL_TEXTURE_2D);
117 DisplayQuads(iSeg.GetPadWidth(), iSeg.GetPadHeight(), iSeg.GetRLow(),
118 iSeg.GetNMaxPads(), iSeg.GetNRows(),
120 if(fSector->fRnrOut1)
121 DisplayQuads(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
122 o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
123 iSeg.GetNMaxPads(), 0);
124 if(fSector->fRnrOut2)
125 DisplayQuads(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
126 o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
127 0, o1Seg.GetNRows());
132 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
138 /**************************************************************************/
140 /**************************************************************************/
142 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
143 Int_t row, Int_t col_off) const
148 Int_t minTime = fSector->fMinTime;
149 Int_t maxTime = fSector->fMaxTime;
150 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
152 UChar_t* img_pos = GetRowCol(row, col_off);
153 while (iter.NextPad()) {
156 while (iter.Next()) {
160 if(time < minTime || time > maxTime)
163 if(fSector->fShowMax) {
168 if(halfBorderTime && (time == minTime || time == maxTime))
175 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
176 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
178 padVal = TMath::Min(padVal, fSector->fMaxVal);
179 if(padVal > fSector->fThreshold)
180 fSector->SetupColor(padVal, img_pos);
185 /**************************************************************************/
187 void TPCSector2DGL::CreateTexture() const
190 fImage = new UChar_t[fgkTextureByteSize];
191 glGenTextures(1, &fTexture);
193 memset(fImage, 0, fgkTextureByteSize);
195 Int_t rowOff[3], colOff[3];
198 rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
199 colOff[0] = colOff[2] = 0;
200 colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
201 isOn[0] = fSector->fRnrInn;
202 isOn[1] = fSector->fRnrOut1;
203 isOn[2] = fSector->fRnrOut2;
205 // Loop over 3 main segments
206 for (Int_t sId = 0; sId <= 2; ++sId) {
207 if(isOn[sId] == kFALSE)
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]);
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);
228 /**************************************************************************/
230 /**************************************************************************/
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
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;
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);
250 /**************************************************************************/
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
261 for (Int_t row=0; row<numRows; row++) {
262 y_d = startR + row*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;
270 glVertex2f(x+padW, y_d);
273 glVertex2f(x+padW, y_u);
280 /**************************************************************************/
282 /**************************************************************************/
284 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
286 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
287 Float_t y = s.GetRLow();
289 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
292 x -= s.GetPadWidth();
295 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
296 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
299 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s)
301 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
302 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
304 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
307 x -= s.GetPadWidth();
311 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
314 void TPCSector2DGL::DisplayFrame() const
317 ColorFromIdx(fSector->fFrameColor, col);
320 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
321 if(fSector->fRnrInn) {
323 TraceStepsUp (TPCSectorData::GetInnSeg());
324 TraceStepsDown(TPCSectorData::GetInnSeg());
327 if(fSector->fRnrOut1) {
329 TraceStepsUp (TPCSectorData::GetOut1Seg());
330 TraceStepsDown(TPCSectorData::GetOut1Seg());
333 if(fSector->fRnrOut2) {
335 TraceStepsUp (TPCSectorData::GetOut2Seg());
336 TraceStepsDown(TPCSectorData::GetOut2Seg());