]> OCCT Git - occt-copy.git/commitdiff
0024437: Efficient HLR visualization based on OpenGL and GLSL
authorasl <asl@opencascade.com>
Thu, 17 May 2018 13:10:30 +0000 (16:10 +0300)
committerasl <asl@opencascade.com>
Thu, 6 Dec 2018 14:17:51 +0000 (17:17 +0300)
New interior style Aspect_IS_OUTLINE is supported for Graphic3d_AspectFillArea3d.
If this style is set, the triangles primitive array is drawn using the outline shader

src/Aspect/Aspect_InteriorStyle.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_Text.cxx
src/ViewerTest/ViewerTest.cxx
tests/bugs/vis/bug24437 [new file with mode: 0644]

index e69a2589f2bd64ebae9682ef2c681c16fc5f9e6c..b197970e3949e13969fad17921ec578f05773644 100644 (file)
@@ -32,7 +32,8 @@ Aspect_IS_HOLLOW,
 Aspect_IS_HATCH,
 Aspect_IS_SOLID,
 Aspect_IS_HIDDENLINE,
-Aspect_IS_POINT
+Aspect_IS_POINT,
+Aspect_IS_OUTLINE
 };
 
 #endif // _Aspect_InteriorStyle_HeaderFile
index 125102fe7582c58ccaf67bbf9da5ea4d6121d95d..91a832cf00e45cfd326a4488574d03ee36a81f61 100644 (file)
@@ -33,6 +33,7 @@
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_AspectFace.hxx>
+#include <OpenGl_View.hxx>
 #include <Graphic3d_TransformUtils.hxx>
 #include <Graphic3d_RenderingParams.hxx>
 
@@ -3449,6 +3450,79 @@ void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
 #endif
 }
 
+// =======================================================================
+// function : PushOrthoScale
+// purpose  :
+// =======================================================================
+void OpenGl_Context::PushOrthoScale (const Handle(OpenGl_Workspace)& theWorkspace)
+{
+  if (!myActiveProgram.IsNull() && !theWorkspace.IsNull())
+  {
+    Standard_ShortReal aScale = (Standard_ShortReal)theWorkspace->View()->Camera()->Scale();
+    myActiveProgram->SetUniform(this, myActiveProgram->GetStateLocation(OpenGl_OCCT_ORTHO_SCALE), aScale);
+  }
+}
+
+// =======================================================================
+// function : SetIsSilhouettePass
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetIsSilhouettePass (Standard_Boolean isSilhouettePass)
+{
+  if (!myActiveProgram.IsNull() )
+  {
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_IS_SILHOUETTE_PASS),
+      isSilhouettePass ? 1.0f : 0.0f);
+  }
+}
+
+// =======================================================================
+// function : PushBackgroundColor
+// purpose  :
+// =======================================================================
+void OpenGl_Context::PushBackgroundColor (const Handle(OpenGl_Workspace)& theWorkspace)
+{
+  if (!myActiveProgram.IsNull() && !theWorkspace.IsNull())
+  {
+    const Quantity_Color& aBackground = theWorkspace->View()->BackgroundColor().GetRGB();
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_BACKGROUND_COLOR), 
+      OpenGl_Vec3((Standard_ShortReal)aBackground.Red(),
+                  (Standard_ShortReal)aBackground.Green(),
+                  (Standard_ShortReal)aBackground.Blue()));
+  }
+}
+
+// =======================================================================
+// function : SetSilhouetteColor
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetSilhouetteColor (const Quantity_Color& theColor)
+{
+  if (!myActiveProgram.IsNull())
+  {
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_SILHOUETTE_COLOR),
+      OpenGl_Vec3((Standard_ShortReal)theColor.Red(),
+                  (Standard_ShortReal)theColor.Green(),
+                  (Standard_ShortReal)theColor.Blue()));
+  }
+}
+
+// =======================================================================
+// function : SetSilhouetteThickness
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetSilhouetteThickness (Standard_ShortReal theThickness)
+{
+  if (!myActiveProgram.IsNull())
+  {
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_SILHOUETTE_THICKNESS), theThickness);
+  }
+}
+
 // =======================================================================
 // function : SetPointSpriteOrigin
 // purpose  :
index 13bf652ba2d1db3ce3306261981269b9e508d57a..58f65a8a2366309e659b143f8ce43c9274314280 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <NCollection_Shared.hxx>
 
+class OpenGl_Workspace;
+
 //! Forward declarations
 #if defined(__APPLE__)
   #import <TargetConditionals.h>
@@ -735,6 +737,12 @@ public: //! @name methods to alter or retrieve current state
   //! Setup texture matrix to active GLSL program or to FFP global state using glMatrixMode (GL_TEXTURE).
   Standard_EXPORT void SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams);
 
+  Standard_EXPORT void PushOrthoScale (const Handle(OpenGl_Workspace)& theWorkspace);
+  Standard_EXPORT void SetIsSilhouettePass (Standard_Boolean);
+  Standard_EXPORT void PushBackgroundColor (const Handle(OpenGl_Workspace)& theWorkspace);
+  Standard_EXPORT void SetSilhouetteColor (const Quantity_Color&);
+  Standard_EXPORT void SetSilhouetteThickness (Standard_ShortReal);
+
   //! Bind default Vertex Array Object
   Standard_EXPORT void BindDefaultVao();
 
index 8986de7bb62d54e8fd92c4dab644c4136671f455..77e8514fd489786c31bc766655f9ab118113e8a0 100644 (file)
@@ -24,6 +24,7 @@
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_VertexBufferCompat.hxx>
+#include <OpenGl_View.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Graphic3d_TextureParams.hxx>
 #include <NCollection_AlignedAllocator.hxx>
@@ -870,7 +871,39 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
                                                 anAspectFace->Aspect()->AlphaMode(),
                                                 hasVertColor,
                                                 toEnableEnvMap,
-                                                anAspectFace->ShaderProgramRes (aCtx));
+                                                anAspectFace->ShaderProgramRes (aCtx),
+                                                anAspectFace->Aspect()->InteriorStyle());
+
+        if (anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_OUTLINE)
+        {
+          const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_HIDDENLINE
+            ? myBounds->Colors
+            : NULL;
+
+          aCtx->PushOrthoScale(theWorkspace);
+          aCtx->PushBackgroundColor(theWorkspace);
+          aCtx->SetSilhouetteColor(anAspectFace->Aspect()->EdgeColor());
+
+          Standard_Integer aViewWidth, aViewHeight;
+          theWorkspace->View()->Window()->Size(aViewWidth, aViewHeight);
+          Standard_Integer aMin = aViewWidth < aViewHeight ? aViewWidth : aViewHeight;
+
+          Standard_ShortReal anEdgeWidth = (Standard_ShortReal)anAspectFace->Aspect()->EdgeWidth() / (Standard_ShortReal)aMin;
+          aCtx->SetSilhouetteThickness(anEdgeWidth);
+
+          aCtx->SetIsSilhouettePass(Standard_True);
+          GLboolean isCull = glIsEnabled(GL_CULL_FACE);
+          glEnable(GL_CULL_FACE);
+          glCullFace(GL_FRONT);
+          drawArray(theWorkspace, aFaceColors, hasColorAttrib);
+
+          aCtx->SetIsSilhouettePass(Standard_False);
+          glCullFace(GL_BACK);
+          drawArray(theWorkspace, aFaceColors, hasColorAttrib);
+
+          if (!isCull)
+            glDisable(GL_CULL_FACE);
+        }
         break;
       }
     }
@@ -928,8 +961,9 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
   }
   else
   {
-    if (anAspectFace->Aspect()->ToDrawEdges()
-     || anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
+    if ((anAspectFace->Aspect()->ToDrawEdges()
+        || anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
+        && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_OUTLINE)
     {
       const OpenGl_Vec4& anEdgeColor = theWorkspace->EdgeColor();
       drawEdges (anEdgeColor, theWorkspace);
@@ -1086,3 +1120,4 @@ void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)&        th
 
   setDrawMode (theType);
 }
+
index 6ff6c20b6fef25cfe0793633c1ec124a46566a52..3f595d6925c23f4ce4b3651e30d72c58cbda6cb3 100644 (file)
@@ -1655,12 +1655,57 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     }
   }
 
+  if ((theBits & OpenGl_PO_OUTLINE) != 0)
+  {
+    aSrcVertExtraOut +=
+      EOL"uniform float occOrthoScale;"
+      EOL"uniform float occIsSilhouettePass;"
+      EOL"uniform float occSilhouetteThickness;"
+      EOL""
+      EOL"THE_SHADER_IN  vec4 normal;"
+      ;
+
+    aSrcVertExtraMain +=
+      EOL"  vec3 delta = vec3(0.0, 0.0, 0.0);"
+      EOL"  if (occIsSilhouettePass > 0.1)"
+      EOL"  {"
+      EOL"    float aShift = occSilhouetteThickness;"
+      EOL"    if (occOrthoScale > 0.0)"
+      EOL"    {"
+      EOL"      aShift *= occOrthoScale;"
+      EOL"      delta = normal.xyz * aShift;"
+      EOL"    }"
+      EOL"    else"
+      EOL"    {"
+      EOL"      vec4 pos = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vertex;"
+      EOL"      delta = normal.xyz * aShift * pos.w;"
+      EOL"    }"
+      EOL"  }"
+      EOL"  vertex += vec4(delta, 0.0);"
+      ;
+
+    aSrcFragExtraOut +=
+      EOL"uniform float occIsSilhouettePass;"
+      EOL"uniform vec3 occBackgroundColor;"
+      EOL"uniform vec3 occSilhouetteColor;"
+      ;
+
+    aSrcFragExtraMain +=
+      EOL"  vec3 aColor = occBackgroundColor;"
+      EOL"  if (occIsSilhouettePass > 0.1)"
+      EOL"    aColor = occSilhouetteColor;"
+      ;
+
+    aSrcFragWriteOit = EOL"  occSetFragColor(vec4(aColor, 1.0));";
+  }
+
   aSrcVert =
       aSrcVertExtraFunc
     + EOL"void main()"
       EOL"{"
+      EOL"  vec4 vertex = occVertex;"
     + aSrcVertExtraMain
-    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vertex;"
     + aSrcVertEndMain
     + EOL"}";
 
index 98b1e6ae4d23781f723faf94bcf60bed854ed993..ddc8392c03766fda41f0534bc68116c65bb8dc5a 100644 (file)
@@ -88,7 +88,8 @@ public:
                                     const Graphic3d_AlphaMode           theAlphaMode,
                                     const Standard_Boolean              theHasVertColor,
                                     const Standard_Boolean              theEnableEnvMap,
-                                    const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+                                    const Handle(OpenGl_ShaderProgram)& theCustomProgram,
+                                    const Aspect_InteriorStyle          theStyle)
   {
     if (!theCustomProgram.IsNull()
      || myContext->caps->ffpEnable)
@@ -100,7 +101,7 @@ public:
                                                         && (theTextures.IsNull() || theTextures->IsModulate())
                                                         ? theShadingModel
                                                         : Graphic3d_TOSM_UNLIT;
-    const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap);
+    const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap, theStyle);
     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits);
     return bindProgramWithState (aProgram);
   }
@@ -415,7 +416,8 @@ protected:
   Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
                                    Graphic3d_AlphaMode theAlphaMode,
                                    Standard_Boolean theHasVertColor,
-                                   Standard_Boolean theEnableEnvMap)
+                                   Standard_Boolean theEnableEnvMap,
+                                   Aspect_InteriorStyle theStyle=Aspect_IS_EMPTY)
 
   {
     Standard_Integer aBits = 0;
@@ -463,6 +465,11 @@ protected:
     {
       aBits |= OpenGl_PO_WriteOit;
     }
+
+    if (theStyle == Aspect_IS_OUTLINE)
+    {
+      aBits |= OpenGl_PO_OUTLINE;
+    }
     return aBits;
   }
 
@@ -471,7 +478,8 @@ protected:
                                                Standard_Integer theBits)
   {
     if (theShadingModel == Graphic3d_TOSM_UNLIT
-     || (theBits & OpenGl_PO_TextureEnv) != 0)
+     || (theBits & OpenGl_PO_TextureEnv) != 0
+     || (theBits & OpenGl_PO_OUTLINE) != 0)
     {
       // If environment map is enabled lighting calculations are
       // not needed (in accordance with default OCCT behavior)
index 0d665d0057b31dce7144dd358f8ffb16e4a10547..0d69aa10a7c8b829900d8276da345969fbc2f632 100755 (executable)
@@ -75,7 +75,13 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occOitDepthFactor",     // OpenGl_OCCT_OIT_DEPTH_FACTOR
 
   "occTexTrsf2d",          // OpenGl_OCCT_TEXTURE_TRSF2D
-  "occPointSize"           // OpenGl_OCCT_POINT_SIZE
+  "occPointSize",          // OpenGl_OCCT_POINT_SIZE
+
+  "occOrthoScale",         // OpenGl_OCCT_ORTHO_SCALE
+  "occIsSilhouettePass",   // OpenGl_OCCT_IS_SILHOUETTE_PASS
+  "occBackgroundColor",    // OpenGl_OCCT_BACKGROUND_COLOR
+  "occSilhouetteColor",    // OpenGl_OCCT_SILHOUETTE_COLOR
+  "occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
 };
 
 namespace
index 1f15f0133de24d618846d84d37b7e799818853d9..42ff8ff76fecf37cbc715932508c1b9b1620213a 100755 (executable)
@@ -75,6 +75,13 @@ enum OpenGl_StateVariable
   OpenGl_OCCT_TEXTURE_TRSF2D,
   OpenGl_OCCT_POINT_SIZE,
 
+  // Parameters of outline (silhouette) shader
+  OpenGl_OCCT_ORTHO_SCALE,
+  OpenGl_OCCT_IS_SILHOUETTE_PASS,
+  OpenGl_OCCT_BACKGROUND_COLOR,
+  OpenGl_OCCT_SILHOUETTE_COLOR,
+  OpenGl_OCCT_SILHOUETTE_THICKNESS,
+
   // DON'T MODIFY THIS ITEM (insert new items before it)
   OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
 };
index 70cd2fb3a37a4ca36f7f794dae29ad538d9ef0c7..84896b7d211cf0acc0ece854fde9e4d8666b49a9 100644 (file)
@@ -651,7 +651,7 @@ void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
   // bind unlit program
   theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Graphic3d_TOSM_UNLIT,
                                             Graphic3d_AlphaMode_Opaque, Standard_False, Standard_False,
-                                            Handle(OpenGl_ShaderProgram)());
+                                            Handle(OpenGl_ShaderProgram)(), Aspect_IS_SOLID);
 
 #if !defined(GL_ES_VERSION_2_0)
   if (theCtx->core11 != NULL
index 9e03442a2dc88af67d645968fbc429b1716b06c5..9c7716a220d85a1e33dd29dddc3a691efc5fec3b 100644 (file)
@@ -1554,14 +1554,18 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI,
   {
     anInterStyle = Aspect_IS_POINT;
   }
+  else if (aStyleArg == "outline")
+  {
+    anInterStyle = Aspect_IS_OUTLINE;
+  }
   else
   {
     const Standard_Integer anIntStyle = aStyleArg.IntegerValue();
     if (anIntStyle < Aspect_IS_EMPTY
-     || anIntStyle > Aspect_IS_POINT)
+     || anIntStyle > Aspect_IS_OUTLINE)
     {
       std::cout << "Error: style must be within a range [0 (Aspect_IS_EMPTY), "
-                << Aspect_IS_POINT << " (Aspect_IS_POINT)]\n";
+                << Aspect_IS_OUTLINE << " (Aspect_IS_OUTLINE)]\n";
       return 1;
     }
     anInterStyle = (Aspect_InteriorStyle )anIntStyle;
diff --git a/tests/bugs/vis/bug24437 b/tests/bugs/vis/bug24437
new file mode 100644 (file)
index 0000000..84f7e8e
--- /dev/null
@@ -0,0 +1,26 @@
+puts "========"
+puts "0024437: Efficient HLR visualization based on OpenGL and GLSL"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vsetcolorbg 220 220 220
+
+psphere sph 1.0
+box b 1 2 3
+ttranslate b 2 -2 -2
+
+vdisplay -dispMode 1 b
+vsetinteriorstyle b outline
+vshowfaceboundary b 1 255 0 0 1.0
+vsetedgetype b -color 255 0 0
+vfit
+
+vdisplay -dispMode 1 sph
+vsetinteriorstyle sph outline
+vshowfaceboundary sph 1 255 0 0 1.0
+vsetedgetype sph -color 255 0 0
+vfit