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
44
46
47////////////////////////////////////////////////////////////////////////////////
48
51
52 fTimeStamp (1),
53 fMinorStamp (1),
54 fLOD (TGLRnrCtx::kLODHigh),
55 fStyle (TGLRnrCtx::kStyleUndef),
56 fWFLineW (0),
57 fOLLineW (0),
58 fClip (nullptr),
59 fSelectable (kTRUE),
60 fBoundingBox (),
61 fBoundingBoxValid (kFALSE),
62 fDoFrustumCheck (kTRUE),
63 fDoClipCheck (kTRUE),
64 fAutoDestruct (kTRUE)
65{
66 // Default constructor.
67
69 fName = Form("unnamed-%d", fSceneID);
70}
71
72////////////////////////////////////////////////////////////////////////////////
73/// Destructor.
74
76{
77 for (ViewerList_i i=fViewers.begin(); i!=fViewers.end(); ++i)
78 {
79 (*i)->SceneDestructing(this);
80 }
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// Add viewer to the list.
85
87{
88 ViewerList_i i = std::find(fViewers.begin(), fViewers.end(), viewer);
89 if (i == fViewers.end())
90 fViewers.push_back(viewer);
91 else
92 Warning("TGLSceneBase::AddViewer", "viewer already in the list.");
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Remove viewer from the list.
97/// If auto-destruct is on and the last viewer is removed the scene
98/// destructs itself.
99
101{
102 ViewerList_i i = std::find(fViewers.begin(), fViewers.end(), viewer);
103 if (i != fViewers.end())
104 fViewers.erase(i);
105 else
106 Warning("TGLSceneBase::RemoveViewer", "viewer not found in the list.");
107
108 if (fViewers.empty() && fAutoDestruct)
109 {
110 if (gDebug > 0)
111 Info("TGLSceneBase::RemoveViewer", "scene '%s' not used - autodestructing.", GetName());
112 delete this;
113 }
114}
115////////////////////////////////////////////////////////////////////////////////
116/// Tag all viewers as changed.
117
119{
120 for (ViewerList_i i=fViewers.begin(); i!=fViewers.end(); ++i)
121 {
122 (*i)->Changed();
123 }
124}
125
126/**************************************************************************/
127
128////////////////////////////////////////////////////////////////////////////////
129/// Name printed on locking info messages.
130
131const char* TGLSceneBase::LockIdStr() const
132{
133 return Form("TGLSceneBase %s", fName.Data());
134}
135
136/**************************************************************************/
137// SceneInfo management
138/**************************************************************************/
139
140////////////////////////////////////////////////////////////////////////////////
141/// Create a scene-info instance appropriate for this scene class.
142/// Here we instantiate the scene-info base-class TGLSceneInfo.
143
145{
146 return new TGLSceneInfo(view, this);
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// Fill scene-info with very basic information that is practically
151/// view independent. This is called when scene content is changed
152/// or when camera-interest changes.
153
155{
156 TGLSceneInfo* sinfo = ctx.GetSceneInfo();
157
158 sinfo->SetLastClip(nullptr);
159 sinfo->SetLastCamera(nullptr);
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Fill scene-info with information needed for rendering, take into
164/// account the render-context (viewer state, camera, clipping).
165/// Usually called from TGLViewer before rendering a scene if some
166/// moderately significant part of render-context has changed.
167///
168/// Here we update the basic state (clear last-LOD, mark the time,
169/// set global <-> scene transformation matrices) and potentially
170/// study and refine the clipping planes based on scene bounding box.
171
173{
174 if (gDebug > 3)
175 {
176 Info("TGLSceneBase::UpdateSceneInfo",
177 "'%s' timestamp=%u",
179 }
180
181 TGLSceneInfo* sinfo = ctx.GetSceneInfo();
182
183 // ------------------------------------------------------------
184 // Reset
185 // ------------------------------------------------------------
186
190
191 sinfo->InFrustum (kTRUE);
192 sinfo->InClip (kTRUE);
194
195 // ------------------------------------------------------------
196 // Setup
197 // ------------------------------------------------------------
198
199 // !!!
200 // setup scene transformation matrices
201 // so far the matrices in scene-base and scene-info are not enabled
202 // sinfo->fSceneToGlobal = scene-info-trans * scene-base-trans;
203 // sinfo->fGlobalToScene = inv of above;
204 // transform to clip and to eye coordinates also interesting
205 //
206 // All these are now done in TGLViewerBase::PreRender() via
207 // TGLSceneInfo::SetupTransformsAndBBox().
208
209 sinfo->SetLastClip(nullptr);
210 sinfo->FrustumPlanes().clear();
211 sinfo->ClipPlanes().clear();
212
213 if (fDoFrustumCheck)
214 {
215 for (Int_t i=0; i<TGLCamera::kPlanesPerFrustum; ++i)
216 {
218 // !!! transform plane
219 switch (BoundingBox().Overlap(p))
220 {
221 case Rgl::kInside: // Whole scene passes ... no need to store it.
222 break;
223 case Rgl::kPartial:
224 sinfo->FrustumPlanes().push_back(p);
225 break;
226 case Rgl::kOutside:
227 sinfo->InFrustum(kFALSE);
228 break;
229 }
230 }
231 }
232
233 if (fDoClipCheck && ctx.HasClip())
234 {
235 if (ctx.Clip()->GetMode() == TGLClip::kOutside)
237 else
239
240 std::vector<TGLPlane> planeSet;
241 ctx.Clip()->PlaneSet(planeSet);
242
243 // Strip any planes outside the scene bounding box - no effect
244 std::vector<TGLPlane>::iterator it = planeSet.begin();
245 while (it != planeSet.end())
246 {
247 // !!! transform plane
248 switch (BoundingBox().Overlap(*it))
249 {
250 case Rgl::kInside: // Whole scene passes ... no need to store it.
251 break;
252 case Rgl::kPartial:
253 sinfo->ClipPlanes().push_back(*it);
254 break;
255 case Rgl::kOutside: // Depends on mode
256 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
257 {
258 // Scene is outside of whole clip object - nothing visible.
259 sinfo->InClip(kFALSE);
260 }
261 else
262 {
263 // Scene is completely inside of whole clip object -
264 // draw all scene without clipping.
266 }
267 // In either case further checks not needed.
268 sinfo->ClipPlanes().clear();
269 return;
270 }
271 ++it;
272 }
273 sinfo->SetLastClip(ctx.Clip());
274 sinfo->SetClipStamp(ctx.Clip()->TimeStamp());
275 }
276
277 sinfo->SetLastCamera(ctx.GetCamera());
278 sinfo->SetCameraStamp(ctx.GetCamera()->TimeStamp());
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Setup LOD-dependant values in scene-info.
283///
284/// Nothing to be done here but to store the last LOD.
285
287{
288 if (gDebug > 3)
289 {
290 Info("TGLSceneBase::LodifySceneInfo",
291 "'%s' timestamp=%u lod=%d",
292 GetName(), fTimeStamp, ctx.CombiLOD());
293 }
294
295 TGLSceneInfo & sInfo = * ctx.GetSceneInfo();
296 sInfo.SetLastLOD(ctx.CombiLOD());
297}
298
299
300/**************************************************************************/
301// Rendering
302/**************************************************************************/
303
304////////////////////////////////////////////////////////////////////////////////
305/// Perform basic pre-render initialization:
306/// - calculate LOD, Style, Clipping,
307/// - build draw lists.
308///
309/// This is called in the beginning of the GL-viewer draw cycle.
310
312{
313 if ( ! IsDrawOrSelectLock()) {
314 Error("TGLSceneBase::FullRender", "expected Draw or Select Lock");
315 }
316
317 TGLSceneInfo& sInfo = * rnrCtx.GetSceneInfo();
318
319 // Bounding-box check done elsewhere (in viewer::pre-render)
320
321 if (fTimeStamp > sInfo.SceneStamp())
322 {
323 RebuildSceneInfo(rnrCtx);
324 }
325
326
327 Bool_t needUpdate = sInfo.HasUpdateTimeouted();
328
329 if (rnrCtx.GetCamera() != sInfo.LastCamera())
330 {
331 sInfo.ResetCameraStamp();
332 needUpdate = kTRUE;
333 }
334 else if (rnrCtx.GetCamera()->TimeStamp() > sInfo.CameraStamp())
335 {
336 needUpdate = kTRUE;
337 }
338
339 TGLClip* clip = nullptr;
340 if (sInfo.Clip() != nullptr) clip = sInfo.Clip();
341 else if (fClip != nullptr) clip = fClip;
342 else clip = rnrCtx.ViewerClip();
343 if (clip != sInfo.LastClip())
344 {
345 sInfo.ResetClipStamp();
346 needUpdate = kTRUE;
347 }
348 else if (clip && clip->TimeStamp() > sInfo.ClipStamp())
349 {
350 needUpdate = kTRUE;
351 }
352 rnrCtx.SetClip(clip);
353
354 if (needUpdate)
355 {
356 UpdateSceneInfo(rnrCtx);
357 }
358
359
360 // Setup LOD ... optionally lodify.
361 Short_t lod;
362 if (sInfo.LOD() != TGLRnrCtx::kLODUndef) lod = sInfo.LOD();
363 else if (fLOD != TGLRnrCtx::kLODUndef) lod = fLOD;
364 else lod = rnrCtx.ViewerLOD();
365 rnrCtx.SetSceneLOD(lod);
366 rnrCtx.SetCombiLOD(TMath::Min(rnrCtx.ViewerLOD(), rnrCtx.SceneLOD()));
367 if (needUpdate || rnrCtx.CombiLOD() != sInfo.LastLOD())
368 {
369 LodifySceneInfo(rnrCtx);
370 }
371
372 // Setup style.
374 if (sInfo.Style() != TGLRnrCtx::kStyleUndef) style = sInfo.Style();
376 else style = rnrCtx.ViewerStyle();
377 rnrCtx.SetSceneStyle(style);
378 sInfo.SetLastStyle(style);
379
380 // Wireframe line width.
381 Float_t wf_linew;
382 if (sInfo.WFLineW() != 0) wf_linew = sInfo.WFLineW();
383 else if (fWFLineW != 0) wf_linew = fWFLineW;
384 else wf_linew = rnrCtx.ViewerWFLineW();
385 rnrCtx.SetSceneWFLineW(wf_linew);
386 sInfo.SetLastWFLineW(wf_linew);
387 // Outline line width.
388 Float_t ol_linew;
389 if (sInfo.OLLineW() != 0) ol_linew = sInfo.OLLineW();
390 else if (fOLLineW != 0) ol_linew = fOLLineW;
391 else ol_linew = rnrCtx.ViewerOLLineW();
392 rnrCtx.SetSceneOLLineW(ol_linew);
393 sInfo.SetLastOLLineW(ol_linew);
394}
395
396////////////////////////////////////////////////////////////////////////////////
397/// Perform pre-render initialization - fill rnrCtx with
398/// values stored during PreDraw().
399///
400/// This is called each time before RenderXyzz().
401
403{
404 TGLSceneInfo& sInfo = * rnrCtx.GetSceneInfo();
405
406 rnrCtx.SetClip (sInfo.LastClip());
407 rnrCtx.SetCombiLOD (sInfo.LastLOD());
408 rnrCtx.SetSceneStyle (sInfo.LastStyle());
409 rnrCtx.SetSceneWFLineW (sInfo.LastWFLineW());
410 rnrCtx.SetSceneOLLineW (sInfo.LastOLLineW());
411
412 // !!!
413 // eventually handle matrix stack.
414 // glPushMatrix();
415 // glMultMatrix(something-from-scene-info);
416 // Should also fix camera matrices
417}
418
419////////////////////////////////////////////////////////////////////////////////
420/// This function does rendering of all stages, the shapes are
421/// rendered in the following order: opaque, transparent,
422/// selected-opaque, selected-transparent.
423///
424/// GL-depth buffer is cleared after transparent shapes have been
425/// rendered.
426///
427/// This is never called from ROOT GL directly. Use it if you know
428/// you are rendering a single scene.
429
431{
432 RenderOpaque(rnrCtx);
433 RenderTransp(rnrCtx);
434 RenderSelOpaque(rnrCtx);
435 RenderSelTransp(rnrCtx);
436}
437
438////////////////////////////////////////////////////////////////////////////////
439/// Render opaque elements.
440
442{
443}
444
445////////////////////////////////////////////////////////////////////////////////
446/// Render transparent elements.
447
449{
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Render selected opaque elements.
454
456{
457}
458
459////////////////////////////////////////////////////////////////////////////////
460/// Render selected transparent elements for highlight.
461
463{
464}
465
466////////////////////////////////////////////////////////////////////////////////
467/// Render selected opaque elements for highlight.
468
470{
471}
472
473////////////////////////////////////////////////////////////////////////////////
474/// Render selected transparent elements.
475
477{
478}
479
480////////////////////////////////////////////////////////////////////////////////
481/// Perform post-render clean-up.
482
484{
485 // !!!
486 // Cleanup matrix stack
487 // glPopMatrix();
488 // Should also fix camera matrices
489}
490
491////////////////////////////////////////////////////////////////////////////////
492/// Finalize drawing.
493///
494/// This is called at the end of the GL-viewer draw cycle.
495
497{
498}
499
500/**************************************************************************/
501// Selection
502/**************************************************************************/
503
504////////////////////////////////////////////////////////////////////////////////
505/// Process selection record rec.
506/// 'curIdx' is the item position where the scene should start
507/// its processing.
508/// Return TRUE if an object has been identified or FALSE otherwise.
509/// The scene-info member of the record is already set by the caller.
510///
511/// See implementation in sub-class TGLScene, here we just return FALSE.
512
514 Int_t /*curIdx*/)
515{
516 return kFALSE;
517}
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t style
Int_t gDebug
Definition TROOT.cxx:595
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
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
void SetSceneOLLineW(Float_t w)
Definition TGLRnrCtx.h:194
Float_t ViewerWFLineW() const
Definition TGLRnrCtx.h:187
void SetSceneLOD(Short_t LOD)
Definition TGLRnrCtx.h:174
Short_t ViewerStyle() const
Definition TGLRnrCtx.h:182
Short_t SceneLOD() const
Definition TGLRnrCtx.h:173
Bool_t HasClip() const
Definition TGLRnrCtx.h:202
void SetClip(TGLClip *p)
Definition TGLRnrCtx.h:201
void SetSceneWFLineW(Float_t w)
Definition TGLRnrCtx.h:190
TGLClip * ViewerClip() const
Definition TGLRnrCtx.h:196
Short_t ViewerLOD() const
Definition TGLRnrCtx.h:171
void SetSceneStyle(Short_t sty)
Definition TGLRnrCtx.h:185
Float_t ViewerOLLineW() const
Definition TGLRnrCtx.h:191
void SetCombiLOD(Short_t LOD)
Definition TGLRnrCtx.h:176
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
Scene base-class – provides basic interface expected by the TGLViewer or its sub-classes:
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.
UInt_t SceneStamp() const
Short_t Style() const
void SetLastClip(TGLClip *p)
Short_t LastStyle() const
void SetLastWFLineW(Float_t w)
void InClip(Bool_t c)
void ResetClipStamp()
Float_t WFLineW() const
void SetCameraStamp(UInt_t ts)
TGLClip * LastClip() const
TGLClip * Clip() const
Char_t ClipMode() const
void SetLastLOD(Short_t ld)
Short_t LastLOD() const
UInt_t CameraStamp() const
void ResetCameraStamp()
void SetLastCamera(TGLCamera *p)
void InFrustum(Bool_t f)
Float_t OLLineW() const
void SetSceneStamp(UInt_t ts)
TGLCamera * LastCamera() const
Float_t LastWFLineW() const
Bool_t HasUpdateTimeouted() const
Short_t LOD() const
std::vector< TGLPlane > & ClipPlanes()
void SetLastStyle(Short_t st)
Float_t LastOLLineW() const
void SetClipStamp(UInt_t ts)
std::vector< TGLPlane > & FrustumPlanes()
UInt_t ClipStamp() const
void SetLastOLLineW(Float_t w)
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:376
@ 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:198