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
25
26////////////////////////////////////////////////////////////////////////////////
27/// Default constructor.
28
29TEveBoxSetGL::TEveBoxSetGL() : TEveDigitSetGL(), fM(nullptr), fBoxDL(0)
30{
31 fDLCache = kFALSE; // Disable display list, used internally for boxes, cones.
33}
34
35////////////////////////////////////////////////////////////////////////////////
36/// Destructor.
37
42
43////////////////////////////////////////////////////////////////////////////////
44/// Return GL primitive used to render the boxes, based on the
45/// render-mode specified in the model object.
46
48{
49 return (fM->fRenderMode != TEveDigitSet::kRM_Line) ? GL_QUADS : GL_LINE_LOOP;
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Fill array p to represent a box (0,0,0) - (dx,dy,dz).
54
56{
57 // bottom
58 p[0][0] = 0; p[0][1] = dy; p[0][2] = 0;
59 p[1][0] = dx; p[1][1] = dy; p[1][2] = 0;
60 p[2][0] = dx; p[2][1] = 0; p[2][2] = 0;
61 p[3][0] = 0; p[3][1] = 0; p[3][2] = 0;
62 // top
63 p[4][0] = 0; p[4][1] = dy; p[4][2] = dz;
64 p[5][0] = dx; p[5][1] = dy; p[5][2] = dz;
65 p[6][0] = dx; p[6][1] = 0; p[6][2] = dz;
66 p[7][0] = 0; p[7][1] = 0; p[7][2] = dz;
67}
68
69////////////////////////////////////////////////////////////////////////////////
70/// Render a box specified by points in array p with standard
71/// axis-aligned normals.
72
73inline void TEveBoxSetGL::RenderBoxStdNorm(const Float_t p[8][3]) const
74{
75 // bottom: 0123
76 glNormal3f(0, 0, -1);
77 glVertex3fv(p[0]); glVertex3fv(p[1]);
78 glVertex3fv(p[2]); glVertex3fv(p[3]);
79 // top: 7654
80 glNormal3f(0, 0, 1);
81 glVertex3fv(p[7]); glVertex3fv(p[6]);
82 glVertex3fv(p[5]); glVertex3fv(p[4]);
83 // back: 0451
84 glNormal3f(0, 1, 0);
85 glVertex3fv(p[0]); glVertex3fv(p[4]);
86 glVertex3fv(p[5]); glVertex3fv(p[1]);
87 // front: 3267
88 glNormal3f(0, -1, 0);
89 glVertex3fv(p[3]); glVertex3fv(p[2]);
90 glVertex3fv(p[6]); glVertex3fv(p[7]);
91 // left: 0374
92 glNormal3f(-1, 0, 0);
93 glVertex3fv(p[0]); glVertex3fv(p[3]);
94 glVertex3fv(p[7]); glVertex3fv(p[4]);
95 // right: 1562
96 glNormal3f(1, 0, 0);
97 glVertex3fv(p[1]); glVertex3fv(p[5]);
98 glVertex3fv(p[6]); glVertex3fv(p[2]);
99}
100
101namespace
102{
103 void subtract_and_normalize(const Float_t a[3], const Float_t b[3],
104 Float_t o[3])
105 {
106 // Calculate a - b and normalize the result.
107 o[0] = a[0] - b[0];
108 o[1] = a[1] - b[1];
109 o[2] = a[2] - b[2];
110 Float_t d = sqrtf(o[0]*o[0] + o[1]*o[1] + o[2]*o[2]);
111 if (d != 0)
112 {
113 d = 1.0f / d;
114 o[0] *= d;
115 o[1] *= d;
116 o[2] *= d;
117 }
118 }
119}
120////////////////////////////////////////////////////////////////////////////////
121/// Render box, calculate normals on the fly from first three points.
122
124{
125 Float_t e[6][3], n[3];
126 subtract_and_normalize(p[1], p[0], e[0]);
127 subtract_and_normalize(p[3], p[0], e[1]);
128 subtract_and_normalize(p[4], p[0], e[2]);
129 subtract_and_normalize(p[5], p[6], e[3]);
130 subtract_and_normalize(p[7], p[6], e[4]);
131 subtract_and_normalize(p[2], p[6], e[5]);
132
133 // bottom: 0123
134 glNormal3fv(TMath::Cross(e[0], e[1], n));
135 glVertex3fv(p[0]); glVertex3fv(p[1]);
136 glVertex3fv(p[2]); glVertex3fv(p[3]);
137 // top: 7654
138 glNormal3fv(TMath::Cross(e[3], e[4], n));
139 glVertex3fv(p[7]); glVertex3fv(p[6]);
140 glVertex3fv(p[5]); glVertex3fv(p[4]);
141 // back: 0451
142 glNormal3fv(TMath::Cross(e[2], e[0], n));
143 glVertex3fv(p[0]); glVertex3fv(p[4]);
144 glVertex3fv(p[5]); glVertex3fv(p[1]);
145 // front: 3267
146 glNormal3fv(TMath::Cross(e[4], e[5], n));
147 glVertex3fv(p[3]); glVertex3fv(p[2]);
148 glVertex3fv(p[6]); glVertex3fv(p[7]);
149 // left: 0374
150 glNormal3fv(TMath::Cross(e[1], e[2], n));
151 glVertex3fv(p[0]); glVertex3fv(p[3]);
152 glVertex3fv(p[7]); glVertex3fv(p[4]);
153 // right: 1562
154 glNormal3fv(TMath::Cross(e[5], e[3], n));
155 glVertex3fv(p[1]); glVertex3fv(p[5]);
156 glVertex3fv(p[6]); glVertex3fv(p[2]);
157}
158
159////////////////////////////////////////////////////////////////////////////////
160/// Create a display-list for rendering a single box, based on the
161/// current box-type.
162/// Some box-types don't benefit from the display-list rendering and
163/// so display-list is not created.
164
166{
172 {
173 if (fBoxDL == 0)
174 fBoxDL = glGenLists(1);
175
177
179 {
181 Float_t p[8][3];
183 MakeOriginBox(p, 1.0f, 1.0f, 1.0f);
184 else
187 glEnd();
188 }
189 else if (fM->fBoxType < TEveBoxSet::kBT_Hex)
190 {
191 static TGLQuadric quad;
192 Int_t nt = 15; // number of corners
193 gluCylinder(quad.Get(), 0, 1, 1, nt, 1);
194
195 if (fM->fDrawConeCap)
196 {
197 glPushMatrix();
198 glTranslatef(0, 0, 1);
199 gluDisk(quad.Get(), 0, 1, nt, 1);
200 glPopMatrix();
201 }
202 }
203 else // Hexagons
204 {
205 static TGLQuadric quad;
206 Int_t nt = 6; // number of corners
207 gluCylinder(quad.Get(), 1, 1, 1, nt, 1);
208
210 gluDisk(quad.Get(), 0, 1, nt, 1);
212
213 glPushMatrix();
214 glTranslatef(0, 0, 1);
215 gluDisk(quad.Get(), 0, 1, nt, 1);
216 glPopMatrix();
217 }
218
219 glEndList();
220
221 TGLUtil::CheckError("TEveBoxSetGL::MakeDisplayList");
222 }
223}
224
225////////////////////////////////////////////////////////////////////////////////
226/// Determines if display-list will be used for rendering.
227/// Virtual from TGLLogicalShape.
228
233
234////////////////////////////////////////////////////////////////////////////////
235/// Called when display lists have been destroyed externally and the
236/// internal display-list data needs to be cleare.
237/// Virtual from TGLLogicalShape.
238
244
245////////////////////////////////////////////////////////////////////////////////
246/// Called when display-lists need to be returned to the system.
247/// Virtual from TGLLogicalShape.
248
250{
251 if (fBoxDL != 0)
252 {
254 fBoxDL = 0;
255 }
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// Set model object.
261/// Virtual from TGLObject.
262
264{
266 return kTRUE;
267}
268
269namespace
270{
271 inline void AntiFlick(Float_t x, Float_t y, Float_t z)
272 {
273 // Render anti-flickering point.
274 glBegin(GL_POINTS);
275 glVertex3f(x, y, z);
276 glEnd();
277 }
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// GL rendering for all box-types.
282
284{
285 static const TEveException eH("TEveBoxSetGL::RenderBoxes ");
286
287 if (rnrCtx.SecSelection()) glPushName(0);
288
289 Int_t boxSkip = 0;
290 if (fM->fBoxSkip > 0 && rnrCtx.CombiLOD() < TGLRnrCtx::kLODHigh &&
291 !rnrCtx.SecSelection())
292 {
293 boxSkip = TMath::Nint(TMath::Power(fM->fBoxSkip, 2.0 - 0.02*rnrCtx.CombiLOD()));
294 }
295
297 if (rnrCtx.Highlight() && fHighlightSet)
298 bi.fSelection = fHighlightSet;
299
300 switch (fM->fBoxType)
301 {
302
304 {
306 while (bi.next())
307 {
309 if (SetupColor(b))
310 {
311 if (rnrCtx.SecSelection()) glLoadName(bi.index());
313 RenderBoxAutoNorm(b.fVertices);
314 glEnd();
315 if (fM->fAntiFlick)
316 AntiFlick(0.5f*(b.fVertices[0][0] + b.fVertices[6][0]),
317 0.5f*(b.fVertices[0][1] + b.fVertices[6][1]),
318 0.5f*(b.fVertices[0][2] + b.fVertices[6][2]));
319 }
320 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
321 }
322 break;
323 } // end case free-box
324
326 {
328 while (bi.next())
329 {
331 if (SetupColor(b))
332 {
333 if (rnrCtx.SecSelection()) glLoadName(bi.index());
334 glPushMatrix();
335 glTranslatef(b.fA, b.fB, b.fC);
336 glScalef (b.fW, b.fH, b.fD);
338 if (fM->fAntiFlick)
339 AntiFlick(0.5f, 0.5f, 0.5f);
340 glPopMatrix();
341 }
342 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
343 }
344 break;
345 }
346
348 {
349 while (bi.next())
350 {
352 if (SetupColor(b))
353 {
354 if (rnrCtx.SecSelection()) glLoadName(bi.index());
355 glTranslatef(b.fA, b.fB, b.fC);
357 if (fM->fAntiFlick)
358 AntiFlick(0.5f*fM->fDefWidth, 0.5f*fM->fDefHeight, 0.5f*fM->fDefDepth);
359 glTranslatef(-b.fA, -b.fB, -b.fC);
360 }
361 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
362 }
363 break;
364 }
365
367 {
368 using namespace TMath;
369
371 Float_t theta=0, phi=0, h=0;
372 while (bi.next())
373 {
375 if (SetupColor(b))
376 {
377 if (rnrCtx.SecSelection()) glLoadName(bi.index());
378 h = b.fDir.Mag();
379 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
380 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
381 glPushMatrix();
382 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
383 glRotatef(phi, 0, 0, 1);
384 glRotatef(90 - theta, 0, 1, 0);
385 glScalef (b.fR, b.fR, h);
387 if (fM->fAntiFlick)
388 AntiFlick(0.0f, 0.0f, 0.5f);
389 glPopMatrix();
390 }
391 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
392 }
393 break;
394 }
395
397 {
398 using namespace TMath;
399
401 Float_t theta=0, phi=0, h=0;
402 while (bi.next())
403 {
405 if (SetupColor(b))
406 {
407 if (rnrCtx.SecSelection()) glLoadName(bi.index());
408 h = b.fDir.Mag();
409 phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
410 theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
411 glPushMatrix();
412 glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
413 glRotatef(phi, 0, 0, 1);
414 glRotatef(90 - theta, 0, 1, 0);
415 glRotatef(b.fAngle, 0, 0, 1);
416 glScalef (b.fR, b.fR2, h);
418 if (fM->fAntiFlick)
419 AntiFlick(0.0f, 0.0f, 0.5f);
420 glPopMatrix();
421 }
422 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
423 }
424 break;
425 }
426
428 {
429 using namespace TMath;
430
432 while (bi.next())
433 {
435 if (SetupColor(h))
436 {
437 if (rnrCtx.SecSelection()) glLoadName(bi.index());
438 glPushMatrix();
439 glTranslatef(h.fPos.fX, h.fPos.fY, h.fPos.fZ);
440 glRotatef(h.fAngle, 0, 0, 1);
441 glScalef (h.fR, h.fR, h.fDepth);
443 if (fM->fAntiFlick)
444 AntiFlick(0.0f, 0.0f, 0.5f);
445 glPopMatrix();
446 }
447 if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
448 }
449 break;
450 }
451
452 default:
453 {
454 throw eH + "unsupported box-type.";
455 }
456
457 } // end switch box-type
458
459 if (rnrCtx.SecSelection()) glPopName();
460}
461
462////////////////////////////////////////////////////////////////////////////////
463/// Actual rendering code.
464/// Virtual from TGLLogicalShape.
465
467{
468 TEveBoxSet& mB = * fM;
469 // printf("TEveBoxSetGL::DirectDraw N boxes %d\n", mB.fPlex.Size());
470
471 if (mB.fPlex.Size() > 0)
472 {
474
475 if (! mB.fSingleColor && ! mB.fValueIsColor && mB.fPalette == nullptr)
476 {
477 mB.AssertPalette();
478 }
479
481
482 if ( ! rnrCtx.IsDrawPassOutlineLine())
483 {
484 if (mB.fRenderMode == TEveDigitSet::kRM_Fill)
486 else if (mB.fRenderMode == TEveDigitSet::kRM_Line)
488 }
489
490 if (mB.fBoxType == TEveBoxSet::kBT_Cone ||
492 {
494 }
495
496 if (mB.fDisableLighting) glDisable(GL_LIGHTING);
497
499
500 glPopAttrib();
501 }
502
504}
505
506////////////////////////////////////////////////////////////////////////////////
507/// Interface for direct rendering from classes that include TEveBoxSet
508/// as a member.
509
#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
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
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
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.
ERenderMode_e fRenderMode
TEveChunkManager fPlex
Bool_t fAntiFlick
Exception class thrown by TEve classes and macros.
Definition TEveUtil.h:102
TT Mag() const
Definition TEveVector.h:99
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
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition TGLRnrCtx.h:41
static Int_t CheckError(const char *loc)
Check current GL error state, outputting details via ROOT Error method if one.
Definition TGLUtil.cxx:1637
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:704
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
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:1284