Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLSceneBase.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Matevz Tadel, Feb 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, 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 "TGLSceneBase.h"
13#include "TGLSceneInfo.h"
14#include "TGLViewerBase.h"
15#include "TGLRnrCtx.h"
16#include "TGLCamera.h"
17#include "TGLClip.h"
18#include "TGLIncludes.h"
19
20#include <TMath.h>
21
22#include <string>
23#include <algorithm>
24
25/** \class TGLSceneBase
26\ingroup opengl
27Scene base-class -- provides basic interface expected by the
28TGLViewer or its sub-classes:
29 - unique scene id
30 - scene locking
31 - overall bounding box
32 - list of viewers displaying the scene (for update propagation)
33 - virtual interface for draw/select/render (?)
34
35The standard ROOT OpenGL scene is implemented in direct sub-class TGLScene.
36
37Note that while each scene can be shared among several viewers, ALL
38of them are obliged to share the same display-list space (this can
39be achieved on GL-context creation time; Matevz believes that by
40default all GL contexts must use shared display-lists etc).
41*/
42
43
45
46////////////////////////////////////////////////////////////////////////////////
47
50
51 fTimeStamp (1),
52 fMinorStamp (1),
53 fLOD (TGLRnrCtx::kLODHigh),
54 fStyle (TGLRnrCtx::kStyleUndef),
55 fWFLineW (0),
56 fOLLineW (0),
57 fClip (nullptr),
58 fSelectable (kTRUE),
59 fBoundingBox (),
60 fBoundingBoxValid (kFALSE),
61 fDoFrustumCheck (kTRUE),
62 fDoClipCheck (kTRUE),
63 fAutoDestruct (kTRUE)
64{
65 // Default constructor.
66
68 fName = Form("unnamed-%d", fSceneID);
69}
70
71////////////////////////////////////////////////////////////////////////////////
72/// Destructor.
73
75{
76 for (ViewerList_i i=fViewers.begin(); i!=fViewers.end(); ++i)
77 {
78 (*i)->SceneDestructing(this);
79 }
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// Add viewer to the list.
84
86{
87 ViewerList_i i = std::find(fViewers.begin(), fViewers.end(), viewer);
88 if (i == fViewers.end())
89 fViewers.push_back(viewer);
90 else
91 Warning("TGLSceneBase::AddViewer", "viewer already in the list.");
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Remove viewer from the list.
96/// If auto-destruct is on and the last viewer is removed the scene
97/// destructs itself.
98
100{
101 ViewerList_i i = std::find(fViewers.begin(), fViewers.end(), viewer);
102 if (i != fViewers.end())
103 fViewers.erase(i);
104 else
105 Warning("TGLSceneBase::RemoveViewer", "viewer not found in the list.");
106
107 if (fViewers.empty() && fAutoDestruct)
108 {
109 if (gDebug > 0)
110 Info("TGLSceneBase::RemoveViewer", "scene '%s' not used - autodestructing.", GetName());
111 delete this;
112 }
113}
114////////////////////////////////////////////////////////////////////////////////
115/// Tag all viewers as changed.
116
118{
119 for (ViewerList_i i=fViewers.begin(); i!=fViewers.end(); ++i)
120 {
121 (*i)->Changed();
122 }
123}
124
125/**************************************************************************/
126
127////////////////////////////////////////////////////////////////////////////////
128/// Name printed on locking info messages.
129
130const char* TGLSceneBase::LockIdStr() const
131{
132 return Form("TGLSceneBase %s", fName.Data());
133}
134
135/**************************************************************************/
136// SceneInfo management
137/**************************************************************************/
138
139////////////////////////////////////////////////////////////////////////////////
140/// Create a scene-info instance appropriate for this scene class.
141/// Here we instantiate the scene-info base-class TGLSceneInfo.
142
144{
145 return new TGLSceneInfo(view, this);
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Fill scene-info with very basic information that is practically
150/// view independent. This is called when scene content is changed
151/// or when camera-interest changes.
152
154{
156
157 sinfo->SetLastClip(nullptr);
158 sinfo->SetLastCamera(nullptr);
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Fill scene-info with information needed for rendering, take into
163/// account the render-context (viewer state, camera, clipping).
164/// Usually called from TGLViewer before rendering a scene if some
165/// moderately significant part of render-context has changed.
166///
167/// Here we update the basic state (clear last-LOD, mark the time,
168/// set global <-> scene transformation matrices) and potentially
169/// study and refine the clipping planes based on scene bounding box.
170
172{
173 if (gDebug > 3)
174 {
175 Info("TGLSceneBase::UpdateSceneInfo",
176 "'%s' timestamp=%u",
178 }
179
181
182 // ------------------------------------------------------------
183 // Reset
184 // ------------------------------------------------------------
185
186 sinfo->SetLastLOD (TGLRnrCtx::kLODUndef);
187 sinfo->SetLastStyle (TGLRnrCtx::kStyleUndef);
188 sinfo->SetSceneStamp(fTimeStamp);
189
190 sinfo->InFrustum (kTRUE);
191 sinfo->InClip (kTRUE);
192 sinfo->ClipMode (TGLSceneInfo::kClipNone);
193
194 // ------------------------------------------------------------
195 // Setup
196 // ------------------------------------------------------------
197
198 // !!!
199 // setup scene transformation matrices
200 // so far the matrices in scene-base and scene-info are not enabled
201 // sinfo->fSceneToGlobal = scene-info-trans * scene-base-trans;
202 // sinfo->fGlobalToScene = inv of above;
203 // transform to clip and to eye coordinates also interesting
204 //
205 // All these are now done in TGLViewerBase::PreRender() via
206 // TGLSceneInfo::SetupTransformsAndBBox().
207
208 sinfo->SetLastClip(nullptr);
209 sinfo->FrustumPlanes().clear();
210 sinfo->ClipPlanes().clear();
211
212 if (fDoFrustumCheck)
213 {
214 for (Int_t i=0; i<TGLCamera::kPlanesPerFrustum; ++i)
215 {
217 // !!! transform plane
218 switch (BoundingBox().Overlap(p))
219 {
220 case Rgl::kInside: // Whole scene passes ... no need to store it.
221 break;
222 case Rgl::kPartial:
223 sinfo->FrustumPlanes().push_back(p);
224 break;
225 case Rgl::kOutside:
226 sinfo->InFrustum(kFALSE);
227 break;
228 }
229 }
230 }
231
232 if (fDoClipCheck && ctx.HasClip())
233 {
234 if (ctx.Clip()->GetMode() == TGLClip::kOutside)
236 else
238
239 std::vector<TGLPlane> planeSet;
240 ctx.Clip()->PlaneSet(planeSet);
241
242 // Strip any planes outside the scene bounding box - no effect
243 std::vector<TGLPlane>::iterator it = planeSet.begin();
244 while (it != planeSet.end())
245 {
246 // !!! transform plane
247 switch (BoundingBox().Overlap(*it))
248 {
249 case Rgl::kInside: // Whole scene passes ... no need to store it.
250 break;
251 case Rgl::kPartial:
252 sinfo->ClipPlanes().push_back(*it);
253 break;
254 case Rgl::kOutside: // Depends on mode
255 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
256 {
257 // Scene is outside of whole clip object - nothing visible.
258 sinfo->InClip(kFALSE);
259 }
260 else
261 {
262 // Scene is completely inside of whole clip object -
263 // draw all scene without clipping.
265 }
266 // In either case further checks not needed.
267 sinfo->ClipPlanes().clear();
268 return;
269 }
270 ++it;
271 }
272 sinfo->SetLastClip(ctx.Clip());
273 sinfo->SetClipStamp(ctx.Clip()->TimeStamp());
274 }
275
276 sinfo->SetLastCamera(ctx.GetCamera());
277 sinfo->SetCameraStamp(ctx.GetCamera()->TimeStamp());
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// Setup LOD-dependant values in scene-info.
282///
283/// Nothing to be done here but to store the last LOD.
284
286{
287 if (gDebug > 3)
288 {
289 Info("TGLSceneBase::LodifySceneInfo",
290 "'%s' timestamp=%u lod=%d",
291 GetName(), fTimeStamp, ctx.CombiLOD());
292 }
293
294 TGLSceneInfo & sInfo = * ctx.GetSceneInfo();
295 sInfo.SetLastLOD(ctx.CombiLOD());
296}
297
298
299/**************************************************************************/
300// Rendering
301/**************************************************************************/
302
303////////////////////////////////////////////////////////////////////////////////
304/// Perform basic pre-render initialization:
305/// - calculate LOD, Style, Clipping,
306/// - build draw lists.
307///
308/// This is called in the beginning of the GL-viewer draw cycle.
309
311{
312 if ( ! IsDrawOrSelectLock()) {
313 Error("TGLSceneBase::FullRender", "expected Draw or Select Lock");
314 }
315
316 TGLSceneInfo& sInfo = * rnrCtx.GetSceneInfo();
317
318 // Bounding-box check done elsewhere (in viewer::pre-render)
319
320 if (fTimeStamp > sInfo.SceneStamp())
321 {
323 }
324
325
326 Bool_t needUpdate = sInfo.HasUpdateTimeouted();
327
328 if (rnrCtx.GetCamera() != sInfo.LastCamera())
329 {
330 sInfo.ResetCameraStamp();
332 }
333 else if (rnrCtx.GetCamera()->TimeStamp() > sInfo.CameraStamp())
334 {
336 }
337
338 TGLClip* clip = nullptr;
339 if (sInfo.Clip() != nullptr) clip = sInfo.Clip();
340 else if (fClip != nullptr) clip = fClip;
341 else clip = rnrCtx.ViewerClip();
342 if (clip != sInfo.LastClip())
343 {
344 sInfo.ResetClipStamp();
346 }
347 else if (clip && clip->TimeStamp() > sInfo.ClipStamp())
348 {
350 }
351 rnrCtx.SetClip(clip);
352
353 if (needUpdate)
354 {
356 }
357
358
359 // Setup LOD ... optionally lodify.
360 Short_t lod;
361 if (sInfo.LOD() != TGLRnrCtx::kLODUndef) lod = sInfo.LOD();
362 else if (fLOD != TGLRnrCtx::kLODUndef) lod = fLOD;
363 else lod = rnrCtx.ViewerLOD();
364 rnrCtx.SetSceneLOD(lod);
365 rnrCtx.SetCombiLOD(TMath::Min(rnrCtx.ViewerLOD(), rnrCtx.SceneLOD()));
366 if (needUpdate || rnrCtx.CombiLOD() != sInfo.LastLOD())
367 {
369 }
370
371 // Setup style.
373 if (sInfo.Style() != TGLRnrCtx::kStyleUndef) style = sInfo.Style();
375 else style = rnrCtx.ViewerStyle();
376 rnrCtx.SetSceneStyle(style);
377 sInfo.SetLastStyle(style);
378
379 // Wireframe line width.
381 if (sInfo.WFLineW() != 0) wf_linew = sInfo.WFLineW();
382 else if (fWFLineW != 0) wf_linew = fWFLineW;
383 else wf_linew = rnrCtx.ViewerWFLineW();
384 rnrCtx.SetSceneWFLineW(wf_linew);
385 sInfo.SetLastWFLineW(wf_linew);
386 // Outline line width.
388 if (sInfo.OLLineW() != 0) ol_linew = sInfo.OLLineW();
389 else if (fOLLineW != 0) ol_linew = fOLLineW;
390 else ol_linew = rnrCtx.ViewerOLLineW();
391 rnrCtx.SetSceneOLLineW(ol_linew);
392 sInfo.SetLastOLLineW(ol_linew);
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Perform pre-render initialization - fill rnrCtx with
397/// values stored during PreDraw().
398///
399/// This is called each time before RenderXyzz().
400
402{
403 TGLSceneInfo& sInfo = * rnrCtx.GetSceneInfo();
404
405 rnrCtx.SetClip (sInfo.LastClip());
406 rnrCtx.SetCombiLOD (sInfo.LastLOD());
407 rnrCtx.SetSceneStyle (sInfo.LastStyle());
408 rnrCtx.SetSceneWFLineW (sInfo.LastWFLineW());
409 rnrCtx.SetSceneOLLineW (sInfo.LastOLLineW());
410
411 // !!!
412 // eventually handle matrix stack.
413 // glPushMatrix();
414 // glMultMatrix(something-from-scene-info);
415 // Should also fix camera matrices
416}
417
418////////////////////////////////////////////////////////////////////////////////
419/// This function does rendering of all stages, the shapes are
420/// rendered in the following order: opaque, transparent,
421/// selected-opaque, selected-transparent.
422///
423/// GL-depth buffer is cleared after transparent shapes have been
424/// rendered.
425///
426/// This is never called from ROOT GL directly. Use it if you know
427/// you are rendering a single scene.
428
436
437////////////////////////////////////////////////////////////////////////////////
438/// Render opaque elements.
439
441{
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Render transparent elements.
446
448{
449}
450
451////////////////////////////////////////////////////////////////////////////////
452/// Render selected opaque elements.
453
455{
456}
457
458////////////////////////////////////////////////////////////////////////////////
459/// Render selected transparent elements for highlight.
460
462{
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// Render selected opaque elements for highlight.
467
471
472////////////////////////////////////////////////////////////////////////////////
473/// Render selected transparent elements.
474
478
479////////////////////////////////////////////////////////////////////////////////
480/// Perform post-render clean-up.
481
483{
484 // !!!
485 // Cleanup matrix stack
486 // glPopMatrix();
487 // Should also fix camera matrices
488}
489
490////////////////////////////////////////////////////////////////////////////////
491/// Finalize drawing.
492///
493/// This is called at the end of the GL-viewer draw cycle.
494
496{
497}
498
499/**************************************************************************/
500// Selection
501/**************************************************************************/
502
503////////////////////////////////////////////////////////////////////////////////
504/// Process selection record rec.
505/// 'curIdx' is the item position where the scene should start
506/// its processing.
507/// Return TRUE if an object has been identified or FALSE otherwise.
508/// The scene-info member of the record is already set by the caller.
509///
510/// See implementation in sub-class TGLScene, here we just return FALSE.
511
513 Int_t /*curIdx*/)
514{
515 return kFALSE;
516}
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t style
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
const_iterator begin() const
const_iterator end() const
UInt_t TimeStamp() const
Definition TGLCamera.h:125
@ kPlanesPerFrustum
Definition TGLCamera.h:54
const TGLPlane & FrustumPlane(EFrustumPlane plane) const
Definition TGLCamera.h:219
Abstract clipping shape - derives from TGLPhysicalShape Adds clip mode (inside/outside) and pure virt...
Definition TGLClip.h:32
@ kOutside
Definition TGLClip.h:36
UInt_t TimeStamp() const
Definition TGLClip.h:63
virtual void PlaneSet(TGLPlaneSet_t &set) const =0
EMode GetMode() const
Definition TGLClip.h:60
Simple locking interface used by viewer and scene.
Definition TGLLockable.h:18
Bool_t IsDrawOrSelectLock() const
Definition TGLLockable.h:63
3D plane class - of format Ax + By + Cz + D = 0
Definition TGLUtil.h:525
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition TGLRnrCtx.h:41
Bool_t HasClip() const
Definition TGLRnrCtx.h:202
TGLCamera * GetCamera()
Definition TGLRnrCtx.h:156
TGLClip * Clip() const
Definition TGLRnrCtx.h:200
TGLSceneInfo * GetSceneInfo()
Definition TGLRnrCtx.h:158
@ kStyleUndef
Definition TGLRnrCtx.h:45
Short_t CombiLOD() const
Definition TGLRnrCtx.h:175
virtual const char * GetName() const
Bool_t fAutoDestruct
virtual void PostDraw(TGLRnrCtx &rnrCtx)
Finalize drawing.
const TGLBoundingBox & BoundingBox() const
virtual void RenderSelOpaque(TGLRnrCtx &rnrCtx)
Render selected opaque elements.
TGLClip * fClip
TString fName
virtual void PostRender(TGLRnrCtx &rnrCtx)
Perform post-render clean-up.
static UInt_t fgSceneIDSrc
virtual TGLSceneInfo * CreateSceneInfo(TGLViewerBase *view)
Create a scene-info instance appropriate for this scene class.
UInt_t fTimeStamp
ViewerList_t fViewers
void RemoveViewer(TGLViewerBase *viewer)
Remove viewer from the list.
virtual void LodifySceneInfo(TGLRnrCtx &ctx)
Setup LOD-dependant values in scene-info.
Short_t fStyle
virtual void RenderSelTransp(TGLRnrCtx &rnrCtx)
Render selected transparent elements for highlight.
virtual void PreRender(TGLRnrCtx &rnrCtx)
Perform pre-render initialization - fill rnrCtx with values stored during PreDraw().
virtual Bool_t ResolveSelectRecord(TGLSelectRecord &rec, Int_t curIdx)
Process selection record rec.
UInt_t fSceneID
virtual void RenderTransp(TGLRnrCtx &rnrCtx)
Render transparent elements.
const char * LockIdStr() const override
Name printed on locking info messages.
virtual void RenderSelTranspForHighlight(TGLRnrCtx &rnrCtx)
Render selected transparent elements.
Bool_t fDoClipCheck
std::list< TGLViewerBase * >::iterator ViewerList_i
virtual void PreDraw(TGLRnrCtx &rnrCtx)
Perform basic pre-render initialization:
virtual void RebuildSceneInfo(TGLRnrCtx &ctx)
Fill scene-info with very basic information that is practically view independent.
void AddViewer(TGLViewerBase *viewer)
Add viewer to the list.
Bool_t fDoFrustumCheck
virtual void RenderOpaque(TGLRnrCtx &rnrCtx)
Render opaque elements.
virtual void RenderSelOpaqueForHighlight(TGLRnrCtx &rnrCtx)
Render selected opaque elements for highlight.
Float_t fWFLineW
virtual void UpdateSceneInfo(TGLRnrCtx &ctx)
Fill scene-info with information needed for rendering, take into account the render-context (viewer s...
void TagViewersChanged()
Tag all viewers as changed.
Float_t fOLLineW
~TGLSceneBase() override
Destructor.
virtual void Render(TGLRnrCtx &rnrCtx)
This function does rendering of all stages, the shapes are rendered in the following order: opaque,...
Base class for extended scene context.
Standard selection record including information about containing scene and details ob out selected ob...
Base class for GL viewers.
const char * Data() const
Definition TString.h:384
@ kInside
Definition TGLUtil.h:36
@ kOutside
Definition TGLUtil.h:38
@ kPartial
Definition TGLUtil.h:37
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199