Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLScene.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Matevz Tadel, Feb 2007
3// Author: Richard Maunder 25/05/2005
4// Parts taken from original TGLRender by Timur Pocheptsov
5
6/*************************************************************************
7 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#include "TGLScene.h"
15#include "TGLRnrCtx.h"
16#include "TGLObject.h"
17#include "TGLSelectRecord.h"
18#include "TGLLogicalShape.h"
19#include "TGLPhysicalShape.h"
20#include "TGLCamera.h"
21#include "TGLContext.h"
22#include "TGLIncludes.h"
23
24#include <TColor.h>
25#include <TROOT.h>
26#include <TClass.h>
27
28#include <algorithm>
29
30//==============================================================================
31// TGLScene::TSceneInfo
32//==============================================================================
33
34//______________________________________________________________________
35//
36// Extend TGLSceneInfo for needs of TGLScene:
37//
38// 1. DrawElement vectors for opaque/transparent shapes which cache
39// physicals that pass the clip tests (frustum and additional
40// clip-object);
41//
42// 2. Statistics / debug information
43//
44
45////////////////////////////////////////////////////////////////////////////////
46/// Constructor.
47
49 TGLSceneInfo (view, scene),
50 fMinorStamp (0),
51 fOpaqueCnt (0),
52 fTranspCnt (0),
53 fAsPixelCnt (0)
54{
55}
56
57////////////////////////////////////////////////////////////////////////////////
58/// Destructor.
59
63
64////////////////////////////////////////////////////////////////////////////////
65/// Clear given vec and if it grew too large compared to the size of
66/// shape-of-interest also resize it.
67
70{
71 if (vec.capacity() > (size_t) maxSize) {
73 foo.reserve((size_t) maxSize);
74 vec.swap(foo);
75 } else {
76 vec.clear();
77 }
78}
79
80////////////////////////////////////////////////////////////////////////////////
81/// Clear given vec and if it grew too large compared to the size of
82/// shape-of-interest also resize it.
83
86{
87 if (vec.capacity() > (size_t) maxSize) {
89 foo.reserve((size_t) maxSize);
90 vec.swap(foo);
91 } else {
92 vec.clear();
93 }
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Clear DrawElementVector fVisibleElement and optionally resize it
98/// so that it doesn't take more space then required by all the
99/// elements in the scene's draw-list.
100
102{
103 Int_t maxSize = (Int_t) fShapesOfInterest.size();
104
105 ClearDrawElementVec(fVisibleElements, maxSize);
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// Clear DrawElementPtrVectors and optionally resize them so that
110/// they don't take more space then required by all the elements in
111/// the scene's draw-list.
112
114{
115 Int_t maxSize = (Int_t) fShapesOfInterest.size();
116
117 ClearDrawElementPtrVec(fOpaqueElements, maxSize);
118 ClearDrawElementPtrVec(fTranspElements, maxSize);
119 ClearDrawElementPtrVec(fSelOpaqueElements, maxSize);
120 ClearDrawElementPtrVec(fSelTranspElements, maxSize);
121
122 fMinorStamp = 0;
123}
124
125////////////////////////////////////////////////////////////////////////////////
126/// Quantize LODs for given render-context.
127
129{
130 for (DrawElementVec_i i = fVisibleElements.begin(); i != fVisibleElements.end(); ++i)
131 i->fPhysical->QuantizeShapeLOD(i->fPixelLOD, ctx.CombiLOD(), i->fFinalLOD);
132}
133
134////////////////////////////////////////////////////////////////////////////////
135/// Prepare for drawing - fill DrawElementPtrVectors from the
136/// contents of fVisibleElements if there was some change.
137
139{
141 {
142 fOpaqueElements.clear();
143 fTranspElements.clear();
144 fSelOpaqueElements.clear();
145 fSelTranspElements.clear();
146
147 for (DrawElementVec_i i = fVisibleElements.begin(); i != fVisibleElements.end(); ++i)
148 {
149 if (i->fPhysical->IsSelected())
150 {
151 if (i->fPhysical->IsTransparent())
152 fSelTranspElements.push_back(&*i);
153 else
154 fSelOpaqueElements.push_back(&*i);
155 } else {
156 if (i->fPhysical->IsTransparent())
157 fTranspElements.push_back(&*i);
158 else
159 fOpaqueElements.push_back(&*i);
160 }
161 }
162 fMinorStamp = fScene->GetMinorStamp();
163 }
164}
165
166////////////////////////////////////////////////////////////////////////////////
167/// Clean-up after drawing, nothing to be done here.
168
172
173////////////////////////////////////////////////////////////////////////////////
174/// Reset draw statistics.
175
177{
178 fOpaqueCnt = 0;
179 fTranspCnt = 0;
180 fAsPixelCnt = 0;
181 fByShapeCnt.clear();
182}
183
184////////////////////////////////////////////////////////////////////////////////
185/// Update draw stats, for newly drawn 'shape'
186
188 Short_t lod)
189{
190 // Update opaque/transparent draw count
191 if (shape.IsTransparent()) {
192 ++fTranspCnt;
193 } else {
194 ++fOpaqueCnt;
195 }
196
197 if (lod == TGLRnrCtx::kLODPixel) {
198 ++fAsPixelCnt;
199 }
200
201 // By type only done at higher debug level.
202 if (gDebug>3) {
203 // Update the stats
204 TClass* logIsA = shape.GetLogical()->IsA();
205 std::map<TClass*, UInt_t>::iterator it = fByShapeCnt.find(logIsA);
206 if (it == fByShapeCnt.end()) {
207 //do not need to check insert(.....).second, because it was stats.end() before
208 it = fByShapeCnt.insert(std::make_pair(logIsA, 0u)).first;
209 }
210
211 it->second++;
212 }
213}
214
215////////////////////////////////////////////////////////////////////////////////
216/// Output draw stats to Info stream.
217
219{
220 if (gDebug>2)
221 {
222 TString out;
223 // Draw/container counts
224 out += Form("Drew scene (%s / %i LOD) - %i (Op %i Trans %i) %i pixel\n",
225 TGLRnrCtx::StyleName(LastStyle()), LastLOD(),
226 fOpaqueCnt + fTranspCnt, fOpaqueCnt, fTranspCnt, fAsPixelCnt);
227 out += Form("\tInner phys nums: physicals=%d, of_interest=%lu, visible=%lu, op=%lu, trans=%lu",
228 ((TGLScene*)fScene)->GetMaxPhysicalID(),
229 (ULong_t)fShapesOfInterest.size(), (ULong_t)fVisibleElements.size(),
230 (ULong_t)fOpaqueElements.size(), (ULong_t)fTranspElements.size());
231
232 // By shape type counts
233 if (gDebug>3)
234 {
235 out += "\n\tStatistics by shape:\n";
236 std::map<TClass*, UInt_t>::const_iterator it = fByShapeCnt.begin();
237 while (it != fByShapeCnt.end()) {
238 out += Form("\t%-20s %u\n", it->first->GetName(), it->second);
239 ++it;
240 }
241 }
242 Info("TGLScene::DumpDrawStats()", "%s",out.Data());
243 }
244}
245
246
247/** \class TGLScene
248\ingroup opengl
249TGLScene provides management and rendering of ROOT's default 3D
250/object representation as logical and physical shapes.
251
252A GL scene is the container for all the viewable objects (shapes)
253loaded into the viewer. It consists of two main stl::maps containing
254the TGLLogicalShape and TGLPhysicalShape collections, and interface
255functions enabling viewers to manage objects in these. The physical
256shapes defined the placement of copies of the logical shapes - see
257TGLLogicalShape/TGLPhysicalShape for more information on relationship
258
259The scene can be drawn by owning viewer, passing camera, draw style
260& quality (LOD), clipping etc - see Draw(). The scene can also be
261drawn for selection in similar fashion - see Select(). The scene
262keeps track of a single selected physical - which can be modified by
263viewers.
264
265The scene maintains a lazy calculated bounding box for the total
266scene extents, axis aligned round TGLPhysicalShape shapes.
267
268Currently a scene is owned exclusively by one viewer - however it is
269intended that it could easily be shared by multiple viewers - for
270efficiency and synchronisation reasons. Hence viewer variant objects
271camera, clips etc being owned by viewer and passed at draw/select
272*/
273
274
275////////////////////////////////////////////////////////////////////////////////
276
287
288////////////////////////////////////////////////////////////////////////////////
289/// Destroy scene objects
290
301
302/**************************************************************************/
303// GLCtxIdentity
304/**************************************************************************/
305
306////////////////////////////////////////////////////////////////////////////////
307/// Release all GL resources for current context identity.
308/// Requires iteration over all logical shapes.
309
311{
312 if (fGLCtxIdentity == nullptr) return;
313
314 if (fGLCtxIdentity->IsValid())
315 {
316 // Purge logical's DLs
318 while (lit != fLogicalShapes.end()) {
319 lit->second->DLCachePurge();
320 ++lit;
321 }
322 }
323 else
324 {
325 // Drop logical's DLs
327 while (lit != fLogicalShapes.end()) {
328 lit->second->DLCacheDrop();
329 ++lit;
330 }
331 }
333 fGLCtxIdentity = nullptr;
334}
335
336/**************************************************************************/
337// SceneInfo management
338/**************************************************************************/
339
340
341////////////////////////////////////////////////////////////////////////////////
342/// Create a scene-info instance appropriate for this scene class.
343/// Here we instantiate the inner class TSceneInfo that includes
344/// camera/clipping specific draw-list containers.
345
347{
348 return new TSceneInfo(view, this);
349}
350
351////////////////////////////////////////////////////////////////////////////////
352/// Compare 'shape1' and 'shape2' bounding box volumes - return kTRUE if
353/// 'shape1' bigger than 'shape2'.
354
357{
358 return (shape1->BoundingBox().Volume() > shape2->BoundingBox().Volume());
359}
360
361////////////////////////////////////////////////////////////////////////////////
362/// Compare 'shape1' and 'shape2' bounding box volumes - return kTRUE if
363/// 'shape1' bigger than 'shape2'.
364
367{
368 return (shape1->BoundingBox().Diagonal() > shape2->BoundingBox().Diagonal());
369}
370
371////////////////////////////////////////////////////////////////////////////////
372/// Major change in scene, need to rebuild all-element draw-vector and
373/// sort it.
374///
375/// Sort the TGLPhysical draw list by shape bounding box diagonal, from
376/// large to small. This makes dropout of shapes with time limited
377/// Draw() calls must less noticeable. As this does not use projected
378/// size it only needs to be done after a scene content change - not
379/// every time scene drawn (potential camera/projection change).
380
382{
383 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
384 if (sinfo == nullptr || sinfo->GetScene() != this) {
385 Error("TGLScene::RebuildSceneInfo", "Scene mismatch.");
386 return;
387 }
388
390
391 if (sinfo->fShapesOfInterest.capacity() > fPhysicalShapes.size()) {
393 foo.reserve(fPhysicalShapes.size());
394 sinfo->fShapesOfInterest.swap(foo);
395 } else {
396 sinfo->fShapesOfInterest.clear();
397 }
398
400 while (pit != fPhysicalShapes.end())
401 {
402 TGLPhysicalShape * pshp = pit->second;
403 const TGLLogicalShape * lshp = pshp->GetLogical();
404 if (rnrCtx.GetCamera()->OfInterest(pshp->BoundingBox(),
405 lshp->IgnoreSizeForOfInterest()))
406 {
407 sinfo->fShapesOfInterest.push_back(pshp);
408 }
409 ++pit;
410 }
411
412 std::sort(sinfo->fShapesOfInterest.begin(), sinfo->fShapesOfInterest.end(),
414
415 sinfo->ClearAfterRebuild();
416}
417
418////////////////////////////////////////////////////////////////////////////////
419/// Fill scene-info with information needed for rendering, take into
420/// account the render-context (viewer state, camera, clipping).
421/// Here we have to iterate over all the physical shapes and select
422/// the visible ones. While at it, opaque and transparent shapes are
423/// divided into two groups.
424
426{
427 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
428 if (sinfo == nullptr || sinfo->GetScene() != this) {
429 Error("TGLScene::UpdateSceneInfo", "Scene mismatch.");
430 return;
431 }
432
433 // Clean-up/reset, update of transformation matrices and clipping
434 // planes done in base-class.
436
437 if (!sinfo->IsVisible())
438 return;
439
440 sinfo->fVisibleElements.clear();
441
442 // Check individual physicals, build DrawElementList.
443
444 Int_t checkCount = 0;
445 Bool_t timerp = rnrCtx.IsStopwatchRunning();
446 sinfo->ResetUpdateTimeouted();
447
448 for (ShapeVec_i phys=sinfo->fShapesOfInterest.begin();
449 phys!=sinfo->fShapesOfInterest.end();
450 ++phys, ++checkCount)
451 {
453
454 // TODO: Do small skipping first? Probably cheaper than frustum check
455 // Profile relative costs? The frustum check could be done implicitly
456 // from the LOD as we project all 8 vertices of the BB onto viewport
457
458 // Work out if we need to draw this shape - assume we do first
460
461 // Draw test against passed clipping planes.
462 // Do before camera clipping on assumption clip planes remove
463 // more objects.
464 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
465 {
466 // Draw not needed if outside any of the planes.
467 std::vector<TGLPlane>::iterator pi = sinfo->ClipPlanes().begin();
468 while (pi != sinfo->ClipPlanes().end())
469 {
470 if (drawShape->BoundingBox().Overlap(*pi) == Rgl::kOutside)
471 {
473 break;
474 }
475 ++pi;
476 }
477 }
478 else if (sinfo->ClipMode() == TGLSceneInfo::kClipInside)
479 {
480 // Draw not needed if inside all the planes.
481 std::vector<TGLPlane>::iterator pi = sinfo->ClipPlanes().begin();
482 size_t cnt = 0;
483 while (pi != sinfo->ClipPlanes().end())
484 {
485 Rgl::EOverlap ovlp = drawShape->BoundingBox().Overlap(*pi);
486 if (ovlp == Rgl::kOutside)
487 break;
488 else if (ovlp == Rgl::kInside)
489 ++cnt;
490 ++pi;
491 }
492 if (cnt == sinfo->ClipPlanes().size())
494 }
495
496 // Test against camera frustum planes (here mode is Outside
497 // implicitly).
498 if (drawNeeded)
499 {
500 std::vector<TGLPlane>::iterator pi = sinfo->FrustumPlanes().begin();
501 while (pi != sinfo->FrustumPlanes().end())
502 {
503 if (drawShape->BoundingBox().Overlap(*pi) == Rgl::kOutside)
504 {
506 break;
507 }
508 ++pi;
509 }
510 }
511
512 // Draw? Then calculate lod and store ...
513 if (drawNeeded)
514 {
516 drawShape->CalculateShapeLOD(rnrCtx, de.fPixelSize, de.fPixelLOD);
517 sinfo->fVisibleElements.push_back(de);
518 }
519
520 // Terminate the traversal if over scene rendering limit.
521 // Only test every 5000 objects as this is somewhat costly.
522 if (timerp && (checkCount % 5000) == 0 && rnrCtx.HasStopwatchTimedOut())
523 {
524 sinfo->UpdateTimeouted();
525 if (rnrCtx.ViewerLOD() == TGLRnrCtx::kLODHigh)
526 Warning("TGLScene::UpdateSceneInfo",
527 "Timeout reached, not all elements processed.");
528 break;
529 }
530 }
531
532 sinfo->ClearAfterUpdate();
533
534 // !!! MT Transparents should be sorted by their eye z-coordinate.
535 // Need combined matrices in scene-info to do this.
536 // Even more ... should z-sort contributions from ALL scenes!
537}
538
539////////////////////////////////////////////////////////////////////////////////
540/// Setup LOD-dependant values in scene-info.
541/// We have to perform LOD quantization for all draw-elements.
542
544{
545 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
546 if (sinfo == nullptr || sinfo->GetScene() != this) {
547 Error("TGLScene::LodifySceneInfo", "Scene mismatch.");
548 return;
549 }
550
552
553 sinfo->Lodify(rnrCtx);
554}
555
556
557/**************************************************************************/
558// Rendering
559/**************************************************************************/
560
561////////////////////////////////////////////////////////////////////////////////
562/// Initialize rendering.
563/// Pass to base-class where most work is done.
564/// Check if GL-ctx is shared with the previous one; if not
565/// wipe display-lists of all logicals.
566
568{
569 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
570 if (sinfo == nullptr || sinfo->GetScene() != this) {
571 TGLSceneInfo* si = rnrCtx.GetSceneInfo();
572 Error("TGLScene::PreDraw", "%s", Form("SceneInfo mismatch (0x%zx, '%s').",
573 (size_t)si, si ? si->IsA()->GetName() : "<>"));
574 return;
575 }
576
577 // Setup ctx, check if Update/Lodify needed.
579
580 TGLContextIdentity* cid = rnrCtx.GetGLCtxIdentity();
581 if (cid != fGLCtxIdentity)
582 {
586 }
587 else
588 {
591 {
592 // Clear logical's DLs
594 while (lit != fLogicalShapes.end()) {
595 lit->second->DLCacheClear();
596 ++lit;
597 }
598 }
599 }
602
603 sinfo->PreDraw();
604
605 // Reset-scene-info counters.
606 sinfo->ResetDrawStats();
607}
608
609////////////////////////////////////////////////////////////////////////////////
610/// Render opaque elements.
611
613{
614 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
615 if (!sinfo->fOpaqueElements.empty())
616 RenderAllPasses(rnrCtx, sinfo->fOpaqueElements, kTRUE);
617}
618
619////////////////////////////////////////////////////////////////////////////////
620/// Render transparent elements.
621
623{
624 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
625 if (!sinfo->fTranspElements.empty())
626 RenderAllPasses(rnrCtx, sinfo->fTranspElements, kTRUE);
627}
628
629////////////////////////////////////////////////////////////////////////////////
630/// Render selected opaque elements.
631
633{
634 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
635 if ( ! sinfo->fSelOpaqueElements.empty())
636 RenderAllPasses(rnrCtx, sinfo->fSelOpaqueElements, kFALSE);
637}
638
639////////////////////////////////////////////////////////////////////////////////
640/// Render selected transparent elements.
641
643{
644 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
645 if (!sinfo->fSelTranspElements.empty())
646 RenderAllPasses(rnrCtx, sinfo->fSelTranspElements, kFALSE);
647}
648
649////////////////////////////////////////////////////////////////////////////////
650/// Render selected opaque elements for highlight.
651
653{
654 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
655 if ( ! sinfo->fSelOpaqueElements.empty())
656 RenderHighlight(rnrCtx, sinfo->fSelOpaqueElements);
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Render selected transparent elements for highlight.
661
663{
664 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
665 if (!sinfo->fSelTranspElements.empty())
666 RenderHighlight(rnrCtx, sinfo->fSelTranspElements);
667}
668
669////////////////////////////////////////////////////////////////////////////////
670
700
701////////////////////////////////////////////////////////////////////////////////
702/// Called after the rendering is finished.
703/// In debug mode draw statistics is dumped.
704/// Parent's PostDraw is called for GL cleanup.
705
707{
708 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
709
710 if (gDebug)
711 sinfo->DumpDrawStats();
712
713 sinfo->PostDraw();
714
716}
717
718////////////////////////////////////////////////////////////////////////////////
719/// Do full rendering of scene.
720///
721/// First draw the opaques, then the transparents. For each we do
722/// the number of passes required by draw mode and clipping setup.
723
727{
728 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
729 assert(sinfo != nullptr);
730
731 Short_t sceneStyle = rnrCtx.SceneStyle();
732
733 // Setup GL for current draw style - fill, wireframe, outline
734 Int_t reqPasses = 1; // default
735
736 Short_t rnrPass[2];
738
739 switch (sceneStyle)
740 {
741 case TGLRnrCtx::kFill:
743 {
745 if (sinfo->ShouldClip())
746 {
747 // Clip object - two sided lighting, two side polygons, don't cull (BACK) faces
751 }
752 // No clip - default single side lighting,
753 // front polygons, cull (BACK) faces ok
754 if (sceneStyle == TGLRnrCtx::kOutline && ! (rnrCtx.Selection() || rnrCtx.Highlight()))
755 {
756 reqPasses = 2; // Outline needs two full draws
759 }
760 else
761 {
763 }
764 break;
765 }
767 {
772 break;
773 }
774 default:
775 {
776 assert(kFALSE);
777 }
778 }
779
780 for (Int_t i = 0; i < reqPasses; ++i)
781 {
782 // For outline two full draws (fill + wireframe) required.
783 // Do it this way to avoid costly GL state swaps on per drawable basis
784
785 Short_t pass = rnrPass[i];
786 rnrCtx.SetDrawPass(pass);
787
789 {
790 // First pass - filled polygons
792 glPolygonOffset(0.5f, 0.5f);
793 }
795 {
796 // Second pass - outline (wireframe)
797 TGLUtil::LineWidth(rnrCtx.SceneOLLineW());
800
801 // We are only showing back faces with clipping as a
802 // better solution than completely invisible faces.
803 // *Could* cull back faces and only outline on front like this:
804 // glEnable(GL_CULL_FACE);
805 // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
806 // However this means clipped back edges not shown - so do inside and out....
808 }
810 {
811 TGLUtil::LineWidth(rnrCtx.SceneWFLineW());
812 }
813
814 // If no clip object no plane sets to extract/pass
815 if ( ! sinfo->ShouldClip())
816 {
818 }
819 else
820 {
821 // Get the clip plane set from the clipping object
822 TGLPlaneSet_t & planeSet = sinfo->ClipPlanes();
823
824 if (gDebug > 3)
825 {
826 Info("TGLScene::RenderAllPasses()",
827 "%ld active clip planes", (Long_t)planeSet.size());
828 }
829 // Limit to smaller of plane set size or GL implementation plane support
834 if (planeSet.size() < maxPlanes) {
835 maxPlanes = planeSet.size();
836 }
837
838 if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
839 {
840 // Clip away scene outside of the clip object.
841 // Load all clip planes (up to max) at once.
842 for (UInt_t ii=0; ii<maxPlanes; ii++) {
845 }
846
847 // Draw scene once with full time slot, physicals have been
848 // clipped during UpdateSceneInfo, so no need to repeat that.
850 }
851 else
852 {
853 // Clip away scene inside of the clip object.
854 // This requires number-of-clip-planes passes and can not
855 // be entirely pre-computed (non-relevant planes are removed).
856 std::vector<TGLPlane> activePlanes;
858 {
859 activePlanes.push_back(planeSet[planeInd]);
860 TGLPlane& p = activePlanes.back();
861 p.Negate();
864
865 // Draw scene with active planes, allocating fraction of time
866 // for total planes.
868
869 p.Negate();
871 }
872 }
873 // Ensure all clip planes turned off again
874 for (planeInd=0; planeInd<maxPlanes; planeInd++) {
876 }
877 }
878 } // end for reqPasses
879
880 // Reset gl modes to defaults
885}
886
887////////////////////////////////////////////////////////////////////////////////
888/// Render DrawElements in elementVec with given timeout.
889/// If clipPlanes is non-zero, test each element against its
890/// clipping planes.
891
896{
897 TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
898 assert(sinfo != nullptr);
899
900 Int_t drawCount = 0;
901
902 for (DrawElementPtrVec_i i = elVec.begin(); i != elVec.end(); ++i)
903 {
904 const TGLPhysicalShape * drawShape = (*i)->fPhysical;
905
907
908 // If clipping planes are passed as argument, we test against them.
909 if (clipPlanes && IsOutside(drawShape->BoundingBox(), *clipPlanes))
911
912 // Draw?
913 if (drawNeeded)
914 {
915 rnrCtx.SetShapeLOD((*i)->fFinalLOD);
916 rnrCtx.SetShapePixSize((*i)->fPixelSize);
917 glPushName(drawShape->ID());
918 drawShape->Draw(rnrCtx);
919 glPopName();
920 ++drawCount;
921 sinfo->UpdateDrawStats(*drawShape, rnrCtx.ShapeLOD());
922 }
923
924 // Terminate the draw if over opaque fraction timeout.
925 // Only test every 2000 objects as this is somewhat costly.
926 if (check_timeout && (drawCount % 2000) == 0 &&
927 rnrCtx.HasStopwatchTimedOut())
928 {
929 if (rnrCtx.ViewerLOD() == TGLRnrCtx::kLODHigh)
930 Warning("TGLScene::RenderElements",
931 "Timeout reached, not all elements rendered.");
932 break;
933 }
934 }
935}
936
937
938/**************************************************************************/
939// Selection
940/**************************************************************************/
941
942////////////////////////////////////////////////////////////////////////////////
943/// Process selection record rec.
944/// 'curIdx' is the item position where the scene should start
945/// its processing.
946/// Return TRUE if an object has been identified or FALSE otherwise.
947/// The scene-info member of the record is already set by the caller.
948
950{
951 if (curIdx >= rec.GetN())
952 return kFALSE;
953
954 TGLPhysicalShape* pshp = FindPhysical(rec.GetItem(curIdx));
955 if (pshp)
956 {
957 rec.SetTransparent(pshp->IsTransparent());
958 rec.SetPhysShape(pshp);
959 rec.SetLogShape(const_cast<TGLLogicalShape*>(pshp->GetLogical()));
960 rec.SetObject(pshp->GetLogical()->GetExternal());
961 rec.SetSpecific(nullptr);
962 return kTRUE;
963 }
964 return kFALSE;
965}
966
967
968/**************************************************************************/
969// Bounding-box
970/**************************************************************************/
971
972////////////////////////////////////////////////////////////////////////////////
973/// Encapsulates all physical shapes bounding box with axes aligned box.
974/// Validity checked in the base-class.
975
977{
979 xMin = xMax = yMin = yMax = zMin = zMax = 0.0;
982 while (physicalShapeIt != fPhysicalShapes.end())
983 {
985 if (!physicalShape)
986 {
987 assert(kFALSE);
988 continue;
989 }
990 const TGLBoundingBox& box = physicalShape->BoundingBox();
991 if (physicalShapeIt == fPhysicalShapes.begin()) {
992 xMin = box.XMin(); xMax = box.XMax();
993 yMin = box.YMin(); yMax = box.YMax();
994 zMin = box.ZMin(); zMax = box.ZMax();
995 } else {
996 if (box.XMin() < xMin) { xMin = box.XMin(); }
997 if (box.XMax() > xMax) { xMax = box.XMax(); }
998 if (box.YMin() < yMin) { yMin = box.YMin(); }
999 if (box.YMax() > yMax) { yMax = box.YMax(); }
1000 if (box.ZMin() < zMin) { zMin = box.ZMin(); }
1001 if (box.ZMax() > zMax) { zMax = box.ZMax(); }
1002 }
1004 }
1007}
1008
1009/**************************************************************************/
1010// Logical shapes
1011/**************************************************************************/
1012
1013////////////////////////////////////////////////////////////////////////////////
1014/// Adopt dynamically created logical 'shape' - add to internal map
1015/// and take responsibility for deleting.
1016
1018{
1019 if (fLock != kModifyLock) {
1020 Error("TGLScene::AdoptLogical", "expected ModifyLock");
1021 return;
1022 }
1023
1024 shape.fScene = this;
1025 fLogicalShapes.insert(LogicalShapeMapValueType_t(shape.ID(), &shape));
1026}
1027
1028////////////////////////////////////////////////////////////////////////////////
1029/// Destroy logical shape defined by unique 'ID'.
1030/// Returns kTRUE if found/destroyed - kFALSE otherwise.
1031///
1032/// If mustFind is true, an error is reported if the logical is not
1033/// found.
1034
1036{
1037 if (fLock != kModifyLock) {
1038 Error("TGLScene::DestroyLogical", "expected ModifyLock");
1039 return kFALSE;
1040 }
1041
1043
1044 if (lit == fLogicalShapes.end()) {
1045 if (mustFind)
1046 Error("TGLScene::DestroyLogical", "logical not found in map.");
1047 return kFALSE;
1048 }
1049
1050 TGLLogicalShape * logical = lit->second;
1051 UInt_t phid;
1052 while ((phid = logical->UnrefFirstPhysical()) != 0)
1053 {
1055 if (pit != fPhysicalShapes.end())
1057 else
1058 Warning("TGLScene::DestroyLogical", "an attached physical not found in map.");
1059 }
1060 assert(logical->Ref() == 0);
1061 fLogicalShapes.erase(lit);
1062 delete logical;
1064 IncTimeStamp();
1065 return kTRUE;
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Destroy all logical shapes in scene.
1070/// Return number of destroyed logicals.
1071
1073{
1074 if (fLock != kModifyLock) {
1075 Error("TGLScene::DestroyLogicals", "expected ModifyLock");
1076 return 0;
1077 }
1078
1079 Int_t count = 0;
1082 while (logicalShapeIt != fLogicalShapes.end()) {
1083 logicalShape = logicalShapeIt->second;
1084 if (logicalShape) {
1085 if (logicalShape->Ref() == 0) {
1087 delete logicalShape;
1088 ++count;
1089 continue;
1090 } else {
1091 assert(kFALSE);
1092 }
1093 } else {
1094 assert(kFALSE);
1095 }
1097 }
1098
1099 return count;
1100}
1101
1102////////////////////////////////////////////////////////////////////////////////
1103/// Find and return logical shape identified by unique logid.
1104/// Returns 0 if not found.
1105
1107{
1109 if (lit != fLogicalShapes.end()) {
1110 return lit->second;
1111 } else {
1112 if (fInSmartRefresh)
1114 else
1115 return nullptr;
1116 }
1117}
1118
1119
1120/**************************************************************************/
1121// Physical shapes
1122/**************************************************************************/
1123
1124////////////////////////////////////////////////////////////////////////////////
1125/// Adopt dynamically created physical 'shape' - add to internal map and take
1126/// responsibility for deleting
1127
1129{
1130 if (fLock != kModifyLock) {
1131 Error("TGLScene::AdoptPhysical", "expected ModifyLock");
1132 return;
1133 }
1134 // TODO: Very inefficient check - disable
1135 assert(fPhysicalShapes.find(shape.ID()) == fPhysicalShapes.end());
1136
1137 fPhysicalShapes.insert(PhysicalShapeMapValueType_t(shape.ID(), &shape));
1138
1140 IncTimeStamp();
1141}
1142
1143////////////////////////////////////////////////////////////////////////////////
1144/// Virtual function to destroy a physical. Sub-classes might have
1145/// special checks to perform.
1146/// Caller should also invalidate the draw-list.
1147
1149{
1150 delete pit->second;
1151 fPhysicalShapes.erase(pit);
1152}
1153
1154////////////////////////////////////////////////////////////////////////////////
1155/// Destroy physical shape defined by unique 'ID'.
1156/// Returns kTRUE if found/destroyed - kFALSE otherwise.
1157
1159{
1160 if (fLock != kModifyLock) {
1161 Error("TGLScene::DestroyPhysical", "expected ModifyLock.");
1162 return kFALSE;
1163 }
1164
1166
1167 if (pit == fPhysicalShapes.end()) {
1168 Error("TGLScene::DestroyPhysical::UpdatePhysical", "physical not found.");
1169 return kFALSE;
1170 }
1171
1173
1175
1176 return kTRUE;
1177}
1178
1179////////////////////////////////////////////////////////////////////////////////
1180/// Destroy physical shapes.
1181
1183{
1184 if (fLock != kModifyLock) {
1185 Error("TGLScene::DestroyPhysicals", "expected ModifyLock");
1186 return 0;
1187 }
1188
1189 // Loop over logicals -- it is much more efficient that way.
1190
1191 UInt_t count = 0;
1192
1194 while (lit != fLogicalShapes.end())
1195 {
1196 TGLLogicalShape *lshp = lit->second;
1197 if (lshp && lshp->Ref() != 0)
1198 {
1199 count += lshp->Ref();
1200 lshp->DestroyPhysicals();
1201 }
1202 ++lit;
1203 }
1204
1205 assert (count == fPhysicalShapes.size());
1206 fPhysicalShapes.clear();
1207
1208 if (count > 0) {
1210 IncTimeStamp();
1211 }
1212
1213 return count;
1214}
1215
1216////////////////////////////////////////////////////////////////////////////////
1217/// Find and return physical shape identified by unique 'ID'.
1218/// Returns 0 if not found.
1219
1221{
1223 return (pit != fPhysicalShapes.end()) ? pit->second : 0;
1224}
1225
1226////////////////////////////////////////////////////////////////////////////////
1227/// Returns the maximum used physical id.
1228/// Returns 0 if empty.
1229
1231{
1232 if (fPhysicalShapes.empty()) return 0;
1233 return (--fPhysicalShapes.end())->first;
1234}
1235
1236
1237/**************************************************************************/
1238// Update methods
1239/**************************************************************************/
1240
1241////////////////////////////////////////////////////////////////////////////////
1242/// Put scene in update mode, return true if lock acquired.
1243
1245{
1247 return ok;
1248}
1249
1250////////////////////////////////////////////////////////////////////////////////
1251/// Exit scene update mode.
1252///
1253/// If sceneChanged is true (default), the scene timestamp is
1254/// increased and basic draw-lists etc will be rebuild on next draw
1255/// request. If you only changed colors or some other visual
1256/// parameters that do not affect object bounding-box or
1257/// transformation matrix, you can set it to false.
1258///
1259/// If updateViewers is true (default), the viewers using this scene
1260/// will be tagged as changed. If sceneChanged is true the
1261/// updateViewers should be true as well, unless you take care of
1262/// the viewers elsewhere or in some other way.
1263
1277
1278////////////////////////////////////////////////////////////////////////////////
1279/// Drop display-lists for the logical (assume TGLObject/direct rendering).
1280/// Re-calculate the bounding box (also for all physicals).
1281
1283{
1284 if (fLock != kModifyLock) {
1285 Error("TGLScene::UpdateLogical", "expected ModifyLock");
1286 return;
1287 }
1288
1290
1291 if (log == nullptr) {
1292 Error("TGLScene::UpdateLogical", "logical not found");
1293 return;
1294 }
1295
1296 log->DLCacheClear();
1297 log->UpdateBoundingBox();
1298}
1299
1300////////////////////////////////////////////////////////////////////////////////
1301/// Reposition/recolor physical shape.
1302
1304{
1305 if (fLock != kModifyLock) {
1306 Error("TGLScene::UpdatePhysical", "expected ModifyLock");
1307 return;
1308 }
1309
1311
1312 if (phys == nullptr) {
1313 Error("TGLScene::UpdatePhysical", "physical not found");
1314 return;
1315 }
1316
1317 if (trans) phys->SetTransform(trans);
1318 if (col) phys->SetDiffuseColor(col);
1319}
1320
1321////////////////////////////////////////////////////////////////////////////////
1322/// Reposition/recolor physical shape.
1323
1325{
1326 if (fLock != kModifyLock) {
1327 Error("TGLScene::UpdatePhysical", "expected ModifyLock");
1328 return;
1329 }
1330
1332
1333 if (phys == nullptr) {
1334 Error("TGLScene::UpdatePhysical", "physical not found");
1335 return;
1336 }
1337
1338 if (trans)
1339 phys->SetTransform(trans);
1340 if (cidx >= 0) {
1341 Float_t rgba[4];
1343 phys->SetDiffuseColor(rgba);
1344 }
1345}
1346
1347////////////////////////////////////////////////////////////////////////////////
1348/// Reposition/recolor physical for given logical (assume TGLObject and
1349/// a single physical).
1350
1352{
1353 if (fLock != kModifyLock) {
1354 Error("TGLScene::UpdatePhysioLogical", "expected ModifyLock");
1355 return;
1356 }
1357
1359
1360 if (log == nullptr) {
1361 Error("TGLScene::UpdatePhysioLogical", "logical not found");
1362 return;
1363 }
1364
1365 if (log->Ref() != 1) {
1366 Warning("TGLScene::UpdatePhysioLogical", "expecting a single physical (%d).", log->Ref());
1367 }
1368
1369 TGLPhysicalShape* phys = log->fFirstPhysical;
1370 if (trans) phys->SetTransform(trans);
1371 if (col) phys->SetDiffuseColor(col);
1372}
1373
1374////////////////////////////////////////////////////////////////////////////////
1375/// Reposition/recolor physical for given logical (assume TGLObject and
1376/// a single physical).
1377
1379{
1380 if (fLock != kModifyLock) {
1381 Error("TGLScene::UpdatePhysioLogical", "expected ModifyLock");
1382 return;
1383 }
1384
1386
1387 if (log == nullptr) {
1388 Error("TGLScene::UpdatePhysioLogical", "logical not found");
1389 return;
1390 }
1391
1392 if (log->Ref() != 1) {
1393 Warning("TGLScene::UpdatePhysioLogical", "expecting a single physical (%d).", log->Ref());
1394 }
1395
1396 TGLPhysicalShape* phys = log->fFirstPhysical;
1397 if (trans)
1398 phys->SetTransform(trans);
1399 if (cidx >= 0) {
1400 Float_t rgba[4];
1402 phys->SetDiffuseColor(rgba);
1403 }
1404}
1405
1406
1407/**************************************************************************/
1408// Smart refresh
1409/**************************************************************************/
1410
1411////////////////////////////////////////////////////////////////////////////////
1412/// Moves logicals that support smart-refresh to intermediate cache.
1413/// Destroys the others and returns the number of destroyed ones.
1414
1416{
1418 // Remove all logicals that don't survive a refresh.
1419 UInt_t count = 0;
1421 while (i != fSmartRefreshCache.end()) {
1422 if (i->second->KeepDuringSmartRefresh() == kFALSE) {
1423 LogicalShapeMapIt_t j = i++;
1424 delete j->second;
1425 fSmartRefreshCache.erase(j);
1426 ++count;
1427 } else {
1428 ++i;
1429 }
1430 }
1432 return count;
1433}
1434
1435////////////////////////////////////////////////////////////////////////////////
1436/// Wipes logicals in refresh-cache.
1437
1439{
1441
1443 while (i != fSmartRefreshCache.end()) {
1444 delete i->second;
1445 ++i;
1446 }
1447 fSmartRefreshCache.clear();
1448}
1449
1450////////////////////////////////////////////////////////////////////////////////
1451/// Find and return logical shape identified by unique 'ID' in refresh-cache.
1452/// Returns 0 if not found.
1453
1455{
1457 if (it != fSmartRefreshCache.end())
1458 {
1459 TGLLogicalShape* l_shape = it->second;
1460 fSmartRefreshCache.erase(it);
1461 if (l_shape->IsA() != TGLObject::GetGLRenderer(ID->IsA()))
1462 {
1463 Warning("TGLScene::FindLogicalSmartRefresh", "Wrong renderer-type found in cache.");
1464 delete l_shape;
1465 return nullptr;
1466 }
1467 // printf("TGLScene::SmartRefresh found cached: %p '%s' [%s] for %p\n",
1468 // l_shape, l_shape->GetExternal()->GetName(),
1469 // l_shape->GetExternal()->IsA()->GetName(), (void*) ID);
1472 l_shape->DLCacheClear();
1473 l_shape->UpdateBoundingBox();
1474 return l_shape;
1475 } else {
1476 return nullptr;
1477 }
1478}
1479
1480
1481/**************************************************************************/
1482// Helpers
1483/**************************************************************************/
1484
1485////////////////////////////////////////////////////////////////////////////////
1486/// Return memory cost of scene.
1487/// Warning: NOT CORRECT at present - doesn't correctly calculate size.
1488/// of logical shapes with dynamic internal contents.
1489
1491{
1492 UInt_t size = sizeof(*this);
1493
1494 printf("Size: Scene Only %u\n", size);
1495
1498 while (logicalShapeIt != fLogicalShapes.end()) {
1499 logicalShape = logicalShapeIt->second;
1500 size += sizeof(*logicalShape);
1502 }
1503
1504 printf("Size: Scene + Logical Shapes %u\n", size);
1505
1508 while (physicalShapeIt != fPhysicalShapes.end()) {
1510 size += sizeof(*physicalShape);
1512 }
1513
1514 printf("Size: Scene + Logical Shapes + Physical Shapes %u\n", size);
1515
1516 return size;
1517}
1518
1519////////////////////////////////////////////////////////////////////////////////
1520/// Print sizes of logical and physical-shape maps.
1521
1523{
1524 printf("Scene: %u Logicals / %u Physicals\n",
1525 (UInt_t) fLogicalShapes.size(), (UInt_t) fPhysicalShapes.size());
1526}
1527
1528////////////////////////////////////////////////////////////////////////////////
1529/// Fill rgba color from ROOT color-index ci and transparency (0->100).
1530
1532{
1533 TColor* c = gROOT->GetColor(ci);
1534 if(c) c->GetRGB(rgba[0], rgba[1], rgba[2]);
1535 else rgba[0] = rgba[1] = rgba[2] = 0.5;
1536 rgba[3] = 1.0f - transp/100.0f;
1537}
1538
1539////////////////////////////////////////////////////////////////////////////////
1540/// Check if box is outside of all planes.
1541
1543 const TGLPlaneSet_t & planes)
1544{
1545 for (TGLPlaneSet_ci p=planes.begin(); p!=planes.end(); ++p)
1546 if (box.Overlap(*p) == Rgl::kOutside)
1547 return kTRUE;
1548 return kFALSE;
1549}
#define c(i)
Definition RSha256.hxx:101
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:69
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
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
std::vector< TGLPlane > TGLPlaneSet_t
Definition TGLUtil.h:571
std::vector< TGLPlane >::const_iterator TGLPlaneSet_ci
Definition TGLUtil.h:573
winID h TVirtualViewer3D TVirtualGLPainter p
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
#define gROOT
Definition TROOT.h:411
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
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
The color creation and management class.
Definition TColor.h:22
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
Concrete class describing an orientated (free) or axis aligned box of 8 vertices.
void SetAligned(const TGLVertex3 &lowVertex, const TGLVertex3 &highVertex)
Set ALIGNED box from two low/high vertices.
Identifier of a shared GL-context.
Definition TGLContext.h:81
Bool_t IsValid() const
Definition TGLContext.h:99
Bool_t TakeLock(ELock lock) const
Lock the object in mode 'lock'.
Bool_t ReleaseLock(ELock lock) const
Release current lock, make sure it the same as the 'lock' argument.
Abstract logical shape - a GL 'drawable' - base for all shapes - faceset sphere etc.
static void SetEnvDefaults()
TObject * ID() const
TGLScene * fScene
Shape's bounding box.
static TClass * GetGLRenderer(TClass *isa)
Return direct-rendering GL class for class isa.
Concrete physical shape - a GL drawable.
UInt_t ID() const
const TGLLogicalShape * GetLogical() const
Bool_t IsTransparent() const
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
static const char * StyleName(Short_t style)
Return string describing the style.
@ kPassOutlineFill
Definition TGLRnrCtx.h:56
@ kPassWireFrame
Definition TGLRnrCtx.h:58
@ kPassOutlineLine
Definition TGLRnrCtx.h:57
Short_t CombiLOD() const
Definition TGLRnrCtx.h:175
Scene base-class – provides basic interface expected by the TGLViewer or its sub-classes:
virtual void PostDraw(TGLRnrCtx &rnrCtx)
Finalize drawing.
UInt_t fMinorStamp
TGLBoundingBox fBoundingBox
virtual void LodifySceneInfo(TGLRnrCtx &ctx)
Setup LOD-dependant values in scene-info.
Bool_t fBoundingBoxValid
void IncTimeStamp()
UInt_t fSceneID
UInt_t GetMinorStamp() const
void InvalidateBoundingBox()
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.
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.
void IncMinorStamp()
Base class for extended scene context.
void PostDraw()
Clean-up after drawing, nothing to be done here.
Definition TGLScene.cxx:169
void ClearAfterRebuild()
Clear DrawElementVector fVisibleElement and optionally resize it so that it doesn't take more space t...
Definition TGLScene.cxx:101
void ResetDrawStats()
Reset draw statistics.
Definition TGLScene.cxx:176
void DumpDrawStats()
Output draw stats to Info stream.
Definition TGLScene.cxx:218
~TSceneInfo() override
Destructor.
Definition TGLScene.cxx:60
TSceneInfo(TGLViewerBase *view=nullptr, TGLScene *scene=nullptr)
Constructor.
Definition TGLScene.cxx:48
void PreDraw()
Prepare for drawing - fill DrawElementPtrVectors from the contents of fVisibleElements if there was s...
Definition TGLScene.cxx:138
void ClearDrawElementVec(DrawElementVec_t &vec, Int_t maxSize)
Clear given vec and if it grew too large compared to the size of shape-of-interest also resize it.
Definition TGLScene.cxx:68
void UpdateDrawStats(const TGLPhysicalShape &shape, Short_t lod)
Update draw stats, for newly drawn 'shape'.
Definition TGLScene.cxx:187
void ClearAfterUpdate()
Clear DrawElementPtrVectors and optionally resize them so that they don't take more space then requir...
Definition TGLScene.cxx:113
void Lodify(TGLRnrCtx &ctx)
Quantize LODs for given render-context.
Definition TGLScene.cxx:128
void ClearDrawElementPtrVec(DrawElementPtrVec_t &vec, Int_t maxSize)
Clear given vec and if it grew too large compared to the size of shape-of-interest also resize it.
Definition TGLScene.cxx:84
TGLScene provides management and rendering of ROOT's default 3D /object representation as logical and...
Definition TGLScene.h:29
Float_t fLastLineWidthScale
Definition TGLScene.h:140
void UpdateSceneInfo(TGLRnrCtx &rnrCtx) override
Fill scene-info with information needed for rendering, take into account the render-context (viewer s...
Definition TGLScene.cxx:425
std::vector< DrawElement_t > DrawElementVec_t
Definition TGLScene.h:65
virtual TGLPhysicalShape * FindPhysical(UInt_t phid) const
Find and return physical shape identified by unique 'ID'.
PhysicalShapeMap_t::const_iterator PhysicalShapeMapCIt_t
Definition TGLScene.h:50
void RenderOpaque(TGLRnrCtx &rnrCtx) override
Render opaque elements.
Definition TGLScene.cxx:612
void CalcBoundingBox() const override
Encapsulates all physical shapes bounding box with axes aligned box.
Definition TGLScene.cxx:976
virtual void DestroyPhysicalInternal(PhysicalShapeMapIt_t pit)
Virtual function to destroy a physical.
void PostDraw(TGLRnrCtx &rnrCtx) override
Called after the rendering is finished.
Definition TGLScene.cxx:706
virtual Bool_t BeginUpdate()
Put scene in update mode, return true if lock acquired.
virtual void AdoptPhysical(TGLPhysicalShape &shape)
Adopt dynamically created physical 'shape' - add to internal map and take responsibility for deleting...
void ReleaseGLCtxIdentity()
Release all GL resources for current context identity.
Definition TGLScene.cxx:310
LogicalShapeMap_t::const_iterator LogicalShapeMapCIt_t
Definition TGLScene.h:44
void RebuildSceneInfo(TGLRnrCtx &rnrCtx) override
Major change in scene, need to rebuild all-element draw-vector and sort it.
Definition TGLScene.cxx:381
virtual void EndUpdate(Bool_t minorChange=kTRUE, Bool_t sceneChanged=kTRUE, Bool_t updateViewers=kTRUE)
Exit scene update mode.
Float_t fLastPointSizeScale
Definition TGLScene.h:139
static Bool_t ComparePhysicalVolumes(const TGLPhysicalShape *shape1, const TGLPhysicalShape *shape2)
Compare 'shape1' and 'shape2' bounding box volumes - return kTRUE if 'shape1' bigger than 'shape2'.
Definition TGLScene.cxx:355
LogicalShapeMap_t fLogicalShapes
Definition TGLScene.h:125
virtual Int_t DestroyPhysicals()
Destroy physical shapes.
virtual void RenderAllPasses(TGLRnrCtx &rnrCtx, DrawElementPtrVec_t &elVec, Bool_t check_timeout)
Do full rendering of scene.
Definition TGLScene.cxx:724
virtual void AdoptLogical(TGLLogicalShape &shape)
Adopt dynamically created logical 'shape' - add to internal map and take responsibility for deleting.
void LodifySceneInfo(TGLRnrCtx &rnrCtx) override
Setup LOD-dependant values in scene-info.
Definition TGLScene.cxx:543
virtual void RenderElements(TGLRnrCtx &rnrCtx, DrawElementPtrVec_t &elVec, Bool_t check_timeout, const TGLPlaneSet_t *clipPlanes=nullptr)
Render DrawElements in elementVec with given timeout.
Definition TGLScene.cxx:892
Bool_t ResolveSelectRecord(TGLSelectRecord &rec, Int_t curIdx) override
Process selection record rec.
Definition TGLScene.cxx:949
static Bool_t IsOutside(const TGLBoundingBox &box, const TGLPlaneSet_t &planes)
Check if box is outside of all planes.
void RenderSelTranspForHighlight(TGLRnrCtx &rnrCtx) override
Render selected transparent elements for highlight.
Definition TGLScene.cxx:662
void EndSmartRefresh()
Wipes logicals in refresh-cache.
virtual Bool_t DestroyLogical(TObject *logid, Bool_t mustFind=kTRUE)
Destroy logical shape defined by unique 'ID'.
std::vector< const TGLPhysicalShape * > ShapeVec_t
Definition TGLScene.h:72
Bool_t fInSmartRefresh
Definition TGLScene.h:135
UInt_t SizeOfScene() const
Return memory cost of scene.
PhysicalShapeMap_t::iterator PhysicalShapeMapIt_t
Definition TGLScene.h:49
LogicalShapeMap_t fSmartRefreshCache
Definition TGLScene.h:136
virtual void RenderHighlight(TGLRnrCtx &rnrCtx, DrawElementPtrVec_t &elVec)
Definition TGLScene.cxx:671
PhysicalShapeMap_t fPhysicalShapes
Definition TGLScene.h:126
std::vector< DrawElement_t >::iterator DrawElementVec_i
Definition TGLScene.h:66
TSceneInfo * CreateSceneInfo(TGLViewerBase *view) override
Create a scene-info instance appropriate for this scene class.
Definition TGLScene.cxx:346
LogicalShapeMap_t::iterator LogicalShapeMapIt_t
Definition TGLScene.h:43
PhysicalShapeMap_t::value_type PhysicalShapeMapValueType_t
Definition TGLScene.h:48
LogicalShapeMap_t::value_type LogicalShapeMapValueType_t
Definition TGLScene.h:42
std::vector< DrawElement_t * > DrawElementPtrVec_t
Definition TGLScene.h:68
std::map< TObject *, TGLLogicalShape * > LogicalShapeMap_t
Definition TGLScene.h:41
friend class TSceneInfo
Definition TGLScene.h:121
ShapeVec_t::iterator ShapeVec_i
Definition TGLScene.h:73
void RenderSelOpaqueForHighlight(TGLRnrCtx &rnrCtx) override
Render selected opaque elements for highlight.
Definition TGLScene.cxx:652
virtual void UpdatePhysioLogical(TObject *logid, Double_t *trans, UChar_t *col)
Reposition/recolor physical for given logical (assume TGLObject and a single physical).
virtual Bool_t DestroyPhysical(UInt_t phid)
Destroy physical shape defined by unique 'ID'.
static void RGBAFromColorIdx(Float_t rgba[4], Color_t ci, Char_t transp=0)
Fill rgba color from ROOT color-index ci and transparency (0->100).
void RenderTransp(TGLRnrCtx &rnrCtx) override
Render transparent elements.
Definition TGLScene.cxx:622
virtual Int_t DestroyLogicals()
Destroy all logical shapes in scene.
TGLLogicalShape * FindLogicalSmartRefresh(TObject *ID) const
Find and return logical shape identified by unique 'ID' in refresh-cache.
~TGLScene() override
Destroy scene objects.
Definition TGLScene.cxx:291
std::vector< DrawElement_t * >::iterator DrawElementPtrVec_i
Definition TGLScene.h:69
void RenderSelTransp(TGLRnrCtx &rnrCtx) override
Render selected transparent elements.
Definition TGLScene.cxx:642
virtual void UpdateLogical(TObject *logid)
Drop display-lists for the logical (assume TGLObject/direct rendering).
TGLContextIdentity * fGLCtxIdentity
Definition TGLScene.h:131
void PreDraw(TGLRnrCtx &rnrCtx) override
Initialize rendering.
Definition TGLScene.cxx:567
void DumpMapSizes() const
Print sizes of logical and physical-shape maps.
virtual void UpdatePhysical(UInt_t phid, Double_t *trans, UChar_t *col)
Reposition/recolor physical shape.
virtual UInt_t GetMaxPhysicalID()
Returns the maximum used physical id.
TGLLogicalShape * FindLogical(TObject *logid) const override
Find and return logical shape identified by unique logid.
UInt_t BeginSmartRefresh()
Moves logicals that support smart-refresh to intermediate cache.
static Bool_t ComparePhysicalDiagonals(const TGLPhysicalShape *shape1, const TGLPhysicalShape *shape2)
Compare 'shape1' and 'shape2' bounding box volumes - return kTRUE if 'shape1' bigger than 'shape2'.
Definition TGLScene.cxx:365
void RenderSelOpaque(TGLRnrCtx &rnrCtx) override
Render selected opaque elements.
Definition TGLScene.cxx:632
Standard selection record including information about containing scene and details ob out selected ob...
static Float_t GetPointSizeScale()
Get global point-size scale.
Definition TGLUtil.cxx:1874
static Float_t GetLineWidthScale()
Returns global line-width scale.
Definition TGLUtil.cxx:1890
static Float_t LineWidth()
Get the line-width, taking the global scaling into account.
Definition TGLUtil.cxx:1934
3 component (x/y/z) vertex class.
Definition TGLUtil.h:84
Base class for GL viewers.
Mother of all ROOT objects.
Definition TObject.h:41
virtual TClass * IsA() const
Definition TObject.h:246
Basic string class.
Definition TString.h:138
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
EOverlap
Definition TGLUtil.h:35
@ kInside
Definition TGLUtil.h:36
@ kOutside
Definition TGLUtil.h:38