0025539: Visualization, TKOpenGl - support environmental texture within built-in...
authordbp <dbp@opencascade.com>
Thu, 19 Mar 2015 15:43:59 +0000 (18:43 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 6 Apr 2015 14:26:25 +0000 (17:26 +0300)
src/OpenGl/OpenGl_SetOfShaderPrograms.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_ShaderStates.hxx
src/OpenGl/OpenGl_View_2.cxx

index 850be25..2b3cc25 100644 (file)
@@ -27,7 +27,8 @@ enum OpenGl_ProgramOptions
   OpenGl_PO_VertColor  = 0x04, //!< per-vertex color
   OpenGl_PO_TextureRGB = 0x08, //!< handle RGB   texturing
   OpenGl_PO_TextureA   = 0x10, //!< handle Alpha texturing
-  OpenGl_PO_NB         = 0x20  //!< overall number of combinations
+  OpenGl_PO_TextureEnv = 0x20, //!< handle environment map
+  OpenGl_PO_NB         = 0x40  //!< overall number of combinations
 };
 
 //! Alias to programs array of predefined length
index 96cdb1b..7826a0d 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <typeinfo>
 
+#include <Graphic3d_TextureParams.hxx>
 #include <OpenGl_AspectFace.hxx>
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_AspectMarker.hxx>
@@ -809,6 +810,25 @@ const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(Op
   return &myMaterialStates.Find (theProgram);
 }
 
+// =======================================================================
+// function : SurfaceDetailState
+// purpose  : Returns current state of OCCT surface detail
+// =======================================================================
+const OpenGl_SurfaceDetailState& OpenGl_ShaderManager::SurfaceDetailState() const
+{
+  return mySurfaceDetailState;
+}
+
+// =======================================================================
+// function : UpdateSurfaceDetailStateTo
+// purpose  : Updates state of OCCT surface detail
+// =======================================================================
+void OpenGl_ShaderManager::UpdateSurfaceDetailStateTo (const Visual3d_TypeOfSurfaceDetail theDetail)
+{
+  mySurfaceDetailState.Set (theDetail);
+  mySurfaceDetailState.Update();
+}
+
 namespace
 {
 
@@ -980,7 +1000,7 @@ void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)
 }
 
 // =======================================================================
-// function : PushWorldViewState
+// function : PushState
 // purpose  : Pushes state of OCCT graphics parameters to the program
 // =======================================================================
 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
@@ -1120,7 +1140,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
                                                               const Standard_Integer        theBits)
 {
   Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
-  TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
+  TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
   TCollection_AsciiString aSrcFragGetColor     = EOL"vec4 getColor(void) { return occColor; }";
   TCollection_AsciiString aSrcFragMainGetColor = EOL"  occFragColor = getColor();";
   if ((theBits & OpenGl_PO_Point) != 0)
@@ -1174,6 +1194,23 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
       aSrcFragGetColor =
         EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st); }";
     }
+    else if ((theBits & OpenGl_PO_TextureEnv) != 0)
+    {
+      aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
+      aSrcFragExtraOut += THE_VARY_TexCoord_IN;
+
+      aSrcVertExtraFunc = THE_FUNC_transformNormal;
+
+      aSrcVertExtraMain +=
+        EOL"  vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+        EOL"  vec3 aNormal   = transformNormal (occNormal);"
+        EOL"  vec3 aReflect  = reflect (normalize (aPosition.xyz), aNormal);"
+        EOL"  aReflect.z += 1.0;"
+        EOL"  TexCoord = aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5);";
+
+      aSrcFragGetColor =
+        EOL"vec4 getColor(void) { return occTexture2D (occActiveSampler, TexCoord.st); }";
+    }
   }
   if ((theBits & OpenGl_PO_VertColor) != 0)
   {
@@ -1197,7 +1234,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
   }
 
   aSrcVert =
-      aSrcVertExtraOut
+      aSrcVertExtraFunc
+    + aSrcVertExtraOut
     + EOL"void main()"
       EOL"{"
     + aSrcVertExtraMain
index 0ef1808..b784278 100644 (file)
@@ -87,7 +87,7 @@ public:
       return bindProgramWithState (theCustomProgram, theAspect);
     }
 
-    const Standard_Integer        aBits    = getProgramBits (theTexture, theHasVertColor);
+    const Standard_Integer        aBits    = getProgramBits (theTexture, theHasVertColor, Standard_True);
     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
     return bindProgramWithState (aProgram, theAspect);
   }
@@ -228,6 +228,14 @@ public:
 
 public:
 
+  //! Returns current state of OCCT surface detail.
+  Standard_EXPORT const OpenGl_SurfaceDetailState& SurfaceDetailState() const;
+
+  //! Updates state of OCCT surface detail.
+  Standard_EXPORT void UpdateSurfaceDetailStateTo (const Visual3d_TypeOfSurfaceDetail theDetail);
+
+public:
+
   //! Pushes current state of OCCT graphics parameters to specified program.
   Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
 
@@ -259,14 +267,21 @@ protected:
 
   //! Define program bits.
   Standard_Integer getProgramBits (const Handle(OpenGl_Texture)& theTexture,
-                                   const Standard_Boolean        theHasVertColor)
+                                   const Standard_Boolean        theHasVertColor,
+                                   const Standard_Boolean        theEnableEnvMap = Standard_False)
+
   {
     Standard_Integer aBits = 0;
     if (myContext->Clipping().IsClippingOrCappingOn())
     {
       aBits |= OpenGl_PO_ClipPlanes;
     }
-    if (!theTexture.IsNull())
+    if (theEnableEnvMap && mySurfaceDetailState.Detail() == Visual3d_TOD_ENVIRONMENT)
+    {
+      // Environment map overwrites material texture
+      aBits |= OpenGl_PO_TextureEnv;
+    }
+    else if (!theTexture.IsNull())
     {
       aBits |= theTexture->IsAlpha() ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
     }
@@ -281,7 +296,9 @@ protected:
   Handle(OpenGl_ShaderProgram)& getStdProgram (const Standard_Boolean theToLightOn,
                                                const Standard_Integer theBits)
   {
-    if (theToLightOn)
+    // If environment map is enabled lighting calculations are
+    // not needed (in accordance with default OCCT behaviour)
+    if (theToLightOn && (theBits & OpenGl_PO_TextureEnv) == 0)
     {
       Handle(OpenGl_ShaderProgram)& aProgram = myLightPrograms->ChangeValue (theBits);
       if (aProgram.IsNull())
@@ -357,6 +374,7 @@ protected:
   OpenGl_WorldViewState              myWorldViewState;     //!< State of OCCT world-view  transformation
   OpenGl_ClippingState               myClippingState;      //!< State of OCCT clipping planes
   OpenGl_LightSourceState            myLightSourceState;   //!< State of OCCT light sources
+  OpenGl_SurfaceDetailState          mySurfaceDetailState; //!< State of OCCT surface detail
 
 private:
 
index 4f162b0..79a65b3 100755 (executable)
@@ -122,7 +122,8 @@ enum OpenGl_UniformStateType
   OpenGl_MODEL_WORLD_STATE,
   OpenGl_WORLD_VIEW_STATE,
   OpenGl_PROJECTION_STATE,
-  OpenGl_MATERIALS_STATE
+  OpenGl_MATERIALS_STATE,
+  OpenGl_SURF_DETAIL_STATE
 };
 
 //! Total number of state types.
index ef35e62..12e390f 100755 (executable)
 #define _OpenGl_State_HeaderFile
 
 #include <InterfaceGraphic_tgl_all.hxx>
-
+#include <NCollection_List.hxx>
 #include <OpenGl_Element.hxx>
 #include <OpenGl_Light.hxx>
 #include <OpenGl_Vec.hxx>
-
-#include <NCollection_List.hxx>
+#include <Visual3d_TypeOfSurfaceDetail.hxx>
 
 //! Defines interface for OpenGL state.
 class OpenGl_StateInterface
@@ -101,7 +100,7 @@ public:
 
   //! Creates uninitialized world-view state.
   OpenGl_WorldViewState();
-  
+
   //! Sets new world-view matrix.
   void Set (const OpenGl_Mat4& theWorldViewMatrix);
 
@@ -146,7 +145,7 @@ public:
 
   //! Creates new material state.
   OpenGl_MaterialState (const OpenGl_Element* theAspect = NULL);
-  
+
   //! Sets new material aspect.
   void Set (const OpenGl_Element* theAspect);
 
@@ -184,4 +183,28 @@ protected:
 
 };
 
+//! Defines generic state of OCCT surface detail.
+class OpenGl_SurfaceDetailState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates new surface detail state.
+  OpenGl_SurfaceDetailState (const Visual3d_TypeOfSurfaceDetail theDetail = Visual3d_TOD_NONE)
+  : myDetail (theDetail)
+  {
+    //
+  }
+
+  //! Sets new surface detail.
+  void Set (const Visual3d_TypeOfSurfaceDetail theDetail) { myDetail = theDetail; }
+
+  //! Returns surface detail.
+  const Visual3d_TypeOfSurfaceDetail Detail() const { return myDetail; }
+
+private:
+
+  Visual3d_TypeOfSurfaceDetail myDetail; //!< OCCT surface detail
+
+};
+
 #endif // _OpenGl_State_HeaderFile
index eb479e7..652c0f2 100644 (file)
@@ -1093,6 +1093,9 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
   // Clear status bitfields
   theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
 
+  // Update state of surface detail level
+  theWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
+
   // Added PCT for handling of textures
   switch (mySurfaceDetail)
   {