4 #include <Reve/BoxSet.h>
6 #include <TGLIncludes.h>
9 #include <TGLSelectRecord.h>
10 #include <TGLContext.h>
14 //______________________________________________________________________________
17 // A GL rendering class for BoxSet.
22 //______________________________________________________________________________
23 BoxSetGL::BoxSetGL() : fM(0), fBoxDL(0)
25 // Default constructor.
27 // fDLCache = false; // Disable display list.
30 //______________________________________________________________________________
36 /**************************************************************************/
38 /**************************************************************************/
40 //______________________________________________________________________________
41 Int_t BoxSetGL::PrimitiveType() const
43 // Return GL primitive used to render the boxes, based on the
44 // render-mode specified in the model object.
46 return (fM->fRenderMode != DigitSet::RM_Line) ? GL_QUADS : GL_LINE_LOOP;
49 //______________________________________________________________________________
50 inline Bool_t BoxSetGL::SetupColor(const DigitSet::DigitBase& q) const
52 // Set GL color for given primitive.
54 if (fM->fValueIsColor)
56 glColor4ubv((UChar_t*) & q.fValue);
62 Bool_t visible = fM->fPalette->ColorFromValue(q.fValue, fM->fDefaultValue, c);
69 //______________________________________________________________________________
70 void BoxSetGL::MakeOriginBox(Float_t p[24], Float_t dx, Float_t dy, Float_t dz) const
72 // Fill array p to represent a box (0,0,0) - (dx,dy,dz).
75 p[0] = 0; p[1] = dy; p[2] = 0; p += 3;
76 p[0] = dx; p[1] = dy; p[2] = 0; p += 3;
77 p[0] = dx; p[1] = 0; p[2] = 0; p += 3;
78 p[0] = 0; p[1] = 0; p[2] = 0; p += 3;
80 p[0] = 0; p[1] = dy; p[2] = dz; p += 3;
81 p[0] = dx; p[1] = dy; p[2] = dz; p += 3;
82 p[0] = dx; p[1] = 0; p[2] = dz; p += 3;
83 p[0] = 0; p[1] = 0; p[2] = dz;
86 //______________________________________________________________________________
87 inline void BoxSetGL::RenderBox(const Float_t p[24]) const
89 // Render a box specified by points in array p.
93 glVertex3fv(p); glVertex3fv(p + 3);
94 glVertex3fv(p + 6); glVertex3fv(p + 9);
97 glVertex3fv(p + 21); glVertex3fv(p + 18);
98 glVertex3fv(p + 15); glVertex3fv(p + 12);
101 glVertex3fv(p); glVertex3fv(p + 12);
102 glVertex3fv(p + 15); glVertex3fv(p + 3);
104 glNormal3f(0, -1, 0);
105 glVertex3fv(p + 9); glVertex3fv(p + 6);
106 glVertex3fv(p + 18); glVertex3fv(p + 21);
108 glNormal3f(-1, 0, 0);
109 glVertex3fv(p); glVertex3fv(p + 9);
110 glVertex3fv(p + 21); glVertex3fv(p + 12);
113 glVertex3fv(p + 3); glVertex3fv(p + 15);
114 glVertex3fv(p + 18); glVertex3fv(p + 6);
117 //______________________________________________________________________________
118 void BoxSetGL::MakeDisplayList() const
120 // Create a display-list for rendering a single box, based on the
122 // Some box-types don't benefit from the display-list rendering and
123 // so display-list is not created.
125 if (fM->fBoxType == BoxSet::BT_AABox ||
126 fM->fBoxType == BoxSet::BT_AABoxFixedDim)
129 fBoxDL = glGenLists(1);
132 if (fM->fBoxType == BoxSet::BT_AABox)
133 MakeOriginBox(p, 1.0f, 1.0f, 1.0f);
135 MakeOriginBox(p, fM->fDefWidth, fM->fDefHeight, fM->fDefDepth);
137 glNewList(fBoxDL, GL_COMPILE);
138 glBegin(PrimitiveType());
145 /**************************************************************************/
146 // Virtuals from base-classes
147 /**************************************************************************/
149 //______________________________________________________________________________
150 Bool_t BoxSetGL::ShouldDLCache(const TGLRnrCtx & rnrCtx) const
152 // Determines if display-list will be used for rendering.
153 // Virtual from TGLLogicalShape.
157 if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine)
159 return TGLObject::ShouldDLCache(rnrCtx);
162 //______________________________________________________________________________
163 void BoxSetGL::DLCacheDrop()
165 // Called when display lists have been destroyed externally and the
166 // internal display-list data needs to be cleare.
167 // Virtual from TGLLogicalShape.
170 TGLObject::DLCacheDrop();
173 //______________________________________________________________________________
174 void BoxSetGL::DLCachePurge()
176 // Called when display-lists need to be returned to the system.
177 // Virtual from TGLLogicalShape.
179 static const Exc_t eH("BoxSetGL::DLCachePurge ");
181 if (fBoxDL == 0) return;
184 fScene->GetGLCtxIdentity()->RegisterDLNameRangeToWipe(fBoxDL, 1);
188 Warning(eH, "Scene unknown, attempting direct deletion.");
189 glDeleteLists(fBoxDL, 1);
191 TGLObject::DLCachePurge();
194 /**************************************************************************/
196 //______________________________________________________________________________
197 Bool_t BoxSetGL::SetModel(TObject* obj, const Option_t* /*opt*/)
200 // Virtual from TGLObject.
202 Bool_t isok = SetModelCheckClass(obj, Reve::BoxSet::Class());
203 fM = isok ? dynamic_cast<Reve::BoxSet*>(obj) : 0;
207 //______________________________________________________________________________
208 void BoxSetGL::SetBBox()
210 // Fill the bounding-box data of the logical-shape.
211 // Virtual from TGLObject.
213 SetAxisAlignedBBox(fM->AssertBBox());
216 //______________________________________________________________________________
217 void BoxSetGL::DirectDraw(TGLRnrCtx & rnrCtx) const
219 // Actual rendering code.
220 // Virtual from TGLLogicalShape.
222 static const Exc_t eH("BoxSetGL::DirectDraw ");
224 if (rnrCtx.DrawPass() == TGLRnrCtx::kPassOutlineLine)
228 // printf("BoxSetGL::DirectDraw N boxes %d\n", mB.fPlex.Size());
229 if(mB.fPlex.Size() == 0)
232 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
233 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
234 glEnable(GL_COLOR_MATERIAL);
236 if (mB.fRenderMode == DigitSet::RM_Fill)
237 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
238 else if (mB.fRenderMode == DigitSet::RM_Line)
239 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
241 if (mB.fDisableLigting) glDisable(GL_LIGHTING);
243 if (rnrCtx.SecSelection()) glPushName(0);
246 if (rnrCtx.ShapeLOD() < 50)
247 boxSkip = 6 - (rnrCtx.ShapeLOD()+1)/10;
249 VoidCPlex::iterator bi(mB.fPlex);
254 case BoxSet::BT_FreeBox:
256 GLenum primitiveType = PrimitiveType();
259 BoxSet::BFreeBox& b = * (BoxSet::BFreeBox*) bi();
262 if (rnrCtx.SecSelection()) glLoadName(bi.index());
263 glBegin(primitiveType);
264 RenderBox(b.fVertices);
267 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
270 } // end case free-box
272 case BoxSet::BT_AABox:
274 glEnable(GL_NORMALIZE);
277 BoxSet::BAABox& b = * (BoxSet::BAABox*) bi();
280 if (rnrCtx.SecSelection()) glLoadName(bi.index());
282 glTranslatef(b.fA, b.fB, b.fC);
283 glScalef (b.fW, b.fH, b.fD);
287 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
292 case BoxSet::BT_AABoxFixedDim:
296 BoxSet::BAABoxFixedDim& b = * (BoxSet::BAABoxFixedDim*) bi();
299 if (rnrCtx.SecSelection()) glLoadName(bi.index());
300 glTranslatef(b.fA, b.fB, b.fC);
302 glTranslatef(-b.fA, -b.fB, -b.fC);
304 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
311 throw(eH + "unsupported box-type.");
314 } // end switch box-type
316 if (rnrCtx.SecSelection()) glPopName();
321 /**************************************************************************/
323 //______________________________________________________________________________
324 void BoxSetGL::ProcessSelection(TGLRnrCtx & /*rnrCtx*/, TGLSelectRecord & rec)
326 // Processes secondary selection from TGLViewer.
327 // Calls TPointSet3D::PointSelected(Int_t) with index of selected
328 // point as an argument.
330 if (rec.GetN() < 2) return;
331 fM->DigitSelected(rec.GetItem(1));
334 //______________________________________________________________________________
335 void BoxSetGL::Render(TGLRnrCtx & rnrCtx)
337 // Interface for direct rendering from classes that include BoxSet
342 glDeleteLists(fBoxDL, 1);