3 #include "TPCSector2DGL.h"
5 #include <Alieve/TPCData.h>
7 #include <TStopwatch.h>
12 using namespace Alieve;
15 //______________________________________________________________________
19 ClassImp(TPCSector2DGL)
21 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
23 const Int_t TPCSector2DGL::fgkTextureWidth = 256;
24 const Int_t TPCSector2DGL::fgkTextureHeight = 128;
25 const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128;
27 /**************************************************************************/
29 TPCSector2DGL::TPCSector2DGL() : TGLObject()
39 TPCSector2DGL::~TPCSector2DGL()
41 if(fImage) delete fImage;
42 if(fTexture) glDeleteTextures(1, &fTexture);
45 /**************************************************************************/
47 Bool_t TPCSector2DGL::SetModel(TObject* obj)
49 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
50 if(set_model(obj, "Alieve::TPCSector2D")) {
52 if(SetModelCheckClass(obj, "Alieve::TPCSector2D")) {
54 fSector = (TPCSector2D*) fExternalObj;
60 void TPCSector2DGL::SetBBox()
62 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
63 set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
65 SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
69 /**************************************************************************/
71 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& /*flags*/) const
75 // printf("TPCSector2DGL::DirectDraw \n");
77 fSectorData = fSector->GetSectorData();
79 if(fRTS < fSector->fRTS && fSectorData != 0) {
84 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
85 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
87 glDisable(GL_LIGHTING);
88 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
89 glEnable(GL_COLOR_MATERIAL);
90 glDisable(GL_CULL_FACE);
93 if(fSectorData != 0) {
95 const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg();
96 const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
97 const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
99 if(fSector->fUseTexture) {
102 glDepthMask(GL_FALSE);
103 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
105 glPolygonOffset(2,2);
106 glEnable(GL_POLYGON_OFFSET_FILL);
108 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
109 glBindTexture(GL_TEXTURE_2D, fTexture);
110 glEnable(GL_TEXTURE_2D);
113 DisplayTexture(iSeg.GetPadWidth(), iSeg.GetPadHeight(), iSeg.GetRLow(),
114 iSeg.GetNMaxPads(), iSeg.GetNRows(),
116 if(fSector->fRnrOut1)
117 DisplayTexture(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
118 o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
119 iSeg.GetNMaxPads(), 0);
120 if(fSector->fRnrOut2)
121 DisplayTexture(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
122 o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
123 0, o1Seg.GetNRows());
125 glDisable(GL_TEXTURE_2D);
128 DisplayQuads(iSeg.GetPadWidth(), iSeg.GetPadHeight(), iSeg.GetRLow(),
129 iSeg.GetNMaxPads(), iSeg.GetNRows(),
131 if(fSector->fRnrOut1)
132 DisplayQuads(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
133 o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
134 iSeg.GetNMaxPads(), 0);
135 if(fSector->fRnrOut2)
136 DisplayQuads(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
137 o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
138 0, o1Seg.GetNRows());
143 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
149 /**************************************************************************/
151 /**************************************************************************/
153 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
154 Int_t row, Int_t col_off) const
159 Int_t minTime = fSector->fMinTime;
160 Int_t maxTime = fSector->fMaxTime;
161 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
163 UChar_t* img_pos = GetRowCol(row, col_off);
164 while (iter.NextPad()) {
167 while (iter.Next()) {
171 if(time < minTime || time > maxTime)
174 if(fSector->fShowMax) {
179 if(halfBorderTime && (time == minTime || time == maxTime))
186 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
187 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
189 padVal = TMath::Min(padVal, fSector->fMaxVal);
190 if(padVal > fSector->fThreshold)
191 fSector->ColorFromArray(padVal, img_pos);
196 /**************************************************************************/
198 void TPCSector2DGL::CreateTexture() const
201 fImage = new UChar_t[fgkTextureByteSize];
202 glGenTextures(1, &fTexture);
204 memset(fImage, 0, fgkTextureByteSize);
206 Int_t rowOff[3], colOff[3];
209 rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
210 colOff[0] = colOff[2] = 0;
211 colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
212 isOn[0] = fSector->fRnrInn;
213 isOn[1] = fSector->fRnrOut1;
214 isOn[2] = fSector->fRnrOut2;
216 fSector->SetupColorArray();
218 // Loop over 3 main segments
219 for (Int_t sId = 0; sId <= 2; ++sId) {
220 if(isOn[sId] == kFALSE)
222 const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId);
223 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
224 TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
225 Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2;
226 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
230 glBindTexture (GL_TEXTURE_2D, fTexture);
231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
235 // glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_MODULATE); // Lightning is off anyway.
236 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
237 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
241 /**************************************************************************/
243 /**************************************************************************/
245 void TPCSector2DGL::DisplayTexture(Float_t padW, Float_t padH, Float_t startR,
246 Int_t numMaxPads, Int_t numRows,
247 Int_t startCol, Int_t startRow) const
249 Float_t w = numMaxPads*padW/2;
250 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
251 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
252 Float_t u2 = u1 + (Float_t) numMaxPads / fgkTextureWidth;
253 Float_t v2 = v1 + (Float_t) numRows / fgkTextureHeight;
256 glTexCoord2f(u1, v1); glVertex2f(-w, startR);
257 glTexCoord2f(u1, v2); glVertex2f(-w, startR + numRows*padH);
258 glTexCoord2f(u2, v2); glVertex2f( w, startR + numRows*padH);
259 glTexCoord2f(u2, v1); glVertex2f( w, startR);
263 /**************************************************************************/
265 void TPCSector2DGL::DisplayQuads(Float_t padW, Float_t padH, Float_t startR,
266 Int_t numMaxPads, Int_t numRows,
267 Int_t startCol, Int_t startRow) const
274 for (Int_t row=0; row<numRows; row++) {
275 y_d = startR + row*padH;
277 x_off = -numMaxPads*padW/2;
278 pix = GetRowCol(row + startRow, startCol);
279 for (Int_t pad=0; pad<numMaxPads; pad++, pix+=4) {
280 x = x_off + pad*padW;
283 glVertex2f(x+padW, y_d);
286 glVertex2f(x+padW, y_u);
293 /**************************************************************************/
295 /**************************************************************************/
297 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
299 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
300 Float_t y = s.GetRLow();
302 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
305 x -= s.GetPadWidth();
308 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
309 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
312 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s)
314 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
315 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
317 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
320 x -= s.GetPadWidth();
324 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
327 void TPCSector2DGL::DisplayFrame() const
330 ColorFromIdx(fSector->fFrameColor, col);
333 if(fSector->fRnrInn) {
335 TraceStepsUp (TPCSectorData::GetInnSeg());
336 TraceStepsDown(TPCSectorData::GetInnSeg());
339 if(fSector->fRnrOut1) {
341 TraceStepsUp (TPCSectorData::GetOut1Seg());
342 TraceStepsDown(TPCSectorData::GetOut1Seg());
345 if(fSector->fRnrOut2) {
347 TraceStepsUp (TPCSectorData::GetOut2Seg());
348 TraceStepsDown(TPCSectorData::GetOut2Seg());