]> 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>
Mon, 21 May 2018 08:06:49 +0000 (11:06 +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

12 files changed:
src/Aspect/Aspect_InteriorStyle.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_SetOfShaderPrograms.hxx
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 18cbea056d29b53b56bcc7e4a82b1e7bf1e04ac4..c9516eae3c02c44675a73c52684ac58ed496017e 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>
 
@@ -3447,6 +3448,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 96ac2636ee3ab35e453f87c2c8eb965b3e83c026..b7a8a3f765d0c349860ffc36df589144019846a2 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <NCollection_Shared.hxx>
 
+class OpenGl_Workspace;
+
 //! Forward declarations
 #if defined(__APPLE__)
   #import <TargetConditionals.h>
@@ -722,6 +724,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 71c96fe539d5d0be027b2562397d9e658099a37e..8804b51bcc4d659b6809a622bcfbbfb7fd88d598 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>
@@ -810,7 +811,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;
       }
     }
@@ -868,8 +901,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);
@@ -1026,3 +1060,4 @@ void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)&        th
 
   setDrawMode (theType);
 }
+
index f04c5471ff4724e9f03947957465cbf55874f995..e4e3fd06d2986993609e897f6d05ea00fefd8d58 100644 (file)
@@ -34,7 +34,8 @@ enum OpenGl_ProgramOptions
   OpenGl_PO_ClipPlanesN = 0x100, //!< handle N clipping planes
   OpenGl_PO_AlphaTest   = 0x200, //!< discard fragment by alpha test (defined by cutoff value)
   OpenGl_PO_WriteOit    = 0x400, //!< write coverage buffer for Blended Order-Independent Transparency
-  OpenGl_PO_NB          = 0x800  //!< overall number of combinations
+  OpenGl_PO_OUTLINE     = 0x800, //!< HLR presentation (outline shader)
+  OpenGl_PO_NB          = 0x1000  //!< overall number of combinations
 };
 
 //! Alias to programs array of predefined length
index a83169c8b11339a419dd9aade678a9bc0c892d92..2c8c74d5fa327f5bd494058b1a0163b9337e2a59 100644 (file)
@@ -1603,13 +1603,58 @@ 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
     + aSrcVertExtraOut
     + 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 7c423e00664f9cc1472a6fbf22cd035665783801..83ff3f5da3c3aaf2ce8da3e19d880fa127b17129 100644 (file)
@@ -87,7 +87,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)
@@ -99,7 +100,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);
   }
@@ -401,7 +402,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;
@@ -444,6 +446,11 @@ protected:
     {
       aBits |= OpenGl_PO_WriteOit;
     }
+
+    if (theStyle == Aspect_IS_OUTLINE)
+    {
+      aBits |= OpenGl_PO_OUTLINE;
+    }
     return aBits;
   }
 
@@ -452,7 +459,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 784dc528ab739c8a7985e9f9b99ec131092d2b0c..e9039714b6dda78b2bb1f5a6cdf967d38c25d738 100755 (executable)
@@ -74,7 +74,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 87941ff0b3a40a582382086a8c41037a6cc9b23a..639921f7360d157fa63ad9486b9e5756af581849 100755 (executable)
@@ -74,6 +74,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 9f162cc35b5f585e5957bf7207bbff3289ee452c..bf92c354c7d936d736d4ed1766737b3f8a51544f 100644 (file)
@@ -761,7 +761,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 e81f4cfe99c1b3d324de0c20354f95469334de0e..14f40829130155af9023d4edabb794186f815ff0 100644 (file)
@@ -1575,14 +1575,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