Logo ROOT   6.14/05
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
22 A 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 {
41  DLCachePurge();
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 {
50  return (fM->fRenderMode != TEveDigitSet::kRM_Line) ? GL_QUADS : GL_LINE_LOOP;
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 
74 inline 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 
102 namespace
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 
124 void TEveBoxSetGL::RenderBoxAutoNorm(const Float_t p[8][3]) const
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 {
172  {
173  if (fBoxDL == 0)
174  fBoxDL = glGenLists(1);
175 
176  glNewList(fBoxDL, GL_COMPILE);
177 
179  {
180  glBegin(PrimitiveType());
181  Float_t p[8][3];
183  MakeOriginBox(p, 1.0f, 1.0f, 1.0f);
184  else
186  RenderBoxStdNorm(p);
187  glEnd();
188  }
189  else
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 
204  glEndList();
205  }
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// Determines if display-list will be used for rendering.
210 /// Virtual from TGLLogicalShape.
211 
213 {
214  MakeDisplayList();
215 
216  return TEveDigitSetGL::ShouldDLCache(rnrCtx);
217 }
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Called when display lists have been destroyed externally and the
221 /// internal display-list data needs to be cleare.
222 /// Virtual from TGLLogicalShape.
223 
225 {
226  fBoxDL = 0;
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Called when display-lists need to be returned to the system.
232 /// Virtual from TGLLogicalShape.
233 
235 {
236  if (fBoxDL != 0)
237  {
238  PurgeDLRange(fBoxDL, 1);
239  fBoxDL = 0;
240  }
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Set model object.
246 /// Virtual from TGLObject.
247 
249 {
250  fM = SetModelDynCast<TEveBoxSet>(obj);
251  return kTRUE;
252 }
253 
254 namespace
255 {
256  inline void AntiFlick(Float_t x, Float_t y, Float_t z)
257  {
258  // Render anti-flickering point.
259  glBegin(GL_POINTS);
260  glVertex3f(x, y, z);
261  glEnd();
262  }
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// GL rendering for all box-types.
267 
269 {
270  static const TEveException eH("TEveBoxSetGL::RenderBoxes ");
271 
272  if (rnrCtx.SecSelection()) glPushName(0);
273 
274  Int_t boxSkip = 0;
275  if (fM->fBoxSkip > 0 && rnrCtx.CombiLOD() < TGLRnrCtx::kLODHigh &&
276  !rnrCtx.SecSelection())
277  {
278  boxSkip = TMath::Nint(TMath::Power(fM->fBoxSkip, 2.0 - 0.02*rnrCtx.CombiLOD()));
279  }
280 
282  if (rnrCtx.Highlight() && fHighlightSet)
284 
285  switch (fM->fBoxType)
286  {
287 
289  {
290  GLenum primitiveType = PrimitiveType();
291  while (bi.next())
292  {
294  if (SetupColor(b))
295  {
296  if (rnrCtx.SecSelection()) glLoadName(bi.index());
297  glBegin(primitiveType);
299  glEnd();
300  if (fM->fAntiFlick)
301  AntiFlick(0.5f*(b.fVertices[0][0] + b.fVertices[6][0]),
302  0.5f*(b.fVertices[0][1] + b.fVertices[6][1]),
303  0.5f*(b.fVertices[0][2] + b.fVertices[6][2]));
304  }
305  if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
306  }
307  break;
308  } // end case free-box
309 
311  {
312  glEnable(GL_NORMALIZE);
313  while (bi.next())
314  {
316  if (SetupColor(b))
317  {
318  if (rnrCtx.SecSelection()) glLoadName(bi.index());
319  glPushMatrix();
320  glTranslatef(b.fA, b.fB, b.fC);
321  glScalef (b.fW, b.fH, b.fD);
322  glCallList(fBoxDL);
323  if (fM->fAntiFlick)
324  AntiFlick(0.5f, 0.5f, 0.5f);
325  glPopMatrix();
326  }
327  if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
328  }
329  break;
330  }
331 
333  {
334  while (bi.next())
335  {
337  if (SetupColor(b))
338  {
339  if (rnrCtx.SecSelection()) glLoadName(bi.index());
340  glTranslatef(b.fA, b.fB, b.fC);
341  glCallList(fBoxDL);
342  if (fM->fAntiFlick)
343  AntiFlick(0.5f*fM->fDefWidth, 0.5f*fM->fDefHeight, 0.5f*fM->fDefDepth);
344  glTranslatef(-b.fA, -b.fB, -b.fC);
345  }
346  if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
347  }
348  break;
349  }
350 
352  {
353  using namespace TMath;
354 
355  glEnable(GL_NORMALIZE);
356  Float_t theta=0, phi=0, h=0;
357  while (bi.next())
358  {
360  if (SetupColor(b))
361  {
362  if (rnrCtx.SecSelection()) glLoadName(bi.index());
363  h = b.fDir.Mag();
364  phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
365  theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
366  glPushMatrix();
367  glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
368  glRotatef(phi, 0, 0, 1);
369  glRotatef(90 - theta, 0, 1, 0);
370  glScalef (b.fR, b.fR, h);
371  glCallList(fBoxDL);
372  if (fM->fAntiFlick)
373  AntiFlick(0.0f, 0.0f, 0.5f);
374  glPopMatrix();
375  }
376  if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
377  }
378  break;
379  }
380 
382  {
383  using namespace TMath;
384 
385  glEnable(GL_NORMALIZE);
386  Float_t theta=0, phi=0, h=0;
387  while (bi.next())
388  {
390  if (SetupColor(b))
391  {
392  if (rnrCtx.SecSelection()) glLoadName(bi.index());
393  h = b.fDir.Mag();
394  phi = ATan2(b.fDir.fY, b.fDir.fX)*RadToDeg();
395  theta = ATan (b.fDir.fZ / Sqrt(b.fDir.fX*b.fDir.fX + b.fDir.fY*b.fDir.fY))*RadToDeg();
396  glPushMatrix();
397  glTranslatef(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
398  glRotatef(phi, 0, 0, 1);
399  glRotatef(90 - theta, 0, 1, 0);
400  glRotatef(b.fAngle, 0, 0, 1);
401  glScalef (b.fR, b.fR2, h);
402  glCallList(fBoxDL);
403  if (fM->fAntiFlick)
404  AntiFlick(0.0f, 0.0f, 0.5f);
405  glPopMatrix();
406  }
407  if (boxSkip) { Int_t s = boxSkip; while (s--) bi.next(); }
408  }
409  break;
410  }
411 
412  default:
413  {
414  throw(eH + "unsupported box-type.");
415  }
416 
417  } // end switch box-type
418 
419  if (rnrCtx.SecSelection()) glPopName();
420 }
421 
422 ////////////////////////////////////////////////////////////////////////////////
423 /// Actual rendering code.
424 /// Virtual from TGLLogicalShape.
425 
427 {
428  TEveBoxSet& mB = * fM;
429  // printf("TEveBoxSetGL::DirectDraw N boxes %d\n", mB.fPlex.Size());
430 
431  if (mB.fPlex.Size() > 0)
432  {
433  if (! mB.fSingleColor && ! mB.fValueIsColor && mB.fPalette == 0)
434  {
435  mB.AssertPalette();
436  }
437 
438  glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
439 
440  if ( ! rnrCtx.IsDrawPassOutlineLine())
441  {
443  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
444  else if (mB.fRenderMode == TEveDigitSet::kRM_Line)
445  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
446  }
447 
448  if (mB.fBoxType == TEveBoxSet::kBT_Cone ||
450  {
451  glDisable(GL_CULL_FACE);
452  }
453 
454  if (mB.fDisableLighting) glDisable(GL_LIGHTING);
455 
456  RenderBoxes(rnrCtx);
457 
458  glPopAttrib();
459  }
460 
461  DrawFrameIfNeeded(rnrCtx);
462 }
463 
464 ////////////////////////////////////////////////////////////////////////////////
465 /// Interface for direct rendering from classes that include TEveBoxSet
466 /// as a member.
467 
469 {
470  MakeDisplayList();
471  DirectDraw(rnrCtx);
472  glDeleteLists(fBoxDL, 1);
473  fBoxDL = 0;
474 }
void MakeDisplayList() const
Create a display-list for rendering a single box, based on the current box-type.
virtual void DLCacheDrop()
Drop all entries for all LODs for this drawable from the display list cache, WITHOUT returning the re...
TEveChunkManager fPlex
Definition: TEveDigitSet.h:65
Bool_t Highlight() const
Definition: TGLRnrCtx.h:218
A GL rendering class for TEveBoxSet.
Definition: TEveBoxSetGL.h:18
const std::set< Int_t > * fSelection
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition: TGLRnrCtx.h:40
Bool_t SecSelection() const
Definition: TGLRnrCtx.h:224
Bool_t fSingleColor
Definition: TEveDigitSet.h:62
Int_t PrimitiveType() const
Return GL primitive used to render the boxes, based on the render-mode specified in the model object...
float Float_t
Definition: RtypesCore.h:53
TEveBoxSetGL()
Default constructor.
const char Option_t
Definition: RtypesCore.h:62
const std::set< Int_t > * fHighlightSet
Collection of 3D primitives (fixed-size boxes, boxes of different sizes, or arbitrary sexto-epipeds...
Definition: TEveBoxSet.h:21
GLUquadric * Get()
Get the internal raw GLU quadric object. Created on first call.
Definition: TGLQuadric.cxx:44
virtual void DLCacheDrop()
Called when display lists have been destroyed externally and the internal display-list data needs to ...
TEveRGBAPalette * AssertPalette()
Make sure the TEveRGBAPalette pointer is not null.
#define f(i)
Definition: RSha256.hxx:104
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Wrapper class for GLU quadric shape drawing object.
Definition: TGLQuadric.h:27
virtual Bool_t ShouldDLCache(const TGLRnrCtx &rnrCtx) const
Determines if display-list will be used for rendering.
void RenderBoxAutoNorm(const Float_t p[8][3]) const
Render box, calculate normals on the fly from first three points.
virtual Bool_t SetModel(TObject *obj, const Option_t *opt=0)
Set model object.
Bool_t IsDrawPassOutlineLine() const
Definition: TGLRnrCtx.h:207
Bool_t fAntiFlick
Definition: TEveDigitSet.h:63
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:734
virtual void DirectDraw(TGLRnrCtx &rnrCtx) const
Actual rendering code.
Double_t x[n]
Definition: legend1.C:17
Int_t fBoxSkip
Definition: TEveBoxSet.h:57
UInt_t fBoxDL
Definition: TEveBoxSetGL.h:26
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:678
Float_t fDefWidth
Definition: TEveBoxSet.h:53
TEveBoxSet * fM
Definition: TEveBoxSetGL.h:24
OpenGL renderer class for TEveDigitSet.
Int_t Size() const
virtual ~TEveBoxSetGL()
Destructor.
virtual void DLCachePurge()
Purge all entries for all LODs for this drawable from the display list cache, returning the reserved ...
Short_t CombiLOD() const
Definition: TGLRnrCtx.h:175
void RenderBoxes(TGLRnrCtx &rnrCtx) const
GL rendering for all box-types.
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).
Double_t Sqrt(Double_t x)
void RenderBoxStdNorm(const Float_t p[8][3]) const
Render a box specified by points in array p with standard axis-aligned normals.
auto * a
Definition: textangle.C:12
Bool_t fDisableLighting
Definition: TEveDigitSet.h:75
Bool_t fValueIsColor
Definition: TEveDigitSet.h:61
TEveRGBAPalette * fPalette
Definition: TEveDigitSet.h:71
ERenderMode_e fRenderMode
Definition: TEveDigitSet.h:72
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:1295
#define h(i)
Definition: RSha256.hxx:106
const Bool_t kFALSE
Definition: RtypesCore.h:88
Float_t fDefHeight
Definition: TEveBoxSet.h:54
#define d(i)
Definition: RSha256.hxx:102
EBoxType_e fBoxType
Definition: TEveBoxSet.h:51
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
#define ClassImp(name)
Definition: Rtypes.h:359
Double_t y[n]
Definition: legend1.C:17
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
TEveVector fDir
Definition: TEveBoxSet.h:46
Bool_t fMultiColor
Definition: TGLObject.h:28
Mother of all ROOT objects.
Definition: TObject.h:37
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition: TMath.h:74
Bool_t next()
Go to next atom.
virtual void DLCachePurge()
Called when display-lists need to be returned to the system.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
TT Mag() const
Definition: TEveVector.h:95
void DrawFrameIfNeeded(TGLRnrCtx &rnrCtx) const
Make a decision if the frame should be drawn.
Exception class thrown by TEve classes and macros.
Definition: TEveUtil.h:102
void PurgeDLRange(UInt_t base, Int_t size) const
External object is a fake.
Bool_t fDLCache
display-list validity bit-field
TEveVector fPos
Definition: TEveBoxSet.h:46
Float_t fDefDepth
Definition: TEveBoxSet.h:55
Bool_t fDrawConeCap
Definition: TEveBoxSet.h:59
TMath.
Definition: TMathBase.h:34
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:712
Bool_t SetupColor(const TEveDigitSet::DigitBase_t &q) const
Set color for rendering of the specified digit.
const Int_t n
Definition: legend1.C:16
Float_t fVertices[8][3]
Definition: TEveBoxSet.h:38
virtual void Render(TGLRnrCtx &rnrCtx)
Interface for direct rendering from classes that include TEveBoxSet as a member.
Double_t ATan(Double_t)
Definition: TMath.h:674