1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0027787: Visualization, TKOpenGl - Optimize rendering by additional check whether the object is fully clipped or not

OpenGl_Structure::Render() now checks if structure is entirely clipped to skip rendering at all,
or entirely NOT clipped to disable clipping / capping plane.

OpenGl_ShaderManager now defines dedicated GLSL programs for one and two clipping planes
to optimize rendering on slow hardware.
This commit is contained in:
dbp
2016-08-18 19:41:05 +03:00
committed by bugmaster
parent afa6834bcd
commit 1a7ece8f23
7 changed files with 178 additions and 40 deletions

View File

@@ -518,13 +518,12 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
// Set up plane equations for non-structure transformed global model-view matrix
// List of planes to be applied to context state
NCollection_Handle<Graphic3d_SequenceOfHClipPlane> aUserPlanes;
Handle(NCollection_Shared<Graphic3d_SequenceOfHClipPlane>) aUserPlanes, aDisabledPlanes;
// Collect clipping planes of structure scope
if (!myClipPlanes.IsEmpty())
{
Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes);
for (; aClippingIter.More(); aClippingIter.Next())
for (Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes); aClippingIter.More(); aClippingIter.Next())
{
const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
if (!aClipPlane->IsOn())
@@ -534,14 +533,12 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
if (aUserPlanes.IsNull())
{
aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
aUserPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
}
aUserPlanes->Append (aClipPlane);
}
}
if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
if (!aUserPlanes.IsNull())
{
// add planes at loaded view matrix state
aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
@@ -550,9 +547,61 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
aCtx->ShaderManager()->UpdateClippingState();
}
// True if structure is fully clipped
bool isClipped = false;
// Set of clipping planes that do not intersect the structure,
// and thus can be disabled to improve rendering performance
const Graphic3d_BndBox4f& aBBox = BoundingBox();
if (!aCtx->Clipping().Planes().IsEmpty() && aBBox.IsValid() && TransformPersistence.Flags == Graphic3d_TMF_None)
{
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aCtx->Clipping().Planes()); aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
if (!aPlane->IsOn())
{
continue;
}
// check for clipping
const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
1.0);
if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
{
isClipped = true;
break;
}
// check for no intersection (e.g. object is "entirely not clipped")
const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
1.0);
if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
{
aCtx->ChangeClipping().SetEnabled (aCtx, aPlane, Standard_False);
if (aDisabledPlanes.IsNull())
{
aDisabledPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
if (aUserPlanes.IsNull())
{
aCtx->ShaderManager()->UpdateClippingState();
}
}
aDisabledPlanes->Append (aPlane);
}
}
}
// Render groups
bool hasClosedPrims = false;
renderGeometry (theWorkspace, hasClosedPrims);
if (!isClipped)
{
renderGeometry (theWorkspace, hasClosedPrims);
}
// Reset correction for mirror transform
if (myIsMirrored)
@@ -562,13 +611,25 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
// Render capping for structure groups
if (hasClosedPrims
&& !aCtx->Clipping().Planes().IsEmpty())
&& aCtx->Clipping().IsCappingOn())
{
OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
}
// Revert structure clippings
if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
if (!aDisabledPlanes.IsNull())
{
// enable planes that were previously disabled
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aDisabledPlanes); aPlaneIt.More(); aPlaneIt.Next())
{
aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt.Value(), Standard_True);
}
if (aUserPlanes.IsNull())
{
aCtx->ShaderManager()->RevertClippingState();
}
}
if (!aUserPlanes.IsNull())
{
aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);