]> OCCT Git - occt.git/commitdiff
0030979: Visualization - introduce customized grid presentations CR30979
authormzernova <mzernova@opencascade.com>
Wed, 7 Sep 2022 13:34:29 +0000 (16:34 +0300)
committermzernova <mzernova@opencascade.com>
Thu, 15 Sep 2022 15:03:51 +0000 (18:03 +0300)
src/AIS/AIS_ViewController.cxx
src/Graphic3d/Graphic3d_ShaderManager.cxx
src/Graphic3d/Graphic3d_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx

index 5445dc0743c69602be56df5c67b18ac9ce7f9812..a3b04e4cb5f5d63803c6f99d499bdb00ad9dd2a2 100644 (file)
@@ -2232,7 +2232,6 @@ void AIS_ViewController::handleCameraActions (const Handle(AIS_InteractiveContex
                                               const Handle(V3d_View)& theView,
                                               const AIS_WalkDelta& theWalk)
 {
-  std::cout << "handleCameraActions\n";
   // apply view actions
   if (myGL.Orientation.ToSetViewOrient)
   {
@@ -3073,7 +3072,6 @@ void AIS_ViewController::handleDynamicHighlight (const Handle(AIS_InteractiveCon
 void AIS_ViewController::handleMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
                                        const Handle(V3d_View)& theView)
 {
-  std::cout << "handleMoveTo\n";
   handleSelectionPick   (theCtx, theView);
   handleDynamicHighlight(theCtx, theView);
   handleSelectionPoly   (theCtx, theView);
index 8650a554dfcd70ed46e2d24dda5a1562a3ae9cf7..d70a83d4b99f99424588fafb43d8a117d4813b13 100644 (file)
@@ -2183,3 +2183,104 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getColoredQuadProgram()
 
   return aProgSrc;
 }
+
+Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getGridProgram() const
+{
+  Handle(Graphic3d_ShaderProgram) aProgSrc = new Graphic3d_ShaderProgram();
+
+  Graphic3d_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
+  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 NearPoint", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 FarPoint", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 MVP", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("float uZNear", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("float uZFar", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("bool uIsDrawAxis", Graphic3d_TOS_FRAGMENT));
+
+  TCollection_AsciiString aSrcVert = TCollection_AsciiString()
+  + EOL"vec3 gridPlane[6] = vec3[] (vec3( 1,  1, 0), vec3(-1, -1, 0), vec3(-1,  1, 0),"
+    EOL"                            vec3(-1, -1, 0), vec3( 1,  1, 0), vec3( 1, -1, 0));"
+
+    EOL"vec3 UnprojectPoint (float aX, float anY, float aZ)"
+    EOL"{"
+    EOL"  vec4 anUnprojPnt = occModelWorldMatrixInverse * occWorldViewMatrixInverse * occProjectionMatrixInverse * vec4 (aX, anY, aZ, 1.0);"
+    EOL"  return anUnprojPnt.xyz / anUnprojPnt.w;"
+    EOL"}"
+
+    EOL"void main()"
+    EOL"{"
+    EOL"  vec3 aVertex = gridPlane[gl_VertexID];"
+    EOL"  NearPoint = UnprojectPoint (aVertex.x, aVertex.y, 0.0);"
+    EOL"  FarPoint  = UnprojectPoint (aVertex.x, aVertex.y, 1.0);"
+    EOL"  MVP = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix;"
+    EOL"  gl_Position = vec4 (aVertex, 1.0);"
+    EOL"}";
+
+  TCollection_AsciiString aSrcFrag = TCollection_AsciiString()
+  + EOL"vec4 grid (vec3 theFragPos3D, vec3 theColor, float theScale, bool theIsDrawAxis)"
+    EOL"{"
+    EOL"  vec2 aCoord = theFragPos3D.xy * theScale;"
+    EOL"  vec2 aDerivative = fwidth (aCoord);"
+    EOL"  vec2 aGrid = abs (fract (aCoord - 0.5) - 0.5) / aDerivative;"
+    EOL"  float aLine = min (aGrid.x, aGrid.y);"
+    EOL"  float aMinY = min (aDerivative.y, 1);"
+    EOL"  float aMinX = min (aDerivative.x, 1);"
+    EOL"  vec4 aColor = vec4 (theColor, round (1.0 - min (aLine, 1.0)));"
+    EOL"  if (uIsDrawAxis && theIsDrawAxis)"
+    EOL"  {"
+    EOL"    bool isYAxis = -aMinX < aCoord.x && aCoord.x < aMinX;"
+    EOL"    bool isXAxis = -aMinY < aCoord.y && aCoord.y < aMinY;"
+    EOL"    if (isXAxis && isYAxis) { aColor.xyz = vec3 (0.0, 0.0, 1.0); }"
+    EOL"    else if (isXAxis) { aColor.xyz = vec3 (1.0, 0.0, 0.0); }"
+    EOL"    else if (isYAxis) { aColor.xyz = vec3 (0.0, 1.0, 0.0); }"
+    EOL"  }"
+    EOL"  return aColor;"
+    EOL" }"
+
+    EOL"float computeDepth (vec3 thePos)"
+    EOL"{"
+    EOL"  vec4 aClipSpacePos = MVP * vec4 (thePos, 1.0);"
+    EOL"  return (aClipSpacePos.z / aClipSpacePos.w);"
+    EOL"}"
+
+    EOL"float computeLinearDepth (vec3 thePos)"
+    EOL"{"
+    EOL"  float aClipSpaceDepth = computeDepth (thePos) * 2.0 - 1.0;"
+    EOL"  float aLinearDepth = (2.0 * uZNear * uZFar) / (uZFar + uZNear - aClipSpaceDepth * (uZFar - uZNear));"
+    EOL"  return aLinearDepth / uZFar;"
+    EOL"}"
+
+    EOL"void main()"
+    EOL"{"
+    EOL"  float aParam = -NearPoint.z / (FarPoint.z - NearPoint.z);"
+    EOL"  vec3 aFragPos3D = NearPoint + aParam * (FarPoint - NearPoint);"
+    EOL"  float aLinearDepth = computeLinearDepth (aFragPos3D);"
+    // TODO : Compute scale
+    EOL"  vec4 aBigGridColor = grid (aFragPos3D, vec3 (0.8), 0.01, true);"
+    EOL"  vec4 aColor = aBigGridColor.a == 0.0"
+    EOL"              ? grid (aFragPos3D, vec3 (0.2), 0.1, false)"
+    EOL"              : aBigGridColor;"
+    EOL"  float aDepth = computeDepth (aFragPos3D);"
+    EOL"  float aFar  = gl_DepthRange.far;"
+    EOL"  float aNear = gl_DepthRange.near;"
+    EOL"  aDepth = ((aFar - aNear) * aDepth + aNear + aFar) * 0.5;"
+    EOL"  if (aColor.a == 0.0 || (-1.0 < aLinearDepth && aLinearDepth < 0.0))"
+    EOL"  {"
+    EOL"    discard;"
+    EOL"  };"
+    // TODO : Get actual background color
+    EOL"  vec4 aBackgroundColor = vec4 (0.0, 0.0, 0.0, 1.0);"
+    EOL"  if (abs (aLinearDepth) > 1.0)"
+    EOL"  {"
+    EOL"    float anInterpVal = float (aLinearDepth > 0.0) - sign (aLinearDepth) * clamp (1.0 / (abs (aLinearDepth) - 1.0), 0.5, 1.0);"
+    EOL"    aColor = mix (aColor, aBackgroundColor, anInterpVal);"
+    EOL"  }"
+    EOL"  gl_FragDepth = aDepth;"
+    EOL"  occFragColor = aColor;"
+    EOL"}";
+
+  defaultGlslVersion (aProgSrc, "grid", 0);
+  aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
+  aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
+
+  return aProgSrc;
+}
index 023b574260beb6282bb7d6af2f46926afbbd4fcc..1f2df5040f3ebd8ccc19f478cb0320c386fc506d 100644 (file)
@@ -148,6 +148,9 @@ protected:
   //! Generates shader program to render correctly colored quad.
   Standard_EXPORT Handle(Graphic3d_ShaderProgram) getColoredQuadProgram() const;
 
+  //! Generates shader program to render grid.
+  Standard_EXPORT Handle(Graphic3d_ShaderProgram) getGridProgram() const;
+
   //! Prepare GLSL source for IBL generation used in PBR pipeline.
   Standard_EXPORT Handle(Graphic3d_ShaderProgram) getPBREnvBakingProgram (Standard_Integer theIndex) const;
 
index eff6bf9f3909747f91e262d960c9e6e360ed8d79..de9725674e504f028b999110c1b2f6de86dafc1e 100644 (file)
@@ -1361,6 +1361,27 @@ Standard_Boolean OpenGl_ShaderManager::preparePBREnvBakingProgram (Standard_Inte
   return Standard_True;
 }
 
+// =======================================================================
+// function : prepareGridProgram
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareGridProgram()
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = getGridProgram();
+
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, myGridProgram))
+  {
+    myGridProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+
+  myContext->BindProgram (myGridProgram);
+  myContext->BindProgram (Handle(OpenGl_ShaderProgram)());
+
+  return Standard_True;
+}
+
 // =======================================================================
 // function : GetBgCubeMapProgram
 // purpose  :
index f8dc9da70b343e9f38da0edc0d32e1e0d0fda089..bfe1db412d7795ff777bfcbcea79f17fb673e93f 100644 (file)
@@ -225,6 +225,16 @@ public:
     return myContext->BindProgram (myPBREnvBakingProgram[theIndex]);
   }
 
+  //! Bind program for IBL maps generation in PBR pipeline.
+  Standard_Boolean BindGridProgram()
+  {
+    if (myGridProgram.IsNull())
+    {
+      prepareGridProgram();
+    }
+    return myContext->BindProgram (myGridProgram);
+  }
+
   //! Generates shader program to render environment cubemap as background.
   Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram();
 
@@ -709,6 +719,8 @@ protected:
   Standard_Boolean IsPbrAllowed() const { return myShadingModel == Graphic3d_TypeOfShadingModel_Pbr
                                               || myShadingModel == Graphic3d_TypeOfShadingModel_PbrFacet; }
 
+  Standard_EXPORT Standard_Boolean prepareGridProgram();
+
 protected:
 
   //! Packed properties of light source
@@ -776,6 +788,7 @@ protected:
   Handle(Graphic3d_ShaderProgram)    myBgCubeMapProgram;       //!< program for background cubemap rendering
   Handle(Graphic3d_ShaderProgram)    myBgSkydomeProgram;       //!< program for background cubemap rendering
   Handle(Graphic3d_ShaderProgram)    myColoredQuadProgram;     //!< program for correct quad rendering
+  Handle(OpenGl_ShaderProgram)       myGridProgram;            //!< program for grid rendering
 
   Handle(OpenGl_ShaderProgram)       myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
 
index 790779556779e7b528070c0260fd90a6d41729f5..147c81970d6e3f46a304b0ea65e9f8d787ff212f 100644 (file)
@@ -2433,6 +2433,12 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
     aContext->core11fwd->glDisable (GL_LIGHTING);
   }
 
+  // ====================================
+  //      Step 3: Redraw grid
+  // ====================================
+
+  renderGrid();
+
   // =================================
   //      Step 3: Redraw main plane
   // =================================
@@ -2525,6 +2531,35 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   }
 }
 
+// =======================================================================
+// function : renderGrid
+// purpose  :
+// =======================================================================
+void OpenGl_View::renderGrid()
+{
+  const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
+
+  aContext->ShaderManager()->UpdateModelWorldStateTo (aContext->ModelWorldState.Current());
+  aContext->ShaderManager()->UpdateProjectionStateTo (aContext->ProjectionState.Current());
+  aContext->ShaderManager()->UpdateWorldViewStateTo (aContext->WorldViewState.Current());
+
+  aContext->core11fwd->glEnable (GL_BLEND);
+  aContext->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  if (aContext->ShaderManager()->BindGridProgram())
+  {
+    const Handle(OpenGl_ShaderProgram)& aProg = aContext->ActiveProgram();
+    aProg->SetUniform (aContext, "uZNear", GLfloat (aContext->Camera()->ZNear()));
+    aProg->SetUniform (aContext, "uZFar", GLfloat (aContext->Camera()->ZFar()));
+    // TODO : add param to draw command
+    aProg->SetUniform (aContext, "uIsDrawAxis", GLboolean (true));
+
+    aContext->ShaderManager()->PushState (aContext->ActiveProgram());
+    aContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+    aContext->BindProgram (NULL);
+  }
+}
+
 // =======================================================================
 // function : InvalidateBVHData
 // purpose  :
index 17768a06d13b2e91ac03685fbd68db8d339c1dde..d541ec5acd4aec077716b93e2fb15f9086966ba1 100644 (file)
@@ -390,6 +390,9 @@ protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
                                               OpenGl_FrameBuffer*    theOitAccumFbo,
                                               const Standard_Boolean theToDrawImmediate);
 
+  //! Renders grid
+  Standard_EXPORT void renderGrid();
+
   //! Renders trihedron.
   void renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace);