From 2b8832bb0ebd09520819fa2bc574e1a3e112b132 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 8 Nov 2017 09:44:27 +0300 Subject: [PATCH] 0028760: Visualization, TKOpenGl - avoid excessive frustum culling traverse within extra OIT rendering pass Culling traverse is no more called implicitly within OpenGl_Layer::Render(). Instead, all layers are traversed at onces within OpenGl_View::render() beforehand. OpenGl_BVHTreeSelector methods have been renamed to better reflect their meaning. Non-persistent culling options has been moved to dedicated structure OpenGl_BVHTreeSelector::CullingContext so that OpenGl_BVHTreeSelector instance can be used for different Layers without modifying its state. --- src/OpenGl/OpenGl_BVHTreeSelector.cxx | 105 +++------------------- src/OpenGl/OpenGl_BVHTreeSelector.hxx | 124 +++++++++++++++++++++++--- src/OpenGl/OpenGl_Layer.cxx | 76 +++++++--------- src/OpenGl/OpenGl_Layer.hxx | 25 +++--- src/OpenGl/OpenGl_LayerList.cxx | 22 ++++- src/OpenGl/OpenGl_LayerList.hxx | 4 + src/OpenGl/OpenGl_Structure.hxx | 9 +- src/OpenGl/OpenGl_View.hxx | 2 +- src/OpenGl/OpenGl_View_Redraw.cxx | 3 + 9 files changed, 202 insertions(+), 168 deletions(-) diff --git a/src/OpenGl/OpenGl_BVHTreeSelector.cxx b/src/OpenGl/OpenGl_BVHTreeSelector.cxx index 644b429fce..b6d994213a 100644 --- a/src/OpenGl/OpenGl_BVHTreeSelector.cxx +++ b/src/OpenGl/OpenGl_BVHTreeSelector.cxx @@ -26,9 +26,7 @@ OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector() : myIsProjectionParallel (Standard_True), myCamScaleInv (1.0), - myDistCull (-1.0), - myPixelSize (1.0), - mySizeCull2 (-1.0) + myPixelSize (1.0) { // } @@ -166,14 +164,15 @@ Standard_Real OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec // function : SetCullingDistance // purpose : // ======================================================================= -void OpenGl_BVHTreeSelector::SetCullingDistance (Standard_Real theDistance) +void OpenGl_BVHTreeSelector::SetCullingDistance (CullingContext& theCtx, + Standard_Real theDistance) const { - myDistCull = -1.0; + theCtx.DistCull = -1.0; if (!myIsProjectionParallel) { - myDistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance) - ? theDistance - : -1.0; + theCtx.DistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance) + ? theDistance + : -1.0; } } @@ -181,13 +180,14 @@ void OpenGl_BVHTreeSelector::SetCullingDistance (Standard_Real theDistance) // function : SetCullingSize // purpose : // ======================================================================= -void OpenGl_BVHTreeSelector::SetCullingSize (Standard_Real theSize) +void OpenGl_BVHTreeSelector::SetCullingSize (CullingContext& theCtx, + Standard_Real theSize) const { - mySizeCull2 = -1.0; + theCtx.SizeCull2 = -1.0; if (theSize > 0.0 && !Precision::IsInfinite (theSize)) { - mySizeCull2 = (myPixelSize * theSize) / myCamScaleInv; - mySizeCull2 *= mySizeCull2; + theCtx.SizeCull2 = (myPixelSize * theSize) / myCamScaleInv; + theCtx.SizeCull2 *= theCtx.SizeCull2; } } @@ -233,84 +233,3 @@ void OpenGl_BVHTreeSelector::CacheClipPtsProjections() myMinOrthoProjectionPts[aDim] = aMinProj; } } - -// ======================================================================= -// function : Intersect -// purpose : Detects if AABB overlaps view volume using separating axis theorem (SAT) -// ======================================================================= -Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec3d& theMinPt, - const OpenGl_Vec3d& theMaxPt) const -{ - // E1 - // |_ E0 - // / - // E2 - - // E0 test - if (theMinPt.x() > myMaxOrthoProjectionPts[0] - || theMaxPt.x() < myMinOrthoProjectionPts[0]) - { - return Standard_False; - } - - // E1 test - if (theMinPt.y() > myMaxOrthoProjectionPts[1] - || theMaxPt.y() < myMinOrthoProjectionPts[1]) - { - return Standard_False; - } - - // E2 test - if (theMinPt.z() > myMaxOrthoProjectionPts[2] - || theMaxPt.z() < myMinOrthoProjectionPts[2]) - { - return Standard_False; - } - - Standard_Real aBoxProjMax = 0.0, aBoxProjMin = 0.0; - const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1; - for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor) - { - OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter]; - aBoxProjMax = (aPlane.x() > 0.0 ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x()) - + (aPlane.y() > 0.0 ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y()) - + (aPlane.z() > 0.0 ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z()); - if (aBoxProjMax > myMinClipProjectionPts[aPlaneIter] - && aBoxProjMax < myMaxClipProjectionPts[aPlaneIter]) - { - continue; - } - - aBoxProjMin = (aPlane.x() < 0.0 ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x()) - + (aPlane.y() < 0.0 ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y()) - + (aPlane.z() < 0.0 ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z()); - if (aBoxProjMin > myMaxClipProjectionPts[aPlaneIter] - || aBoxProjMax < myMinClipProjectionPts[aPlaneIter]) - { - return Standard_False; - } - } - - // distance culling - discard node if distance to it's bounding box from camera eye is less than specified culling distance - if (myDistCull > 0.0) - { - // check distance to the bounding sphere as fast approximation - const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5; - const Standard_Real aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5; - if ((aSphereCenter - myCamEye).Modulus() - aSphereRadius > myDistCull) - { - return Standard_False; - } - } - - // size culling - discard node if diagonal of it's bounding box is less than specified culling size - if (mySizeCull2 > 0.0) - { - if ((theMaxPt - theMinPt).SquareModulus() < mySizeCull2) - { - return Standard_False; - } - } - - return Standard_True; -} diff --git a/src/OpenGl/OpenGl_BVHTreeSelector.hxx b/src/OpenGl/OpenGl_BVHTreeSelector.hxx index e0815f5931..902e194141 100644 --- a/src/OpenGl/OpenGl_BVHTreeSelector.hxx +++ b/src/OpenGl/OpenGl_BVHTreeSelector.hxx @@ -25,6 +25,16 @@ //! view volume. class OpenGl_BVHTreeSelector { +public: + //! Auxiliary structure holding non-persistent culling options. + struct CullingContext + { + Standard_Real DistCull; //!< culling distance + Standard_Real SizeCull2; //!< squared culling size + + //! Empty constructor. + CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {} + }; public: //! Creates an empty selector object with parallel projection type by default. @@ -38,21 +48,30 @@ public: Standard_Real theResolutionRatio); //! Setup distance culling. - Standard_EXPORT void SetCullingDistance (Standard_Real theDistance); + Standard_EXPORT void SetCullingDistance (CullingContext& theCtx, + Standard_Real theDistance) const; //! Setup size culling. - Standard_EXPORT void SetCullingSize (Standard_Real theSize); + Standard_EXPORT void SetCullingSize (CullingContext& theCtx, + Standard_Real theSize) const; //! Caches view volume's vertices projections along its normals and AABBs dimensions. //! Must be called at the beginning of each BVH tree traverse loop. Standard_EXPORT void CacheClipPtsProjections(); - //! Detects if AABB overlaps view volume using separating axis theorem (SAT). - //! @param theMinPt [in] maximum point of AABB. - //! @param theMaxPt [in] minimum point of AABB. - //! @return Standard_True, if AABB is in viewing area, Standard_False otherwise. - Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec3d& theMinPt, - const OpenGl_Vec3d& theMaxPt) const; + //! Checks whether given AABB should be entirely culled or not. + //! @param theCtx [in] culling properties + //! @param theMinPt [in] maximum point of AABB + //! @param theMaxPt [in] minimum point of AABB + //! @return Standard_True, if AABB is in viewing area, Standard_False otherwise + bool IsCulled (const CullingContext& theCtx, + const OpenGl_Vec3d& theMinPt, + const OpenGl_Vec3d& theMaxPt) const + { + return isFullOut (theMinPt, theMaxPt) + || isTooDistant(theCtx, theMinPt, theMaxPt) + || isTooSmall (theCtx, theMinPt, theMaxPt); + } //! Return the camera definition. const Handle(Graphic3d_Camera)& Camera() const { return myCamera; } @@ -93,6 +112,93 @@ protected: Standard_EXPORT Standard_Real SignedPlanePointDistance (const OpenGl_Vec4d& theNormal, const OpenGl_Vec4d& thePnt); + //! Detects if AABB overlaps view volume using separating axis theorem (SAT). + //! @param theMinPt [in] maximum point of AABB. + //! @param theMaxPt [in] minimum point of AABB. + //! @return FALSE, if AABB is in viewing area, TRUE otherwise. + bool isFullOut (const OpenGl_Vec3d& theMinPt, + const OpenGl_Vec3d& theMaxPt) const + { + // E1 + // |_ E0 + // / + // E2 + + // E0 test + if (theMinPt.x() > myMaxOrthoProjectionPts[0] + || theMaxPt.x() < myMinOrthoProjectionPts[0]) + { + return true; + } + + // E1 test + if (theMinPt.y() > myMaxOrthoProjectionPts[1] + || theMaxPt.y() < myMinOrthoProjectionPts[1]) + { + return true; + } + + // E2 test + if (theMinPt.z() > myMaxOrthoProjectionPts[2] + || theMaxPt.z() < myMinOrthoProjectionPts[2]) + { + return true; + } + + Standard_Real aBoxProjMax = 0.0, aBoxProjMin = 0.0; + const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1; + for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor) + { + OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter]; + aBoxProjMax = (aPlane.x() > 0.0 ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x()) + + (aPlane.y() > 0.0 ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y()) + + (aPlane.z() > 0.0 ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z()); + if (aBoxProjMax > myMinClipProjectionPts[aPlaneIter] + && aBoxProjMax < myMaxClipProjectionPts[aPlaneIter]) + { + continue; + } + + aBoxProjMin = (aPlane.x() < 0.0 ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x()) + + (aPlane.y() < 0.0 ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y()) + + (aPlane.z() < 0.0 ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z()); + if (aBoxProjMin > myMaxClipProjectionPts[aPlaneIter] + || aBoxProjMax < myMinClipProjectionPts[aPlaneIter]) + { + return true; + } + } + return false; + } + + //! Returns TRUE if given AABB should be discarded by distance culling criterion. + bool isTooDistant (const CullingContext& theCtx, + const OpenGl_Vec3d& theMinPt, + const OpenGl_Vec3d& theMaxPt) const + { + if (theCtx.DistCull <= 0.0) + { + return false; + } + + // check distance to the bounding sphere as fast approximation + const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5; + const Standard_Real aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5; + return (aSphereCenter - myCamEye).Modulus() - aSphereRadius > theCtx.DistCull; + } + + //! Returns TRUE if given AABB should be discarded by size culling criterion. + bool isTooSmall (const CullingContext& theCtx, + const OpenGl_Vec3d& theMinPt, + const OpenGl_Vec3d& theMaxPt) const + { + if (theCtx.SizeCull2 <= 0.0) + { + return false; + } + return (theMaxPt - theMinPt).SquareModulus() < theCtx.SizeCull2; + } + protected: //! Enumerates planes of view volume. @@ -150,9 +256,7 @@ protected: Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling Standard_Real myCamScaleInv; //!< inverted camera scale for size culling - Standard_Real myDistCull; //!< culling distance Standard_Real myPixelSize; //!< pixel size for size culling - Standard_Real mySizeCull2; //!< squared culling size }; diff --git a/src/OpenGl/OpenGl_Layer.cxx b/src/OpenGl/OpenGl_Layer.cxx index f5bca3f86b..e5e94cf03f 100644 --- a/src/OpenGl/OpenGl_Layer.cxx +++ b/src/OpenGl/OpenGl_Layer.cxx @@ -34,7 +34,8 @@ OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities, myNbStructures (0), myBVHPrimitivesTrsfPers (theBuilder), myBVHIsLeftChildQueuedFirst (Standard_True), - myIsBVHPrimitivesNeedsReset (Standard_False) + myIsBVHPrimitivesNeedsReset (Standard_False), + myIsCulled (Standard_False) { myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true; } @@ -147,7 +148,7 @@ bool OpenGl_Layer::Remove (const OpenGl_Structure* theStruct, // function : InvalidateBVHData // purpose : // ======================================================================= -void OpenGl_Layer::InvalidateBVHData() const +void OpenGl_Layer::InvalidateBVHData() { myIsBVHPrimitivesNeedsReset = Standard_True; } @@ -429,12 +430,8 @@ void OpenGl_Layer::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) cons for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) { const OpenGl_Structure* aStruct = aStructIter.Value(); - if (!aStruct->IsVisible()) - { - continue; - } - else if (!aStruct->ViewAffinity.IsNull() - && !aStruct->ViewAffinity->IsVisible (aViewId)) + if (aStruct->IsCulled() + || !aStruct->IsVisible (aViewId)) { continue; } @@ -483,51 +480,43 @@ void OpenGl_Layer::updateBVH() const } // ======================================================================= -// function : renderTraverse +// function : UpdateCulling // purpose : // ======================================================================= -void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const +void OpenGl_Layer::UpdateCulling (const OpenGl_BVHTreeSelector& theSelector, + const Standard_Boolean theToTraverse) { updateBVH(); - if (myBVHPrimitives .Size() != 0 - || myBVHPrimitivesTrsfPers.Size() != 0) - { - OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector(); - aSelector.SetCullingDistance (myLayerSettings.CullingDistance()); - aSelector.SetCullingSize (myLayerSettings.CullingSize()); - aSelector.CacheClipPtsProjections(); - traverse (aSelector); - } - const Standard_Integer aViewId = theWorkspace->View()->Identification(); + myIsCulled = false; for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next()) { const OpenGl_IndexedMapOfStructure& aStructures = aMapIter.Value(); for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next()) { const OpenGl_Structure* aStruct = aStructIter.Value(); - if (aStruct->IsCulled() - || !aStruct->IsVisible (aViewId)) - { - continue; - } - - aStruct->Render (theWorkspace); - aStruct->ResetCullingStatus(); + aStruct->SetCulled (theToTraverse); } } -} -// ======================================================================= -// function : traverse -// purpose : -// ======================================================================= -void OpenGl_Layer::traverse (const OpenGl_BVHTreeSelector& theSelector) const -{ - opencascade::handle > aBVHTree; + if (!theToTraverse) + { + return; + } + if (myBVHPrimitives .Size() == 0 + && myBVHPrimitivesTrsfPers.Size() == 0) + { + return; + } + + myIsCulled = myAlwaysRenderedMap.IsEmpty(); + OpenGl_BVHTreeSelector::CullingContext aCullCtx; + theSelector.SetCullingDistance(aCullCtx, myLayerSettings.CullingDistance()); + theSelector.SetCullingSize (aCullCtx, myLayerSettings.CullingSize()); for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx) { const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1; + opencascade::handle > aBVHTree; if (isTrsfPers) { if (myBVHPrimitivesTrsfPers.Size() == 0) @@ -549,26 +538,23 @@ void OpenGl_Layer::traverse (const OpenGl_BVHTreeSelector& theSelector) const aBVHTree = myBVHPrimitives.BVH(); } - Standard_Integer aNode = 0; // a root node - - if (!theSelector.Intersect (aBVHTree->MinPoint (0), - aBVHTree->MaxPoint (0))) + if (theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0))) { continue; } + myIsCulled = false; Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; Standard_Integer aHead = -1; + Standard_Integer aNode = 0; // a root node for (;;) { if (!aBVHTree->IsOuter (aNode)) { const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode); const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode); - const Standard_Boolean isLeftChildIn = theSelector.Intersect (aBVHTree->MinPoint (aLeftChildIdx), - aBVHTree->MaxPoint (aLeftChildIdx)); - const Standard_Boolean isRightChildIn = theSelector.Intersect (aBVHTree->MinPoint (aRightChildIdx), - aBVHTree->MaxPoint (aRightChildIdx)); + const Standard_Boolean isLeftChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx)); + const Standard_Boolean isRightChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx)); if (isLeftChildIn && isRightChildIn) { @@ -743,7 +729,7 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, } // render priority list - theWorkspace->IsCullingEnabled() ? renderTraverse (theWorkspace) : renderAll (theWorkspace); + renderAll (theWorkspace); if (hasLocalCS) { diff --git a/src/OpenGl/OpenGl_Layer.hxx b/src/OpenGl/OpenGl_Layer.hxx index a74ea4302a..ee96e8eff2 100644 --- a/src/OpenGl/OpenGl_Layer.hxx +++ b/src/OpenGl/OpenGl_Layer.hxx @@ -92,7 +92,7 @@ public: //! Marks BVH tree for given priority list as dirty and //! marks primitive set for rebuild. - void InvalidateBVHData() const; + void InvalidateBVHData(); //! Marks cached bounding box as obsolete. void InvalidateBoundingBox() const @@ -119,6 +119,14 @@ public: const Standard_Integer theWindowWidth, const Standard_Integer theWindowHeight) const; + //! Update culling state - should be called before rendering. + //! Traverses through BVH tree to determine which structures are in view volume. + void UpdateCulling (const OpenGl_BVHTreeSelector& theSelector, + const Standard_Boolean theToTraverse); + + //! Returns TRUE if layer is empty or has been discarded entirely by culling test. + bool IsCulled() const { return myNbStructures == 0 || myIsCulled; } + // Render all structures. void Render (const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_GlobalLayerSettings& theDefaultSettings) const; @@ -134,15 +142,9 @@ protected: //! Updates BVH trees if their state has been invalidated. void updateBVH() const; - //! Traverses through BVH tree to determine which structures are in view volume. - void traverse (const OpenGl_BVHTreeSelector& theSelector) const; - //! Iterates through the hierarchical list of existing structures and renders them all. void renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const; - //! Iterates through the hierarchical list of existing structures and renders only overlapping ones. - void renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const; - private: //! Array of OpenGl_Structures by priority rendered in layer. @@ -164,7 +166,7 @@ private: mutable NCollection_IndexedMap myAlwaysRenderedMap; //! Is needed for implementation of stochastic order of BVH traverse. - mutable Standard_Boolean myBVHIsLeftChildQueuedFirst; + Standard_Boolean myBVHIsLeftChildQueuedFirst; //! Defines if the primitive set for BVH is outdated. mutable Standard_Boolean myIsBVHPrimitivesNeedsReset; @@ -172,13 +174,12 @@ private: //! Defines if the cached bounding box is outdated. mutable bool myIsBoundingBoxNeedsReset[2]; + //! Flag indicating that this layer is marked culled as whole + bool myIsCulled; + //! Cached layer bounding box. mutable Bnd_Box myBoundingBox[2]; -public: - - DEFINE_STANDARD_ALLOC - }; #endif //_OpenGl_Layer_Header diff --git a/src/OpenGl/OpenGl_LayerList.cxx b/src/OpenGl/OpenGl_LayerList.cxx index aa361ac2e0..eddee5b10c 100644 --- a/src/OpenGl/OpenGl_LayerList.cxx +++ b/src/OpenGl/OpenGl_LayerList.cxx @@ -509,6 +509,26 @@ void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId theLaye aLayer.SetLayerSettings (theSettings); } +//======================================================================= +//function : UpdateCulling +//purpose : +//======================================================================= +void OpenGl_LayerList::UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspace, + const Standard_Boolean theToDrawImmediate) +{ + const OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector(); + for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next()) + { + OpenGl_Layer& aLayer = *anIts.ChangeValue(); + if (aLayer.IsImmediate() != theToDrawImmediate) + { + continue; + } + + aLayer.UpdateCulling (aSelector, theWorkspace->IsCullingEnabled()); + } +} + //======================================================================= //function : Render //purpose : @@ -588,7 +608,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, { aClearDepthLayer = aLayerIter.Index(); } - if (aLayer.NbStructures() < 1) + if (aLayer.IsCulled()) { continue; } diff --git a/src/OpenGl/OpenGl_LayerList.hxx b/src/OpenGl/OpenGl_LayerList.hxx index 1e7848cba2..bf4063c49b 100644 --- a/src/OpenGl/OpenGl_LayerList.hxx +++ b/src/OpenGl/OpenGl_LayerList.hxx @@ -88,6 +88,10 @@ public: void SetLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings); + //! Update culling state - should be called before rendering. + void UpdateCulling (const Handle(OpenGl_Workspace)& theWorkspace, + const Standard_Boolean theToDrawImmediate); + //! Render this element void Render (const Handle(OpenGl_Workspace)& theWorkspace, const Standard_Boolean theToDrawImmediate, diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index 11d38ac9b6..e7f679b352 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -119,13 +119,10 @@ public: //! Releases structure resources. virtual void Release (const Handle(OpenGl_Context)& theGlCtx); - //! Marks structure as not overlapping view volume (as it is by default). - void ResetCullingStatus() const + //! Marks structure as culled/not culled. + void SetCulled (Standard_Boolean theIsCulled) const { - if (!IsAlwaysRendered()) - { - myIsCulled = Standard_True; - } + myIsCulled = theIsCulled && !IsAlwaysRendered(); } //! Marks structure as overlapping the current view volume one. diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 95adf316fa..f9e01422f4 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -336,7 +336,7 @@ public: //! Returns selector for BVH tree, providing a possibility to store information //! about current view volume and to detect which objects are overlapping it. - OpenGl_BVHTreeSelector& BVHTreeSelector() { return myBVHSelector; } + const OpenGl_BVHTreeSelector& BVHTreeSelector() const { return myBVHSelector; } //! Returns true if there are immediate structures to display bool HasImmediateStructures() const diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index b579c524a4..bc36fcc2d4 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -881,6 +881,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection, // note that we pass here window dimensions ignoring Graphic3d_RenderingParams::RenderResolutionScale myBVHSelector.SetViewVolume (myCamera); myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio()); + myBVHSelector.CacheClipPtsProjections(); const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager(); if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState) @@ -1058,6 +1059,8 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, myRaytraceInitStatus == OpenGl_RT_FAIL || aCtx->IsFeedback(); + myZLayers.UpdateCulling (myWorkspace, theToDrawImmediate); + if (!toRenderGL) { toRenderGL = !initRaytraceResources (aCtx) ||