3 #include "TPCSector2DGL.h"
5 #include <Alieve/TPCData.h>
7 #include <TStopwatch.h>
9 #include <TGLDrawFlags.h>
13 using namespace Alieve;
16 //______________________________________________________________________
20 ClassImp(TPCSector2DGL)
22 // This can be optimized to non-pow-2 values once everybody has GL 1.4.
24 const Int_t TPCSector2DGL::fgkTextureWidth = 256;
25 const Int_t TPCSector2DGL::fgkTextureHeight = 128;
26 const Int_t TPCSector2DGL::fgkTextureByteSize = 4*256*128;
28 /**************************************************************************/
30 TPCSector2DGL::TPCSector2DGL() : TGLObject()
40 TPCSector2DGL::~TPCSector2DGL()
42 if(fImage) delete fImage;
43 if(fTexture) glDeleteTextures(1, &fTexture);
46 /**************************************************************************/
48 Bool_t TPCSector2DGL::SetModel(TObject* obj)
50 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
51 if(set_model(obj, "Alieve::TPCSector2D")) {
52 #elif ROOT_VERSION_CODE <= ROOT_VERSION(5,13,0)
53 if(SetModelCheckClass(obj, "Alieve::TPCSector2D")) {
55 if(SetModelCheckClass(obj, Alieve::TPCSector2D::Class())) {
57 fSector = (TPCSector2D*) fExternalObj;
63 void TPCSector2DGL::SetBBox()
65 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,11,2)
66 set_axis_aligned_bbox(((TPCSector2D*)fExternalObj)->AssertBBox());
68 SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
72 /**************************************************************************/
74 void TPCSector2DGL::DirectDraw(const TGLDrawFlags& flags) const
78 // printf("TPCSector2DGL::DirectDraw \n");
80 fSectorData = fSector->GetSectorData();
82 if(fRTS < fSector->fRTS && fSectorData != 0) {
87 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
88 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
90 glDisable(GL_LIGHTING);
91 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
92 glEnable(GL_COLOR_MATERIAL);
93 glDisable(GL_CULL_FACE);
96 if(fSectorData != 0) {
98 const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg();
99 const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
100 const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
102 if(flags.SecSelection()) {
104 if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0);
105 if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0);
106 if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows());
110 if(fSector->fUseTexture) {
113 glDepthMask(GL_FALSE);
114 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
116 glPolygonOffset(2,2);
117 glEnable(GL_POLYGON_OFFSET_FILL);
119 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
120 glBindTexture(GL_TEXTURE_2D, fTexture);
121 glEnable(GL_TEXTURE_2D);
123 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
124 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
125 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
127 glDisable(GL_TEXTURE_2D);
129 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
130 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
131 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
133 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
142 /**************************************************************************/
144 /**************************************************************************/
146 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
147 Int_t row, Int_t col_off) const
152 Int_t minTime = fSector->fMinTime;
153 Int_t maxTime = fSector->fMaxTime;
154 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
156 UChar_t* img_pos = GetRowCol(row, col_off);
157 while (iter.NextPad()) {
160 while (iter.Next()) {
164 if(time < minTime || time > maxTime)
167 if(fSector->fShowMax) {
172 if(halfBorderTime && (time == minTime || time == maxTime))
179 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
180 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
182 padVal = TMath::Min(padVal, fSector->fMaxVal);
183 if(padVal > fSector->fThreshold)
184 fSector->ColorFromArray(padVal, img_pos);
189 /**************************************************************************/
191 void TPCSector2DGL::CreateTexture() const
194 fImage = new UChar_t[fgkTextureByteSize];
195 glGenTextures(1, &fTexture);
197 memset(fImage, 0, fgkTextureByteSize);
199 Int_t rowOff[3], colOff[3];
202 rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
203 colOff[0] = colOff[2] = 0;
204 colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
205 isOn[0] = fSector->fRnrInn;
206 isOn[1] = fSector->fRnrOut1;
207 isOn[2] = fSector->fRnrOut2;
209 fSector->SetupColorArray();
211 // Loop over 3 main segments
212 for (Int_t sId = 0; sId <= 2; ++sId) {
213 if(isOn[sId] == kFALSE)
215 const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId);
216 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
217 TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
218 Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2;
219 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
223 glBindTexture (GL_TEXTURE_2D, fTexture);
224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
228 glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
229 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
230 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
234 /**************************************************************************/
236 /**************************************************************************/
238 void TPCSector2DGL::DisplayTexture(const TPCSectorData::SegmentInfo& seg,
239 Int_t startCol, Int_t startRow) const
241 Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2;
242 Float_t y1 = seg.GetRLow();
243 Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
245 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
246 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
247 Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth;
248 Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight;
251 glTexCoord2f(u1, v1); glVertex2f(-w, y1);
252 glTexCoord2f(u1, v2); glVertex2f(-w, y2);
253 glTexCoord2f(u2, v2); glVertex2f( w, y2);
254 glTexCoord2f(u2, v1); glVertex2f( w, y1);
258 /**************************************************************************/
260 void TPCSector2DGL::DisplayQuads(const TPCSectorData::SegmentInfo& seg,
261 Int_t startCol, Int_t startRow) const
265 Float_t padW = seg.GetPadWidth();
266 Float_t padH = seg.GetPadHeight();
269 for (Int_t row=0; row<seg.GetNRows(); row++) {
270 y_d = seg.GetRLow() + row*padH;
272 x_off = -seg.GetNMaxPads()*padW/2;
273 Int_t tpcRow = row + seg.GetFirstRow();
274 Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2;
275 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
276 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
277 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
278 x = x_off + pad*padW;
281 glVertex2f(x+padW, y_d);
284 glVertex2f(x+padW, y_u);
291 void TPCSector2DGL::DisplayNamedQuads(const TPCSectorData::SegmentInfo& seg,
292 Int_t startCol, Int_t startRow) const
296 Float_t padW = seg.GetPadWidth();
297 Float_t padH = seg.GetPadHeight();
300 for (Int_t row=0; row<seg.GetNRows(); row++) {
301 y_d = seg.GetRLow() + row*padH;
303 x_off = -seg.GetNMaxPads()*padW/2;
304 Int_t tpcRow = row + seg.GetFirstRow();
306 Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2;
307 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
308 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
310 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
311 x = x_off + pad*padW;
312 // !!! Potentially replace following 'if', add an option to TPCSector2D.
313 // !!! Details depend on how data is processed during extraction.
315 glLoadName(pad - deltaPad);
317 glVertex2f(x+padW, y_d);
320 glVertex2f(x+padW, y_u);
329 /**************************************************************************/
331 /**************************************************************************/
333 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
335 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
336 Float_t y = s.GetRLow();
338 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
341 x -= s.GetPadWidth();
344 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
345 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
348 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s)
350 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
351 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
353 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
356 x -= s.GetPadWidth();
360 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
363 void TPCSector2DGL::DisplayFrame() const
366 ColorFromIdx(fSector->fFrameColor, col);
369 if(fSector->fRnrInn) {
371 TraceStepsUp (TPCSectorData::GetInnSeg());
372 TraceStepsDown(TPCSectorData::GetInnSeg());
375 if(fSector->fRnrOut1) {
377 TraceStepsUp (TPCSectorData::GetOut1Seg());
378 TraceStepsDown(TPCSectorData::GetOut1Seg());
381 if(fSector->fRnrOut2) {
383 TraceStepsUp (TPCSectorData::GetOut2Seg());
384 TraceStepsDown(TPCSectorData::GetOut2Seg());