3 #include "TPCSector2DGL.h"
5 #include <Alieve/TPCData.h>
8 #include <TGLSelectRecord.h>
9 #include <TGLIncludes.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() :
40 TPCSector2DGL::~TPCSector2DGL()
42 if(fImage) delete fImage;
43 if(fTexture) glDeleteTextures(1, &fTexture);
46 /**************************************************************************/
48 Bool_t TPCSector2DGL::SetModel(TObject* obj, const Option_t* /*opt*/)
50 if(SetModelCheckClass(obj, Alieve::TPCSector2D::Class())) {
51 fSector = (TPCSector2D*) fExternalObj;
57 void TPCSector2DGL::SetBBox()
59 SetAxisAlignedBBox(((TPCSector2D*)fExternalObj)->AssertBBox());
62 /**************************************************************************/
64 void TPCSector2DGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/,
65 TGLSelectRecord & rec)
67 if (rec.GetN() != 3) return;
68 Int_t row = rec.GetItem(1);
69 Int_t pad = rec.GetItem(2);
70 if (row < 0 || row >= TPCSectorData::GetNAllRows()) return;
71 if (pad < 0 || pad >= TPCSectorData::GetNPadsInRow(row)) return;
72 fSector->PadSelected(row, pad);
75 /**************************************************************************/
77 void TPCSector2DGL::DirectDraw(TGLRnrCtx& rnrCtx) const
81 // printf("TPCSector2DGL::DirectDraw \n");
83 fSectorData = fSector->GetSectorData();
85 if(fRTS < fSector->fRTS && fSectorData != 0) {
90 glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT |
91 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
93 glDisable(GL_LIGHTING);
94 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
95 glEnable(GL_COLOR_MATERIAL);
96 glDisable(GL_CULL_FACE);
99 if(fSectorData != 0) {
101 const TPCSectorData::SegmentInfo& iSeg = TPCSectorData::GetInnSeg();
102 const TPCSectorData::SegmentInfo& o1Seg = TPCSectorData::GetOut1Seg();
103 const TPCSectorData::SegmentInfo& o2Seg = TPCSectorData::GetOut2Seg();
105 if(rnrCtx.SecSelection()) {
107 if(fSector->fRnrInn) DisplayNamedQuads(iSeg, 0, 0);
108 if(fSector->fRnrOut1) DisplayNamedQuads(o1Seg, iSeg.GetNMaxPads(), 0);
109 if(fSector->fRnrOut2) DisplayNamedQuads(o2Seg, 0, o1Seg.GetNRows());
113 if(fSector->fUseTexture) {
116 glDepthMask(GL_FALSE);
117 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
119 glPolygonOffset(2,2);
120 glEnable(GL_POLYGON_OFFSET_FILL);
122 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
123 glBindTexture(GL_TEXTURE_2D, fTexture);
124 glEnable(GL_TEXTURE_2D);
126 if(fSector->fRnrInn) DisplayTexture(iSeg, 0, 0);
127 if(fSector->fRnrOut1) DisplayTexture(o1Seg, iSeg.GetNMaxPads(), 0);
128 if(fSector->fRnrOut2) DisplayTexture(o2Seg, 0, o1Seg.GetNRows());
130 glDisable(GL_TEXTURE_2D);
132 if(fSector->fRnrInn) DisplayQuads(iSeg, 0, 0);
133 if(fSector->fRnrOut1) DisplayQuads(o1Seg, iSeg.GetNMaxPads(), 0);
134 if(fSector->fRnrOut2) DisplayQuads(o2Seg, 0, o1Seg.GetNRows());
136 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
145 /**************************************************************************/
147 /**************************************************************************/
149 void TPCSector2DGL::LoadPadrow(TPCSectorData::RowIterator& iter,
150 Int_t row, Int_t col_off) const
155 Int_t minTime = fSector->fMinTime;
156 Int_t maxTime = fSector->fMaxTime;
157 Bool_t halfBorderTime = ((maxTime - minTime) % 2 == 0);
159 UChar_t* img_pos = GetRowCol(row, col_off);
160 while (iter.NextPad()) {
163 while (iter.Next()) {
167 if(time < minTime || time > maxTime)
170 if(fSector->fShowMax) {
175 if(halfBorderTime && (time == minTime || time == maxTime))
182 if(fSector->fShowMax == kFALSE && fSector->fAverage) {
183 padVal = (Int_t)((Float_t)padVal / (maxTime - minTime));
185 padVal = TMath::Min(padVal, fSector->fMaxVal);
186 if(padVal > fSector->fThreshold)
187 fSector->ColorFromArray(padVal, img_pos);
192 /**************************************************************************/
194 void TPCSector2DGL::CreateTexture() const
197 fImage = new UChar_t[fgkTextureByteSize];
198 glGenTextures(1, &fTexture);
200 memset(fImage, 0, fgkTextureByteSize);
202 Int_t rowOff[3], colOff[3];
205 rowOff[1] = rowOff[2] = -TPCSectorData::GetSeg(1).GetFirstRow();
206 colOff[0] = colOff[2] = 0;
207 colOff[1] = TPCSectorData::GetSeg(0).GetNMaxPads();
208 isOn[0] = fSector->fRnrInn;
209 isOn[1] = fSector->fRnrOut1;
210 isOn[2] = fSector->fRnrOut2;
212 fSector->SetupColorArray();
214 // Loop over 3 main segments
215 for (Int_t sId = 0; sId <= 2; ++sId) {
216 if(isOn[sId] == kFALSE)
218 const TPCSectorData::SegmentInfo& sInfo = TPCSectorData::GetSeg(sId);
219 for (Int_t row=sInfo.GetFirstRow(); row<=sInfo.GetLastRow(); ++row) {
220 TPCSectorData::RowIterator i = fSectorData->MakeRowIterator(row);
221 Int_t offset = (sInfo.GetNMaxPads() - TPCSectorData::GetNPadsInRow(row))/2;
222 LoadPadrow(i, row + rowOff[sId], offset + colOff[sId]);
226 glBindTexture (GL_TEXTURE_2D, fTexture);
227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
231 glTexEnvf (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
232 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fgkTextureWidth, fgkTextureHeight,
233 0, GL_RGBA, GL_UNSIGNED_BYTE, fImage);
237 /**************************************************************************/
239 /**************************************************************************/
241 void TPCSector2DGL::DisplayTexture(const TPCSectorData::SegmentInfo& seg,
242 Int_t startCol, Int_t startRow) const
244 Float_t w = seg.GetNMaxPads()*seg.GetPadWidth()/2;
245 Float_t y1 = seg.GetRLow();
246 Float_t y2 = y1 + seg.GetNRows()*seg.GetPadHeight();
248 Float_t u1 = (Float_t) startCol / fgkTextureWidth;
249 Float_t v1 = (Float_t) startRow / fgkTextureHeight;
250 Float_t u2 = u1 + (Float_t) seg.GetNMaxPads() / fgkTextureWidth;
251 Float_t v2 = v1 + (Float_t) seg.GetNRows() / fgkTextureHeight;
254 glTexCoord2f(u1, v1); glVertex2f(-w, y1);
255 glTexCoord2f(u1, v2); glVertex2f(-w, y2);
256 glTexCoord2f(u2, v2); glVertex2f( w, y2);
257 glTexCoord2f(u2, v1); glVertex2f( w, y1);
261 /**************************************************************************/
263 void TPCSector2DGL::DisplayQuads(const TPCSectorData::SegmentInfo& seg,
264 Int_t startCol, Int_t startRow) const
268 Float_t padW = seg.GetPadWidth();
269 Float_t padH = seg.GetPadHeight();
272 for (Int_t row=0; row<seg.GetNRows(); row++) {
273 y_d = seg.GetRLow() + row*padH;
275 x_off = -seg.GetNMaxPads()*padW/2;
276 Int_t tpcRow = row + seg.GetFirstRow();
277 Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2;
278 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
279 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
280 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
281 x = x_off + pad*padW;
284 glVertex2f(x+padW, y_d);
287 glVertex2f(x+padW, y_u);
294 void TPCSector2DGL::DisplayNamedQuads(const TPCSectorData::SegmentInfo& seg,
295 Int_t startCol, Int_t startRow) const
299 Float_t padW = seg.GetPadWidth();
300 Float_t padH = seg.GetPadHeight();
303 for (Int_t row=0; row<seg.GetNRows(); row++) {
304 y_d = seg.GetRLow() + row*padH;
306 x_off = -seg.GetNMaxPads()*padW/2;
307 Int_t tpcRow = row + seg.GetFirstRow();
309 Int_t deltaPad = (seg.GetNMaxPads() - TPCSectorData::GetNPadsInRow(tpcRow))/2;
310 Int_t maxPad = seg.GetNMaxPads() - deltaPad;
311 UChar_t *pix = GetRowCol(row + startRow, startCol + deltaPad);
313 for (Int_t pad=deltaPad; pad<maxPad; pad++, pix+=4) {
314 x = x_off + pad*padW;
315 if (pix[3] != 0 || fSector->fPickEmpty) {
316 glLoadName(pad - deltaPad);
318 glVertex2f(x+padW, y_d);
321 glVertex2f(x+padW, y_u);
330 /**************************************************************************/
332 /**************************************************************************/
334 void TPCSector2DGL::TraceStepsUp(const TPCSectorData::SegmentInfo& s)
336 Float_t x = -(s.GetNMaxPads()*1.0/2 - s.GetNYSteps())*s.GetPadWidth();
337 Float_t y = s.GetRLow();
339 for (Int_t i=0; i<s.GetNYSteps(); ++i) {
342 x -= s.GetPadWidth();
345 y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
346 glVertex2f(-s.GetNMaxPads()*s.GetPadWidth()/2, y);
349 void TPCSector2DGL::TraceStepsDown(const TPCSectorData::SegmentInfo& s)
351 Float_t x = s.GetNMaxPads()*s.GetPadWidth()/2;
352 Float_t y = s.GetRLow() + s.GetNRows()*s.GetPadHeight();
354 for (Int_t i=s.GetNYSteps() - 1; i>=0; --i) {
357 x -= s.GetPadWidth();
361 glVertex2f((0.5*s.GetNMaxPads() - s.GetNYSteps())*s.GetPadWidth(), y);
364 void TPCSector2DGL::DisplayFrame() const
367 ColorFromIdx(fSector->fFrameColor, col);
370 if(fSector->fRnrInn) {
372 TraceStepsUp (TPCSectorData::GetInnSeg());
373 TraceStepsDown(TPCSectorData::GetInnSeg());
376 if(fSector->fRnrOut1) {
378 TraceStepsUp (TPCSectorData::GetOut1Seg());
379 TraceStepsDown(TPCSectorData::GetOut1Seg());
382 if(fSector->fRnrOut2) {
384 TraceStepsUp (TPCSectorData::GetOut2Seg());
385 TraceStepsDown(TPCSectorData::GetOut2Seg());