Logo ROOT  
Reference Guide
TEveBoxSetGL.cxx
Go to the documentation of this file.
1// @(#)root/eve:$Id$
2// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TEveBoxSetGL.h"
13#include "TEveBoxSet.h"
14
15#include "TGLIncludes.h"
16#include "TGLRnrCtx.h"
17#include "TGLSelectRecord.h"
18#include "TGLQuadric.h"
19
20/** \class TEveBoxSetGL
21\ingroup TEve
22A GL rendering class for TEveBoxSet.
23*/
24
26
27////////////////////////////////////////////////////////////////////////////////
28/// Default constructor.
29
31{
32 fDLCache = kFALSE; // Disable display list, used internally for boxes, cones.
34}
35
36////////////////////////////////////////////////////////////////////////////////
37/// Destructor.
38
40{
42}
43
44////////////////////////////////////////////////////////////////////////////////
45/// Return GL primitive used to render the boxes, based on the
46/// render-mode specified in the model object.
47
49{
51}
52
53////////////////////////////////////////////////////////////////////////////////
54/// Fill array p to represent a box (0,0,0) - (dx,dy,dz).
55
57{
58 // bottom
59 p[0][0] = 0; p[0][1] = dy; p[0][2] = 0;
60 p[1][0] = dx; p[1][1] = dy; p[1][2] = 0;
61 p[2][0] = dx; p[2][1] = 0; p[2][2] = 0;
62 p[3][0] = 0; p[3][1] = 0; p[3][2] = 0;
63 // top
64 p[4][0] = 0; p[4][1] = dy; p[4][2] = dz;
65 p[5][0] = dx; p[5][1] = dy; p[5][2] = dz;
66 p[6][0] = dx; p[6][1] = 0; p[6][2] = dz;
67 p[7][0] = 0; p[7][1] = 0; p[7][2] = dz;
68}
69
70////////////////////////////////////////////////////////////////////////////////
71/// Render a box specified by points in array p with standard
72/// axis-aligned normals.
73
74inline void TEveBoxSetGL::RenderBoxStdNorm(const Float_t p[8][3]) const
75{
76 // bottom: 0123
77 glNormal3f(0, 0, -1);
78 glVertex3fv(p[0]); glVertex3fv(p[1]);
79 glVertex3fv(p[2]); glVertex3fv(p[3]);
80 // top: 7654
81 glNormal3f(0, 0, 1);
82 glVertex3fv(p[7]); glVertex3fv(p[6]);
83 glVertex3fv(p[5]); glVertex3fv(p[4]);
84 // back: 0451
85 glNormal3f(0, 1, 0);
86 glVertex3fv(p[0]); glVertex3fv(p[4]);
87 glVertex3fv(p[5]); glVertex3fv(p[1]);
88 // front: 3267
89 glNormal3f(0, -1, 0);
90 glVertex3fv(p[3]); glVertex3fv(p[2]);
91 glVertex3fv(p[6]); glVertex3fv(p[7]);
92 // left: 0374
93 glNormal3f(-1, 0, 0);
94 glVertex3fv(p[0]); glVertex3fv(p[3]);
95 glVertex3fv(p[7]); glVertex3fv(p[4]);
96 // right: 1562
97 glNormal3f(1, 0, 0);
98 glVertex3fv(p[1]); glVertex3fv(p[5]);
99 glVertex3fv(p[6]); glVertex3fv(p[2]);
100}
101
102namespace
103{
104 void subtract_and_normalize(const Float_t a[3], const Float_t b[3],
105 Float_t o[3])
106 {
107 // Calculate a - b and normalize the result.
108 o[0] = a[0] - b[0];
109 o[1] = a[1] - b[1];
110 o[2] = a[2] - b[2];
111 Float_t d = sqrtf(o[0]*o[0] + o[1]*o[1] + o[2]*o[2]);
112 if (d != 0)
113 {
114 d = 1.0f / d;
115 o[0] *= d;
116 o[1] *= d;
117 o[2] *= d;
118 }
119 }
120}
121////////////////////////////////////////////////////////////////////////////////
122/// Render box, calculate normals on the fly from first three points.
123
125{
126 Float_t e[6][3], n[3];
127 subtract_and_normalize(p[1], p[0], e[0]);
128 subtract_and_normalize(p[3], p[0], e[1]);
129 subtract_and_normalize(p[4], p[0], e[2]);
130 subtract_and_normalize(p[5], p[6], e[3]);
131 subtract_and_normalize(p[7], p[6], e[4]);
132 subtract_and_normalize(p[2], p[6], e[5]);
133
134 // bottom: 0123
135 glNormal3fv(TMath::Cross(e[0], e[1], n));
136 glVertex3fv(p[0]); glVertex3fv(p[1]);
137 glVertex3fv(p[2]); glVertex3fv(p[3]);
138 // top: 7654
139 glNormal3fv(TMath::Cross(e[3], e[4], n));
140 glVertex3fv(p[7]); glVertex3fv(p[6]);
141 glVertex3fv(p[5]); glVertex3fv(p[4]);
142 // back: 0451
143 glNormal3fv(TMath::Cross(e[2], e[0], n));
144 glVertex3fv(p[0]); glVertex3fv(p[4]);
145 glVertex3fv(p[5]); glVertex3fv(p[1]);
146 // front: 3267
147 glNormal3fv(TMath::Cross(e[4], e[5], n));
148 glVertex3fv(p[3]); glVertex3fv(p[2]);
149 glVertex3fv(p[6]); glVertex3fv(p[7]);
150 // left: 0374
151 glNormal3fv(TMath::Cross(e[1], e[2], n));
152 glVertex3fv(p[0]); glVertex3fv(p[3]);
153 glVertex3fv(p[7]); glVertex3fv(p[4]);
154 // right: 1562
155 glNormal3fv(TMath::Cross(e[5], e[3], n));
156 glVertex3fv(p[1]); glVertex3fv(p[5]);
157 glVertex3fv(p[6]); glVertex3fv(p[2]);
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Create a display-list for rendering a single box, based on the
162/// current box-type.
163/// Some box-types don't benefit from the display-list rendering and
164/// so display-list is not created.
165
167{
173 {
174 if (fBoxDL == 0)
175 fBoxDL = glGenLists(1);
176
177 glNewList(fBoxDL, GL_COMPILE);
178
180 {
181 glBegin(PrimitiveType());
182 Float_t p[8][3];
184 MakeOriginBox(p, 1.0f, 1.0f, 1.0f);
185 else
188 glEnd();
189 }
190 else if (fM->fBoxType < TEveBoxSet::kBT_Hex)
191 {
192 static TGLQuadric quad;
193 Int_t nt = 15; // number of corners
194 gluCylinder(quad.Get(), 0, 1, 1, nt, 1);
195
196 if (fM->fDrawConeCap)
197 {
198 glPushMatrix();
199 glTranslatef(0, 0, 1);
200 gluDisk(quad.Get(), 0, 1, nt, 1);
201 glPopMatrix();
202 }
203 }
204 else // Hexagons
205 {
206 static TGLQuadric quad;
207 Int_t nt = 6; // number of corners
208 gluCylinder(quad.Get(), 1, 1, 1, nt, 1);
209
210 gluQuadricOrientation(quad.Get(), GLU_INSIDE);
211 gluDisk(quad.Get(), 0, 1, nt, 1);
212 gluQuadricOrientation(quad.Get(), GLU_OUTSIDE);
213
214 glPushMatrix();
215 glTranslatef(0, 0, 1);
216 gluDisk(quad.Get(), 0, 1, nt, 1);
217 glPopMatrix();
218 }
219
220 glEndList();
221
222 TGLUtil::CheckError("TEveBoxSetGL::MakeDisplayList");
223 }
224}
225
226////////////////////////////////////////////////////////////////////////////////
227/// Determines if display-list will be used for rendering.
228/// Virtual from TGLLogicalShape.
229
231{
232 return TEveDigitSetGL::ShouldDLCache(rnrCtx);
233}
234
235////////////////////////////////////////////////////////////////////////////////
236/// Called when display lists have been destroyed externally and the
237/// internal display-list data needs to be cleare.
238/// Virtual from TGLLogicalShape.
239
241{
242 fBoxDL = 0;
244}
245
246////////////////////////////////////////////////////////////////////////////////
247/// Called when display-lists need to be returned to the system.
248/// Virtual from TGLLogicalShape.
249
251{
252 if (fBoxDL != 0)
253 {
255 fBoxDL = 0;
256 }
258}
259
260////////////////////////////////////////////////////////////////////////////////
261/// Set model object.
262/// Virtual from TGLObject.
263
265{
266 fM = SetModelDynCast<TEveBoxSet>(obj);
267 return kTRUE;
268}
269
270namespace
271{
272 inline void AntiFlick(Float_t x, Float_t y, Float_t z)
273 {
274 // Render anti-flickering point.
275 glBegin(GL_POINTS);
276 glVertex3f(x, y, z);
277 glEnd();
278 }
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// GL rendering for all box-types.
283
285{
286 static const TEveException eH("TEveBoxSetGL::RenderBoxes ");
287
288 if (rnrCtx.SecSelection()) glPushName(0);
289
290 Int_t boxSkip = 0;
291 if (fM->fBoxSkip > 0 && rnrCtx.CombiLOD() < TGLRnrCtx::kLODHigh &&
292 !rnrCtx.SecSelection())
293 {
294 boxSkip = TMath::Nint(TMath::Power(fM->fBoxSkip, 2.0 - 0.02*rnrCtx.CombiLOD()));
295 }
296
298 if (rnrCtx.Highlight() && fHighlightSet)
300
301 switch (fM->fBoxType)
302 {
303
305 {
306 GLenum primitiveType = PrimitiveType();
307 while (bi.next())
308 {
310 if (SetupColor(b))
311 {
312 if (rnrCtx.SecSelection()) glLoadName(bi.index());
313 glBegin(primitiveType);
314 RenderBoxAutoNorm(b.fVertices);
315 glEnd();
316 if (fM->fAntiFlick)
317 AntiFlick(0.5f*(b.fVertices[0][0] + b.fVertices[6][0]),
318 0.5f*(b.fVertices[0][1] + b.fVertices[6][1]),
319 0.5f*(b.fVertices[0][2] + b.fVertices[6][2]));
320 }
321 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
322 }
323 break;
324 } // end case free-box
325
327 {
328 glEnable(GL_NORMALIZE);
329 while (bi.next())
330 {
332 if (SetupColor(b))
333 {
334 if (rnrCtx.SecSelection()) glLoadName(bi.index());
335 glPushMatrix();
336 glTranslatef(b.fA, b.fB, b.fC);
337 glScalef (b.fW, b.fH, b.fD);
338 glCallList(fBoxDL);
339 if (fM->fAntiFlick)
340 AntiFlick(0.5f, 0.5f, 0.5f);
341 glPopMatrix();
342 }
343 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
344 }
345 break;
346 }
347
349 {
350 while (bi.next())
351 {
353 if (SetupColor(b))
354 {
355 if (rnrCtx.SecSelection()) glLoadName(bi.index());
356 glTranslatef(b.fA, b.fB, b.fC);
357 glCallList(fBoxDL);
358 if (fM->fAntiFlick)
359 AntiFlick(0.5f*fM->fDefWidth, 0.5f*fM->fDefHeight, 0.5f*fM->fDefDepth);
360 glTranslatef(-b.fA, -b.fB, -b.fC);
361 }
362 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
363 }
364 break;
365 }
366
368 {
369 using namespace TMath;
370
371 glEnable(GL_NORMALIZE);
372 Float_t theta=0, phi=0, h=0;
373 while (bi.next())
374 {
376 if (SetupColor(b))
377 {
378 if (rnrCtx.SecSelection()) glLoadName(bi.index());
379 h = b.fDir.Mag();
380 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
381 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
382 glPushMatrix();
383 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
384 glRotatef(phi, 0, 0, 1);
385 glRotatef(90 - theta, 0, 1, 0);
386 glScalef (b.fR, b.fR, h);
387 glCallList(fBoxDL);
388 if (fM->fAntiFlick)
389 AntiFlick(0.0f, 0.0f, 0.5f);
390 glPopMatrix();
391 }
392 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
393 }
394 break;
395 }
396
398 {
399 using namespace TMath;
400
401 glEnable(GL_NORMALIZE);
402 Float_t theta=0, phi=0, h=0;
403 while (bi.next())
404 {
406 if (SetupColor(b))
407 {
408 if (rnrCtx.SecSelection()) glLoadName(bi.index());
409 h = b.fDir.Mag();
410 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
411 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
412 glPushMatrix();
413 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
414 glRotatef(phi, 0, 0, 1);
415 glRotatef(90 - theta, 0, 1, 0);
416 glRotatef(b.fAngle, 0, 0, 1);
417 glScalef (b.fR, b.fR2, h);
418 glCallList(fBoxDL);
419 if (fM->fAntiFlick)
420 AntiFlick(0.0f, 0.0f, 0.5f);
421 glPopMatrix();
422 }
423 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
424 }
425 break;
426 }
427
429 {
430 using namespace TMath;
431
432 glEnable(GL_NORMALIZE);
433 while (bi.next())
434 {
436 if (SetupColor(h))
437 {
438 if (rnrCtx.SecSelection()) glLoadName(bi.index());
439 glPushMatrix();
440 glTranslatef(h.fPos.fX, h.fPos.fY, h.fPos.fZ);
441 glRotatef(h.fAngle, 0, 0, 1);
442 glScalef (h.fR, h.fR, h.fDepth);
443 glCallList(fBoxDL);
444 if (fM->fAntiFlick)
445 AntiFlick(0.0f, 0.0f, 0.5f);
446 glPopMatrix();
447 }
448 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
449 }
450 break;
451 }
452
453 default:
454 {
455 throw eH + "unsupported box-type.";
456 }
457
458 } // end switch box-type
459
460 if (rnrCtx.SecSelection()) glPopName();
461}
462
463////////////////////////////////////////////////////////////////////////////////
464/// Actual rendering code.
465/// Virtual from TGLLogicalShape.
466
468{
469 TEveBoxSet& mB = * fM;
470 // printf("TEveBoxSetGL::DirectDraw N boxes %d\n", mB.fPlex.Size());
471
472 if (mB.fPlex.Size() > 0)
473 {
475
476 if (! mB.fSingleColor && ! mB.fValueIsColor && mB.fPalette == 0)
477 {
478 mB.AssertPalette();
479 }
480
481 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
482
483 if ( ! rnrCtx.IsDrawPassOutlineLine())
484 {
486 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
487 else if (mB.fRenderMode == TEveDigitSet::kRM_Line)
488 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
489 }
490
491 if (mB.fBoxType == TEveBoxSet::kBT_Cone ||
493 {
494 glDisable(GL_CULL_FACE);
495 }
496
497 if (mB.fDisableLighting) glDisable(GL_LIGHTING);
498
499 RenderBoxes(rnrCtx);
500
501 glPopAttrib();
502 }
503
504 DrawFrameIfNeeded(rnrCtx);
505}
506
507////////////////////////////////////////////////////////////////////////////////
508/// Interface for direct rendering from classes that include TEveBoxSet
509/// as a member.
510
512{
513 DirectDraw(rnrCtx);
514}
#define GLU_OUTSIDE
Definition: GL_glu.h:203
#define GL_QUADS
Definition: GL_glu.h:290
#define GL_POINTS
Definition: GL_glu.h:283
#define GLU_INSIDE
Definition: GL_glu.h:204
#define GL_LINE_LOOP
Definition: GL_glu.h:285
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
const Bool_t kFALSE
Definition: RtypesCore.h:90
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define ClassImp(name)
Definition: Rtypes.h:361
A GL rendering class for TEveBoxSet.
Definition: TEveBoxSetGL.h:19
TEveBoxSetGL()
Default constructor.
virtual Bool_t ShouldDLCache(const TGLRnrCtx &rnrCtx) const
Determines if display-list will be used for rendering.
UInt_t fBoxDL
Definition: TEveBoxSetGL.h:26
virtual void DLCachePurge()
Called when display-lists need to be returned to the system.
void MakeDisplayList() const
Create a display-list for rendering a single box, based on the current box-type.
virtual Bool_t SetModel(TObject *obj, const Option_t *opt=0)
Set model object.
void RenderBoxAutoNorm(const Float_t p[8][3]) const
Render box, calculate normals on the fly from first three points.
virtual void DirectDraw(TGLRnrCtx &rnrCtx) const
Actual rendering code.
virtual void Render(TGLRnrCtx &rnrCtx)
Interface for direct rendering from classes that include TEveBoxSet as a member.
void RenderBoxes(TGLRnrCtx &rnrCtx) const
GL rendering for all box-types.
TEveBoxSet * fM
Definition: TEveBoxSetGL.h:24
Int_t PrimitiveType() const
Return GL primitive used to render the boxes, based on the render-mode specified in the model object.
void MakeOriginBox(Float_t p[8][3], Float_t dx, Float_t dy, Float_t dz) const
Fill array p to represent a box (0,0,0) - (dx,dy,dz).
virtual ~TEveBoxSetGL()
Destructor.
virtual void DLCacheDrop()
Called when display lists have been destroyed externally and the internal display-list data needs to ...
void RenderBoxStdNorm(const Float_t p[8][3]) const
Render a box specified by points in array p with standard axis-aligned normals.
Collection of 3D primitives (fixed-size boxes, boxes of different sizes, or arbitrary sexto-epipeds,...
Definition: TEveBoxSet.h:22
Float_t fDefWidth
Definition: TEveBoxSet.h:56
Int_t fBoxSkip
Definition: TEveBoxSet.h:60
Float_t fDefDepth
Definition: TEveBoxSet.h:58
Float_t fDefHeight
Definition: TEveBoxSet.h:57
EBoxType_e fBoxType
Definition: TEveBoxSet.h:54
Bool_t fDrawConeCap
Definition: TEveBoxSet.h:62
@ kBT_EllipticCone
Definition: TEveBoxSet.h:35
@ kBT_AABoxFixedDim
Definition: TEveBoxSet.h:33
Int_t Size() const
OpenGL renderer class for TEveDigitSet.
const std::set< Int_t > * fHighlightSet
void DrawFrameIfNeeded(TGLRnrCtx &rnrCtx) const
Make a decision if the frame should be drawn.
Bool_t SetupColor(const TEveDigitSet::DigitBase_t &q) const
Set color for rendering of the specified digit.
Bool_t fDisableLighting
Definition: TEveDigitSet.h:75
TEveRGBAPalette * fPalette
Definition: TEveDigitSet.h:71
TEveRGBAPalette * AssertPalette()
Make sure the TEveRGBAPalette pointer is not null.
Bool_t fSingleColor
Definition: TEveDigitSet.h:62
ERenderMode_e fRenderMode
Definition: TEveDigitSet.h:72
TEveChunkManager fPlex
Definition: TEveDigitSet.h:65
Bool_t fValueIsColor
Definition: TEveDigitSet.h:61
Bool_t fAntiFlick
Definition: TEveDigitSet.h:63
Exception class thrown by TEve classes and macros.
Definition: TEveUtil.h:102
virtual void DLCachePurge()
Purge all entries for all LODs for this drawable from the display list cache, returning the reserved ...
virtual void DLCacheDrop()
Drop all entries for all LODs for this drawable from the display list cache, WITHOUT returning the re...
void PurgeDLRange(UInt_t base, Int_t size) const
External object is a fake.
Bool_t fDLCache
display-list validity bit-field
Bool_t fMultiColor
Definition: TGLObject.h:28
virtual Bool_t ShouldDLCache(const TGLRnrCtx &rnrCtx) const
Decide if display-list should be used for this pass rendering, as determined by rnrCtx.
Definition: TGLObject.cxx:41
Wrapper class for GLU quadric shape drawing object.
Definition: TGLQuadric.h:28
GLUquadric * Get()
Get the internal raw GLU quadric object. Created on first call.
Definition: TGLQuadric.cxx:44
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition: TGLRnrCtx.h:41
@ kLODHigh
Definition: TGLRnrCtx.h:67
Bool_t SecSelection() const
Definition: TGLRnrCtx.h:224
Bool_t IsDrawPassOutlineLine() const
Definition: TGLRnrCtx.h:207
Bool_t Highlight() const
Definition: TGLRnrCtx.h:218
Short_t CombiLOD() const
Definition: TGLRnrCtx.h:175
static Int_t CheckError(const char *loc)
Check current GL error state, outputting details via ROOT Error method if one.
Definition: TGLUtil.cxx:1641
Mother of all ROOT objects.
Definition: TObject.h:37
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
Double_t Sqrt(Double_t x)
static constexpr double s
TMath.
Definition: TMathBase.h:35
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:703
Double_t ATan(Double_t)
Definition: TMath.h:665
Double_t ATan2(Double_t y, Double_t x)
Definition: TMath.h:669
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:725
T * Cross(const T v1[3], const T v2[3], T out[3])
Calculate the Cross Product of two vectors: out = [v1 x v2].
Definition: TMath.h:1165
constexpr Double_t RadToDeg()
Conversion from radian to degree:
Definition: TMath.h:74
Bool_t next()
Go to next atom.
const std::set< Int_t > * fSelection
auto * a
Definition: textangle.C:12