From 8d1a539c4a8c8d59852174d6de0928aedaf8251b Mon Sep 17 00:00:00 2001 From: kgv Date: Mon, 4 Dec 2017 16:29:43 +0300 Subject: [PATCH] 0029366: Visualization, OpenGl_Text - artifacts when using Aspect_TODT_SHADOW/Aspect_TODT_DEKALE at different zoom level OpenGl_Text now applies Polygon Offset instead of Z-shift in world coordinates for drawing background. OpenGl_Context::SetPolygonOffset() - polygon offset state has been moved from OpenGl_Workspace to OpenGl_Context. --- src/OpenGl/OpenGl_Context.cxx | 62 ++++++++++++++++++++++++++++++ src/OpenGl/OpenGl_Context.hxx | 7 ++++ src/OpenGl/OpenGl_Layer.cxx | 8 ++-- src/OpenGl/OpenGl_Text.cxx | 67 +++++++++++++++++++++++++-------- src/OpenGl/OpenGl_Workspace.cxx | 48 +---------------------- src/OpenGl/OpenGl_Workspace.hxx | 8 ---- 6 files changed, 126 insertions(+), 74 deletions(-) diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 494ae5cdda..fdafc5484d 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -207,6 +207,10 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) myViewportVirt[2] = 0; myViewportVirt[3] = 0; + myPolygonOffset.Mode = Aspect_POM_Off; + myPolygonOffset.Factor = 0.0f; + myPolygonOffset.Units = 0.0f; + // system-dependent fields #if defined(HAVE_EGL) myDisplay = (Aspect_Display )EGL_NO_DISPLAY; @@ -3558,6 +3562,64 @@ Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_Ha return myHatchStyles->SetTypeOfHatch (this, theStyle); } +// ======================================================================= +// function : SetPolygonOffset +// purpose : +// ======================================================================= +void OpenGl_Context::SetPolygonOffset (const Graphic3d_PolygonOffset& theOffset) +{ + const bool toFillOld = (myPolygonOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill; + const bool toFillNew = (theOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill; + if (toFillNew != toFillOld) + { + if (toFillNew) + { + glEnable (GL_POLYGON_OFFSET_FILL); + } + else + { + glDisable (GL_POLYGON_OFFSET_FILL); + } + } + +#if !defined(GL_ES_VERSION_2_0) + const bool toLineOld = (myPolygonOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line; + const bool toLineNew = (theOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line; + if (toLineNew != toLineOld) + { + if (toLineNew) + { + glEnable (GL_POLYGON_OFFSET_LINE); + } + else + { + glDisable (GL_POLYGON_OFFSET_LINE); + } + } + + const bool toPointOld = (myPolygonOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point; + const bool toPointNew = (theOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point; + if (toPointNew != toPointOld) + { + if (toPointNew) + { + glEnable (GL_POLYGON_OFFSET_POINT); + } + else + { + glDisable (GL_POLYGON_OFFSET_POINT); + } + } +#endif + + if (myPolygonOffset.Factor != theOffset.Factor + || myPolygonOffset.Units != theOffset.Units) + { + glPolygonOffset (theOffset.Factor, theOffset.Units); + } + myPolygonOffset = theOffset; +} + // ======================================================================= // function : ApplyModelWorldMatrix // purpose : diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index b2f01c6afb..353aa8de48 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -543,6 +543,12 @@ public: //! @return old type of hatch. Standard_EXPORT Standard_Integer SetPolygonHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle); + //! Sets and applies current polygon offset. + Standard_EXPORT void SetPolygonOffset (const Graphic3d_PolygonOffset& theOffset); + + //! Returns currently applied polygon offset parameters. + const Graphic3d_PolygonOffset& PolygonOffset() const { return myPolygonOffset; } + //! Applies matrix stored in ModelWorldState to OpenGl. Standard_EXPORT void ApplyModelWorldMatrix(); @@ -917,6 +923,7 @@ private: //! @name fields tracking current state Standard_Integer myPointSpriteOrig; //!< GL_POINT_SPRITE_COORD_ORIGIN state (GL_UPPER_LEFT by default) Standard_Integer myRenderMode; //!< value for active rendering mode Standard_Integer myPolygonMode; //!< currently used polygon rasterization mode (glPolygonMode) + Graphic3d_PolygonOffset myPolygonOffset; //!< currently applied polygon offset bool myToCullBackFaces; //!< back face culling mode enabled state (glIsEnabled (GL_CULL_FACE)) Standard_Integer myReadBuffer; //!< current read buffer OpenGl_DrawBuffers myDrawBuffers; //!< current draw buffers diff --git a/src/OpenGl/OpenGl_Layer.cxx b/src/OpenGl/OpenGl_Layer.cxx index 4f768116c0..2879617c10 100644 --- a/src/OpenGl/OpenGl_Layer.cxx +++ b/src/OpenGl/OpenGl_Layer.cxx @@ -651,7 +651,8 @@ void OpenGl_Layer::SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_GlobalLayerSettings& theDefaultSettings) const { - const Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->AppliedPolygonOffset(); + const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); + const Graphic3d_PolygonOffset anAppliedOffsetParams = aCtx->PolygonOffset(); // myLayerSettings.ToClearDepth() is handled outside // handle depth test @@ -673,14 +674,13 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, } // handle depth offset - theWorkspace->SetPolygonOffset (myLayerSettings.PolygonOffset()); + aCtx->SetPolygonOffset (myLayerSettings.PolygonOffset()); // handle depth write theWorkspace->UseDepthWrite() = myLayerSettings.ToEnableDepthWrite() && theDefaultSettings.DepthMask == GL_TRUE; glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE); const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull(); - const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources(); const bool hasOwnLights = aCtx->ColorMask() && !myLayerSettings.Lights().IsNull() && myLayerSettings.Lights() != aLightsBack; @@ -755,7 +755,7 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, } // always restore polygon offset between layers rendering - theWorkspace->SetPolygonOffset (anAppliedOffsetParams); + aCtx->SetPolygonOffset (anAppliedOffsetParams); // restore environment texture if (!myLayerSettings.UseEnvironmentTexture()) diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index eb09e0a657..132f5a90a5 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -138,6 +138,38 @@ namespace } #endif + //! Auxiliary tool for setting polygon offset temporarily. + struct BackPolygonOffsetSentry + { + BackPolygonOffsetSentry (const Handle(OpenGl_Context)& theCtx) + : myCtx (theCtx), + myOffsetBack (!theCtx.IsNull() ? theCtx->PolygonOffset() : Graphic3d_PolygonOffset()) + { + if (!theCtx.IsNull()) + { + Graphic3d_PolygonOffset aPolyOffset = myOffsetBack; + aPolyOffset.Mode = Aspect_POM_Fill; + aPolyOffset.Units += 1.0f; + theCtx->SetPolygonOffset (aPolyOffset); + } + } + + ~BackPolygonOffsetSentry() + { + if (!myCtx.IsNull()) + { + myCtx->SetPolygonOffset (myOffsetBack); + } + } + + private: + BackPolygonOffsetSentry (const BackPolygonOffsetSentry& ); + BackPolygonOffsetSentry& operator= (const BackPolygonOffsetSentry& ); + private: + const Handle(OpenGl_Context)& myCtx; + const Graphic3d_PolygonOffset myOffsetBack; + }; + } // anonymous namespace // ======================================================================= @@ -424,10 +456,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const const OpenGl_AspectText* aTextAspect = theWorkspace->ApplyAspectText(); const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)()); -#if !defined(GL_ES_VERSION_2_0) - const Standard_Integer aPrevPolygonMode = aCtx->SetPolygonMode (GL_FILL); - const bool aPrevHatchingMode = aCtx->SetPolygonHatchEnabled (false); -#endif + // Bind custom shader program or generate default version aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx)); @@ -447,10 +476,6 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const { aCtx->BindTextures (aPrevTexture); } -#if !defined(GL_ES_VERSION_2_0) - aCtx->SetPolygonMode (aPrevPolygonMode); - aCtx->SetPolygonHatchEnabled (aPrevHatchingMode); -#endif // restore Z buffer settings if (theWorkspace->UseZBuffer()) @@ -743,7 +768,7 @@ void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx, } #endif theCtx->SetColor4fv (theColorSubs); - setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f)); + setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f)); myBndVertsVbo->BindAttribute (theCtx, Graphic3d_TOA_POS); theCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); @@ -854,11 +879,15 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx, { glDisable (GL_LIGHTING); } + + const Standard_Integer aPrevPolygonMode = theCtx->SetPolygonMode (GL_FILL); + const bool aPrevHatchingMode = theCtx->SetPolygonHatchEnabled (false); #endif // setup depth test - if (myIs2d - || theTextAspect.Aspect()->Style() == Aspect_TOST_ANNOTATION) + const bool hasDepthTest = !myIs2d + && theTextAspect.Aspect()->Style() != Aspect_TOST_ANNOTATION; + if (!hasDepthTest) { glDisable (GL_DEPTH_TEST); } @@ -903,26 +932,29 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx, } case Aspect_TODT_SUBTITLE: { + BackPolygonOffsetSentry aPolygonOffsetTmp (hasDepthTest ? theCtx : Handle(OpenGl_Context)()); drawRect (theCtx, theTextAspect, theColorSubs); break; } case Aspect_TODT_DEKALE: { + BackPolygonOffsetSentry aPolygonOffsetTmp (hasDepthTest ? theCtx : Handle(OpenGl_Context)()); theCtx->SetColor4fv (theColorSubs); - setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f)); + setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.0f)); drawText (theCtx, theTextAspect); - setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f)); + setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.0f)); drawText (theCtx, theTextAspect); - setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f)); + setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.0f)); drawText (theCtx, theTextAspect); - setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f)); + setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.0f)); drawText (theCtx, theTextAspect); break; } case Aspect_TODT_SHADOW: { + BackPolygonOffsetSentry aPolygonOffsetTmp (hasDepthTest ? theCtx : Handle(OpenGl_Context)()); theCtx->SetColor4fv (theColorSubs); - setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f)); + setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.0f)); drawText (theCtx, theTextAspect); break; } @@ -988,6 +1020,9 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx, glDisable (GL_ALPHA_TEST); } glDisable (GL_COLOR_LOGIC_OP); + + theCtx->SetPolygonMode (aPrevPolygonMode); + theCtx->SetPolygonHatchEnabled (aPrevHatchingMode); #endif // model view matrix was modified diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 6f20f3cc27..cace5f4cd4 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -220,7 +220,7 @@ void OpenGl_Workspace::ResetAppliedAspect() myAspectMarkerSet = &myDefaultAspectMarker; myAspectMarkerApplied.Nullify(); myAspectTextSet = &myDefaultAspectText; - myPolygonOffsetApplied= Graphic3d_PolygonOffset(); + myGlContext->SetPolygonOffset (Graphic3d_PolygonOffset()); ApplyAspectLine(); ApplyAspectFace(); @@ -355,12 +355,7 @@ const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace() // Aspect_POM_None means: do not change current settings if ((myAspectFaceSet->Aspect()->PolygonOffset().Mode & Aspect_POM_None) != Aspect_POM_None) { - if (myPolygonOffsetApplied.Mode != myAspectFaceSet->Aspect()->PolygonOffset().Mode - || myPolygonOffsetApplied.Factor != myAspectFaceSet->Aspect()->PolygonOffset().Factor - || myPolygonOffsetApplied.Units != myAspectFaceSet->Aspect()->PolygonOffset().Units) - { - SetPolygonOffset (myAspectFaceSet->Aspect()->PolygonOffset()); - } + myGlContext->SetPolygonOffset (myAspectFaceSet->Aspect()->PolygonOffset()); } // Case of hidden line @@ -391,45 +386,6 @@ const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace() return myAspectFaceSet; } -//======================================================================= -//function : SetPolygonOffset -//purpose : -//======================================================================= -void OpenGl_Workspace::SetPolygonOffset (const Graphic3d_PolygonOffset& theParams) -{ - myPolygonOffsetApplied = theParams; - - if ((theParams.Mode & Aspect_POM_Fill) == Aspect_POM_Fill) - { - glEnable (GL_POLYGON_OFFSET_FILL); - } - else - { - glDisable (GL_POLYGON_OFFSET_FILL); - } - -#if !defined(GL_ES_VERSION_2_0) - if ((theParams.Mode & Aspect_POM_Line) == Aspect_POM_Line) - { - glEnable (GL_POLYGON_OFFSET_LINE); - } - else - { - glDisable (GL_POLYGON_OFFSET_LINE); - } - - if ((theParams.Mode & Aspect_POM_Point) == Aspect_POM_Point) - { - glEnable (GL_POLYGON_OFFSET_POINT); - } - else - { - glDisable (GL_POLYGON_OFFSET_POINT); - } -#endif - glPolygonOffset (theParams.Factor, theParams.Units); -} - // ======================================================================= // function : ApplyAspectMarker // purpose : diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index 7b1648f40a..0a59ff01c1 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -257,12 +257,6 @@ public: //! @return applied model structure matrix. inline const OpenGl_Matrix* ModelMatrix() const { return StructureMatrix_applied; } - //! Sets and applies current polygon offset. - void SetPolygonOffset (const Graphic3d_PolygonOffset& theParams); - - //! Returns currently applied polygon offset parameters. - const Graphic3d_PolygonOffset& AppliedPolygonOffset() { return myPolygonOffsetApplied; } - //! Returns capping algorithm rendering filter. const Handle(OpenGl_CappingAlgoFilter)& DefaultCappingAlgoFilter() const { @@ -317,8 +311,6 @@ protected: //! @name fields related to status OpenGl_Matrix myModelViewMatrix; //!< Model matrix with applied structure transformations - Graphic3d_PolygonOffset myPolygonOffsetApplied; //!< currently applied polygon offset - OpenGl_AspectFace myAspectFaceHl; //!< Hiddenline aspect Handle(OpenGl_TextureSet) myEnvironmentTexture;