0030713: Visualization, TKOpenGl - stipple line artifacts on Intel UHD Graphics 630
authormnv <mnv@opencascade.com>
Thu, 16 May 2019 06:28:28 +0000 (09:28 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 20 May 2019 08:19:41 +0000 (11:19 +0300)
Added workaround for dashed line presentation on Intel UHD Graphics 630.

src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
tests/bugs/vis/bug30713 [new file with mode: 0644]

index f431e1d..9dcdbc2 100644 (file)
@@ -628,16 +628,11 @@ void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldVi
 }
 
 // =======================================================================
-// function : PushLightSourceState
-// purpose  : Pushes state of OCCT light sources to the program
+// function : pushLightSourceState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -800,16 +795,11 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
 }
 
 // =======================================================================
-// function : PushProjectionState
-// purpose  : Pushes state of OCCT projection transform to the program
+// function : pushProjectionState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -845,16 +835,11 @@ void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgra
 }
 
 // =======================================================================
-// function : PushModelWorldState
-// purpose  : Pushes state of OCCT model-world transform to the program
+// function : pushModelWorldState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -892,10 +877,10 @@ void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgra
 }
 
 // =======================================================================
-// function : PushWorldViewState
-// purpose  : Pushes state of OCCT world-view transform to the program
+// function : pushWorldViewState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
   if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
   {
@@ -957,16 +942,11 @@ void OpenGl_ShaderManager::RevertClippingState()
 }
 
 // =======================================================================
-// function : PushClippingState
-// purpose  : Pushes state of OCCT clipping planes to the program
+// function : pushClippingState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -1136,16 +1116,11 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
 }
 
 // =======================================================================
-// function : PushMaterialState
+// function : pushMaterialState
 // purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myMaterialState.Index() == theProgram->ActiveState (OpenGl_MATERIAL_STATE))
-  {
-    return;
-  }
-
   const OpenGl_Material& aFrontMat = myMaterialState.FrontMaterial();
   const OpenGl_Material& aBackMat  = myMaterialState.BackMaterial();
   theProgram->UpdateState (OpenGl_MATERIAL_STATE, myMaterialState.Index());
@@ -1208,21 +1183,11 @@ void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)
 }
 
 // =======================================================================
-// function : PushOitState
-// purpose  : Pushes state of OIT uniforms to the specified program
+// function : pushOitState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (!theProgram->IsValid())
-  {
-    return;
-  }
-
-  if (myOitState.Index() == theProgram->ActiveState (OpenGL_OIT_STATE))
-  {
-    return;
-  }
-
   const GLint aLocOutput = theProgram->GetStateLocation (OpenGl_OCCT_OIT_OUTPUT);
   if (aLocOutput != OpenGl_ShaderProgram::INVALID_LOCATION)
   {
@@ -1249,10 +1214,6 @@ void OpenGl_ShaderManager::PushInteriorState (const Handle(OpenGl_ShaderProgram)
     return;
   }
 
-  if (const OpenGl_ShaderUniformLocation aLocViewPort = theProgram->GetStateLocation (OpenGl_OCCT_VIEWPORT))
-  {
-    theProgram->SetUniform (myContext, aLocViewPort, OpenGl_Vec4 ((float )myContext->Viewport()[0], (float )myContext->Viewport()[1], (float )myContext->Viewport()[2], (float )myContext->Viewport()[3]));
-  }
   if (const OpenGl_ShaderUniformLocation aLocLineWidth = theProgram->GetStateLocation (OpenGl_OCCT_LINE_WIDTH))
   {
     theProgram->SetUniform (myContext, aLocLineWidth, theAspect->EdgeWidth() * myContext->LineWidthScale());
@@ -1289,6 +1250,15 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
   PushLightSourceState (aProgram);
   PushMaterialState    (aProgram);
   PushOitState         (aProgram);
+
+  if (!theProgram.IsNull())
+  {
+    if (const OpenGl_ShaderUniformLocation& aLocViewPort = theProgram->GetStateLocation (OpenGl_OCCT_VIEWPORT))
+    {
+      theProgram->SetUniform (myContext, aLocViewPort, OpenGl_Vec4 ((float )myContext->Viewport()[0], (float )myContext->Viewport()[1],
+                                                                    (float )myContext->Viewport()[2], (float )myContext->Viewport()[3]));
+    }
+  }
 }
 
 // =======================================================================
@@ -1851,12 +1821,23 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     {
       aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int   uPattern", Graphic3d_TOS_FRAGMENT));
       aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("float uFactor",  Graphic3d_TOS_FRAGMENT));
+      aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 occViewport", Graphic3d_TOS_VERTEX));
       aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 ScreenSpaceCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
       aSrcVertEndMain =
-        EOL"  ScreenSpaceCoord = gl_Position.xy / gl_Position.w;";
+        EOL"  vec2 aPosition   = gl_Position.xy / gl_Position.w;"
+        EOL"  aPosition        = aPosition * 0.5 + 0.5;"
+        EOL"  ScreenSpaceCoord = aPosition.xy * occViewport.zw + occViewport.xy;";
       aSrcFragMainGetColor =
-        EOL"  float anAngle      = atan (dFdx (ScreenSpaceCoord.x), dFdy (ScreenSpaceCoord.y));"
-        EOL"  float aRotatePoint = gl_FragCoord.x * sin (anAngle) + gl_FragCoord.y * cos (anAngle);"
+        EOL"  vec2 anAxis = vec2 (0.0);"
+        EOL"  if (abs (dFdx (ScreenSpaceCoord.x)) - abs (dFdy (ScreenSpaceCoord.y)) > 0.001)" 
+        EOL"  {"
+        EOL"    anAxis = vec2 (1.0, 0.0);"
+        EOL"  }"
+        EOL"  else"
+        EOL"  {"
+        EOL"    anAxis = vec2 (0.0, 1.0);"
+        EOL"  }"
+        EOL"  float aRotatePoint = dot (gl_FragCoord.xy, anAxis);"
         EOL"  uint  aBit         = uint (floor (aRotatePoint / uFactor + 0.5)) & 15U;"
         EOL"  if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
         EOL"  vec4 aColor = getFinalColor();"
index 5599136..6a00b7e 100644 (file)
@@ -250,8 +250,17 @@ public:
   //! Invalidate state of OCCT light sources.
   Standard_EXPORT void UpdateLightSourceState();
 
+  //! Pushes current state of OCCT light sources to specified program (only on state change).
+  void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (myLightSourceState.Index() != theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
+    {
+      pushLightSourceState (theProgram);
+    }
+  }
+
   //! Pushes current state of OCCT light sources to specified program.
-  Standard_EXPORT void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  Standard_EXPORT void pushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
@@ -261,8 +270,17 @@ public:
   //! Updates state of OCCT projection transform.
   Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix);
 
+  //! Pushes current state of OCCT projection transform to specified program (only on state change).
+  void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (myProjectionState.Index() != theProgram->ActiveState (OpenGl_PROJECTION_STATE))
+    {
+      pushProjectionState (theProgram);
+    }
+  }
+
   //! Pushes current state of OCCT projection transform to specified program.
-  Standard_EXPORT void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  Standard_EXPORT void pushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
@@ -272,8 +290,17 @@ public:
   //! Updates state of OCCT model-world transform.
   Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix);
 
+  //! Pushes current state of OCCT model-world transform to specified program (only on state change).
+  void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (myModelWorldState.Index() != theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
+    {
+      pushModelWorldState (theProgram);
+    }
+  }
+
   //! Pushes current state of OCCT model-world transform to specified program.
-  Standard_EXPORT void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  Standard_EXPORT void pushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
@@ -283,8 +310,17 @@ public:
   //! Updates state of OCCT world-view transform.
   Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix);
 
+  //! Pushes current state of OCCT world-view transform to specified program (only on state change).
+  void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (myWorldViewState.Index() != theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
+    {
+      pushWorldViewState (theProgram);
+    }
+  }
+
   //! Pushes current state of OCCT world-view transform to specified program.
-  Standard_EXPORT void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  Standard_EXPORT void pushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
@@ -294,8 +330,17 @@ public:
   //! Reverts state of OCCT clipping planes.
   Standard_EXPORT void RevertClippingState();
 
+  //! Pushes current state of OCCT clipping planes to specified program (only on state change).
+  void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (myClippingState.Index() != theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
+    {
+      pushClippingState (theProgram);
+    }
+  }
+
   //! Pushes current state of OCCT clipping planes to specified program.
-  Standard_EXPORT void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  Standard_EXPORT void pushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
@@ -319,8 +364,17 @@ public:
     myMaterialState.Update();
   }
 
+  //! Pushes current state of material to specified program (only on state change).
+  void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (myMaterialState.Index() != theProgram->ActiveState (OpenGl_MATERIAL_STATE))
+    {
+      pushMaterialState (theProgram);
+    }
+  }
+
   //! Pushes current state of material to specified program.
-  void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  Standard_EXPORT void pushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
@@ -333,7 +387,7 @@ public:
   //! Returns state of OIT uniforms.
   const OpenGl_OitState& OitState() const { return myOitState; }
 
-  //! Set the state of OIT rendering pass.
+  //! Set the state of OIT rendering pass (only on state change).
   //! @param theToEnableOitWrite [in] flag indicating whether the special output should be written for OIT algorithm.
   //! @param theDepthFactor [in] the scalar factor of depth influence to the fragment's coverage.
   void SetOitState (const bool theToEnableOitWrite, const float theDepthFactor)
@@ -343,7 +397,17 @@ public:
   }
 
   //! Pushes state of OIT uniforms to the specified program.
-  Standard_EXPORT void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+  void PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+  {
+    if (theProgram->IsValid()
+     && myOitState.Index() != theProgram->ActiveState (OpenGL_OIT_STATE))
+    {
+      pushOitState (theProgram);
+    }
+  }
+
+  //! Pushes state of OIT uniforms to the specified program.
+  Standard_EXPORT void pushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
 public:
 
diff --git a/tests/bugs/vis/bug30713 b/tests/bugs/vis/bug30713
new file mode 100644 (file)
index 0000000..f3f888f
--- /dev/null
@@ -0,0 +1,19 @@
+puts "============="
+puts "0030713: Visualization, TKOpenGl - stipple line artifacts on Intel UHD Graphics 630"
+puts "============="
+
+pload MODELING VISUALIZATION
+box b 1 2 3
+vclear
+vcaps -core
+vinit View1
+vglinfo
+vdisplay -dispMode 0 b
+vtop
+vfit
+vzoom 0.8
+vaspects b -lineType DASH
+vrotate 0 0 0.785
+vfit
+
+vdump ${imagedir}/${casename}.png