Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
30TEveBoxSetGL::TEveBoxSetGL() : TEveDigitSetGL(), fM(nullptr), fBoxDL(0)
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 == nullptr)
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 a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
winID h TVirtualViewer3D TVirtualGLPainter p
A GL rendering class for TEveBoxSet.
TEveBoxSetGL()
Default constructor.
Bool_t SetModel(TObject *obj, const Option_t *opt=nullptr) override
Set model object.
void MakeDisplayList() const
Create a display-list for rendering a single box, based on the current box-type.
void DLCacheDrop() override
Called when display lists have been destroyed externally and the internal display-list data needs to ...
void RenderBoxAutoNorm(const Float_t p[8][3]) const
Render box, calculate normals on the fly from first three points.
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.
void DLCachePurge() override
Called when display-lists need to be returned to the system.
TEveBoxSet * fM
~TEveBoxSetGL() override
Destructor.
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).
Bool_t ShouldDLCache(const TGLRnrCtx &rnrCtx) const override
Determines if display-list will be used for rendering.
void DirectDraw(TGLRnrCtx &rnrCtx) const override
Actual rendering code.
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
TEveRGBAPalette * fPalette
TEveRGBAPalette * AssertPalette()
Make sure the TEveRGBAPalette pointer is not null.
Bool_t fSingleColor
ERenderMode_e fRenderMode
TEveChunkManager fPlex
Bool_t fValueIsColor
Bool_t fAntiFlick
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 Bool_t ShouldDLCache(const TGLRnrCtx &rnrCtx) const
Returns kTRUE if draws should be display list cached kFALSE otherwise.
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
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.
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition TGLRnrCtx.h:41
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:1646
Mother of all ROOT objects.
Definition TObject.h:41
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
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:693
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
T * Cross(const T v1[3], const T v2[3], T out[3])
Calculates the Cross Product of two vectors: out = [v1 x v2].
Definition TMath.h:1197
Bool_t next()
Go to next atom.
const std::set< Int_t > * fSelection