From deb02f8655152ef50d24cfc489f4c177e9bf8f47 Mon Sep 17 00:00:00 2001 From: kgv Date: Fri, 5 Aug 2016 20:58:13 +0300 Subject: [PATCH] 0027735: Visualization, OpenGl_ShaderManager - fix clipping state management OpenGl_CappingAlgo::RenderCapping() now updates clipping state in Shader Manager. OpenGl_View::render() clipping state setup has been moved to OpenGl_View::renderScene(). OpenGl_ShaderManager now converts position to homogeneous coordinates within clipping code GLSL. This fixes capping plane rendering with clipping planes applied. Fixed possible Clipping planes misconfiguration when FFP is used; error-prone OpenGl_Clipping::AddWorldLazy() method has been dropped. --- src/OpenGl/OpenGl_CappingAlgo.cxx | 8 ++++++- src/OpenGl/OpenGl_Clipping.hxx | 12 ---------- src/OpenGl/OpenGl_ShaderManager.cxx | 2 +- src/OpenGl/OpenGl_Structure.cxx | 10 ++------ src/OpenGl/OpenGl_View_Redraw.cxx | 37 ++++++++++++++--------------- src/Shaders/PhongShading.fs | 2 +- tests/bugs/vis/bug24224 | 9 ++----- 7 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx index 13f33c484d..e2ce3c0ac6 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.cxx +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -14,13 +14,14 @@ // commercial license or contractual agreement. #include + #include #include #include #include #include #include -#include +#include IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter,OpenGl_RenderFilter) @@ -98,6 +99,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks const Standard_Boolean isOn = (aPlane == aRenderPlane); aContext->ChangeClipping().SetEnabled (aContext, aPlane, isOn); } + aContext->ShaderManager()->UpdateClippingState(); glClear (GL_STENCIL_BUFFER_BIT); glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); @@ -126,6 +128,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks const Standard_Boolean isOn = (aPlane != aRenderPlane); aContext->ChangeClipping().SetEnabled (aContext, aPlane, isOn); } + aContext->ShaderManager()->UpdateClippingState(); // render capping plane using the generated stencil mask glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -135,6 +138,9 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks glEnable (GL_DEPTH_TEST); RenderPlane (theWorkspace, aRenderPlane); + + aContext->ShaderManager()->RevertClippingState(); + aContext->ShaderManager()->RevertClippingState(); } // restore previous application state diff --git a/src/OpenGl/OpenGl_Clipping.hxx b/src/OpenGl/OpenGl_Clipping.hxx index b59022162d..b88979a5a0 100755 --- a/src/OpenGl/OpenGl_Clipping.hxx +++ b/src/OpenGl/OpenGl_Clipping.hxx @@ -173,18 +173,6 @@ public: //! @name Short-cuts add (theGlCtx, EquationCoords_World, thePlanes); } - //! Add planes to the context clipping at the world system of coordinates. - //! If the number of the passed planes exceeds capabilities of OpenGl, the last planes - //! are simply ignored. - //! @param thePlanes [in/out] the list of planes to be added - //! The list then provides information on which planes were really added to clipping state. - //! This list then can be used to fall back to previous state. - inline void AddWorldLazy (const Handle(OpenGl_Context)& theGlCtx, - Graphic3d_SequenceOfHClipPlane& thePlanes) - { - addLazy (theGlCtx, EquationCoords_World, thePlanes); - } - //! Remove all of the planes from context state. inline void RemoveAll (const Handle(OpenGl_Context)& theGlCtx) { diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index c999a28735..7fb2266505 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -228,7 +228,7 @@ const char THE_FRAG_CLIP_PLANES[] = EOL" int aClipSpace = occClipPlaneSpaces[aPlaneIter];" EOL" if (aClipSpace == OccEquationCoords_World)" EOL" {" - EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0)" + EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)" EOL" {" EOL" discard;" EOL" }" diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index f20c254a26..a0eca72694 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -558,10 +558,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes); // Set OCCT state uniform variables - if (!aCtx->ShaderManager()->IsEmpty()) - { - aCtx->ShaderManager()->UpdateClippingState(); - } + aCtx->ShaderManager()->UpdateClippingState(); } // Render groups @@ -587,10 +584,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes); // Set OCCT state uniform variables - if (!aCtx->ShaderManager()->IsEmpty()) - { - aCtx->ShaderManager()->RevertClippingState(); - } + aCtx->ShaderManager()->RevertClippingState(); } // Restore local transformation diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index 78af8c705f..c5f48768d9 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -922,10 +922,6 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection, #endif aManager->SetShadingModel (myShadingModel); - if (!aManager->IsEmpty()) - { - aManager->UpdateClippingState(); - } // Redraw 3d scene if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye) @@ -954,17 +950,11 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection, // before drawing auxiliary stuff (trihedrons, overlayer) myWorkspace->ResetAppliedAspect(); - aContext->ChangeClipping().RemoveAll (aContext); - if (!aManager->IsEmpty()) - { - aManager->RevertClippingState(); - - // We need to disable (unbind) all shaders programs to ensure - // that all objects without specified aspect will be drawn - // correctly (such as background) - aContext->BindProgram (NULL); - } + // We need to disable (unbind) all shaders programs to ensure + // that all objects without specified aspect will be drawn + // correctly (such as background) + aContext->BindProgram (NULL); // Render trihedron if (!theToDrawImmediate) @@ -1192,6 +1182,8 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection, // add planes at loaded view matrix state aContext->ChangeClipping().AddView (aContext, aSlicingPlanes); } + + aContext->ShaderManager()->UpdateClippingState(); } #ifdef _WIN32 @@ -1221,13 +1213,10 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection, if (!aUserPlanes.IsEmpty()) { - aContext->ChangeClipping().AddWorldLazy (aContext, aUserPlanes); + aContext->ChangeClipping().AddWorld (aContext, aUserPlanes); } - if (!aContext->ShaderManager()->IsEmpty()) - { - aContext->ShaderManager()->UpdateClippingState(); - } + aContext->ShaderManager()->UpdateClippingState(); } #if !defined(GL_ES_VERSION_2_0) @@ -1314,6 +1303,16 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection, // Apply restored view matrix. aContext->ApplyWorldViewMatrix(); + aContext->ChangeClipping().RemoveAll (aContext); + if (!myClipPlanes.IsEmpty()) + { + aContext->ShaderManager()->RevertClippingState(); + } + if (myZClip.Back.IsOn || myZClip.Front.IsOn) + { + aContext->ShaderManager()->RevertClippingState(); + } + #ifdef _WIN32 // set printing scale/tiling transformation if (!aPrintContext.IsNull()) diff --git a/src/Shaders/PhongShading.fs b/src/Shaders/PhongShading.fs index bdcd58c62b..d7fb9b2934 100755 --- a/src/Shaders/PhongShading.fs +++ b/src/Shaders/PhongShading.fs @@ -182,7 +182,7 @@ void main() int aClipSpace = occClipPlaneSpaces[anIndex]; if (aClipSpace == OccEquationCoords_World) { - if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0) + if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0) { discard; } diff --git a/tests/bugs/vis/bug24224 b/tests/bugs/vis/bug24224 index 05b78e3e6b..8ba33feb3b 100644 --- a/tests/bugs/vis/bug24224 +++ b/tests/bugs/vis/bug24224 @@ -18,10 +18,8 @@ set y2_coord 320 set x3_coord 73 set y3_coord 150 -# enable FFP until bug-fix for GLSL -vcaps -ffp 1 - -vinit +vclear +vinit View1 box b1 0 0 0 10 10 10 box b2 30 0 0 10 40 10 box b3 -30 0 0 20 20 20 @@ -53,6 +51,3 @@ vclipplane set pln2 object b3 checkcolor $x3_coord $y3_coord 0.5 0.5 0.9 checkview -screenshot -3d -path ${imagedir}/${test_image}.png - - -