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 ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
44 if(set_model(obj, "Alieve::TPCSector2D")) {
46 if(SetModelCheckClass(obj, "Alieve::TPCSector2D")) {
48 fSector = (TPCSector2D*) fExternalObj;
54 void TPCSector2DGL::SetBBox()
56 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
57 set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
59 SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
63 /**************************************************************************/
65 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& /*flags*/) const
69 // printf("TPCSector2DGL::DirectDraw \n");
71 if(fSector->fTPCData == 0)
74 fSectorData = fSector->fTPCData->GetSectorData(fSector->fSectorID);
76 if(fRTS < fSector->fRTS && fSectorData != 0) {
81 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
82 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
84 glDisable(GL_LIGHTING);
85 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
86 glEnable(GL_COLOR_MATERIAL);
87 glDisable(GL_CULL_FACE);
90 if(fSectorData != 0) {
92 const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg();
93 const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
94 const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
96 if(fSector->fUseTexture) {
99 glDepthMask(GL_FALSE);
100 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
102 glPolygonOffset(2,2);
103 glEnable(GL_POLYGON_OFFSET_FILL);
105 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
106 glBindTexture(GL_TEXTURE_2D, fTexture);
107 glEnable(GL_TEXTURE_2D);
110 DisplayTexture(iSeg.GetPadWidth(), iSeg.GetPadHeight(), iSeg.GetRLow(),
111 iSeg.GetNMaxPads(), iSeg.GetNRows(),
113 if(fSector->fRnrOut1)
114 DisplayTexture(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
115 o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
116 iSeg.GetNMaxPads(), 0);
117 if(fSector->fRnrOut2)
118 DisplayTexture(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
119 o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
120 0, o1Seg.GetNRows());
122 glDisable(GL_TEXTURE_2D);
125 DisplayQuads(iSeg.GetPadWidth(), iSeg.GetPadHeight(), iSeg.GetRLow(),
126 iSeg.GetNMaxPads(), iSeg.GetNRows(),
128 if(fSector->fRnrOut1)
129 DisplayQuads(o1Seg.GetPadWidth(), o1Seg.GetPadHeight(), o1Seg.GetRLow(),
130 o1Seg.GetNMaxPads(), o1Seg.GetNRows(),
131 iSeg.GetNMaxPads(), 0);
132 if(fSector->fRnrOut2)
133 DisplayQuads(o2Seg.GetPadWidth(), o2Seg.GetPadHeight(), o2Seg.GetRLow(),
134 o2Seg.GetNMaxPads(), o2Seg.GetNRows(),
135 0, o1Seg.GetNRows());
140 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
146 /**************************************************************************/
148 /**************************************************************************/
150 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
151 Int_t row, Int_t col_off) const
156 Int_t minTime = fSector->fMinTime;
157 Int_t maxTime = fSector->fMaxTime;
158 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
160 UChar_t* img_pos = GetRowCol(row, col_off);
161 while (iter.NextPad()) {
164 while (iter.Next()) {
168 if(time < minTime || time > maxTime)
171 if(fSector->fShowMax) {
176 if(halfBorderTime && (time == minTime || time == maxTime))
183 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
184 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
186 padVal = TMath::Min(padVal, fSector->fMaxVal);
187 if(padVal > fSector->fThreshold)
188 fSector->SetupColor(padVal, img_pos);
193 /**************************************************************************/
195 void TPCSector2DGL::CreateTexture() const
198 fImage = new UChar_t[fgkTextureByteSize];
199 glGenTextures(1, &fTexture);
201 memset(fImage, 0, fgkTextureByteSize);
203 Int_t rowOff[3], colOff[3];
206 rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
207 colOff[0] = colOff[2] = 0;
208 colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
209 isOn[0] = fSector->fRnrInn;
210 isOn[1] = fSector->fRnrOut1;
211 isOn[2] = fSector->fRnrOut2;
213 // Loop over 3 main segments
214 for (Int_t sId = 0; sId <= 2; ++sId) {
215 if(isOn[sId] == kFALSE)
217 const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId);
218 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
219 TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
220 Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2;
221 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
225 glBindTexture (GL_TEXTURE_2D, fTexture);
226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
230 // glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_MODULATE); // Lightning is off anyway.
231 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
232 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
236 /**************************************************************************/
238 /**************************************************************************/
240 void TPCSector2DGL::DisplayTexture(Float_t padW, Float_t padH, Float_t startR,
241 Int_t numMaxPads, Int_t numRows,
242 Int_t startCol, Int_t startRow) const
244 Float_t w = numMaxPads*padW/2;
245 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
246 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
247 Float_t u2 = u1 + (Float_t) numMaxPads / fgkTextureWidth;
248 Float_t v2 = v1 + (Float_t) numRows / fgkTextureHeight;
251 glTexCoord2f(u1, v1); glVertex2f(-w, startR);
252 glTexCoord2f(u1, v2); glVertex2f(-w, startR + numRows*padH);
253 glTexCoord2f(u2, v2); glVertex2f( w, startR + numRows*padH);
254 glTexCoord2f(u2, v1); glVertex2f( w, startR);
258 /**************************************************************************/
260 void TPCSector2DGL::DisplayQuads(Float_t padW, Float_t padH, Float_t startR,
261 Int_t numMaxPads, Int_t numRows,
262 Int_t startCol, Int_t startRow) const
269 for (Int_t row=0; row<numRows; row++) {
270 y_d = startR + row*padH;
272 x_off = -numMaxPads*padW/2;
273 pix = GetRowCol(row + startRow, startCol);
274 for (Int_t pad=0; pad<numMaxPads; pad++, pix+=4) {
275 x = x_off + pad*padW;
278 glVertex2f(x+padW, y_d);
281 glVertex2f(x+padW, y_u);
288 /**************************************************************************/
290 /**************************************************************************/
292 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
294 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
295 Float_t y = s.GetRLow();
297 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
300 x -= s.GetPadWidth();
303 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
304 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
307 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s)
309 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
310 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
312 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
315 x -= s.GetPadWidth();
319 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
322 void TPCSector2DGL::DisplayFrame() const
325 ColorFromIdx(fSector->fFrameColor, col);
328 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
329 if(fSector->fRnrInn) {
331 TraceStepsUp (TPCSectorData::GetInnSeg());
332 TraceStepsDown(TPCSectorData::GetInnSeg());
335 if(fSector->fRnrOut1) {
337 TraceStepsUp (TPCSectorData::GetOut1Seg());
338 TraceStepsDown(TPCSectorData::GetOut1Seg());
341 if(fSector->fRnrOut2) {
343 TraceStepsUp (TPCSectorData::GetOut2Seg());
344 TraceStepsDown(TPCSectorData::GetOut2Seg());