diff --git a/src/OpenGl/OpenGl_SetOfShaderPrograms.hxx b/src/OpenGl/OpenGl_SetOfShaderPrograms.hxx index 850be25ae5..2b3cc25fd4 100644 --- a/src/OpenGl/OpenGl_SetOfShaderPrograms.hxx +++ b/src/OpenGl/OpenGl_SetOfShaderPrograms.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 96cdb1b1de..7826a0d2bc 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -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 diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index 0ef1808ac8..b7842785c9 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -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); } @@ -226,6 +226,14 @@ public: //! Returns current state of OCCT material for specified program. Standard_EXPORT const OpenGl_MaterialState* MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const; +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. @@ -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: diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx index 4f162b0af3..79a65b3e73 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.hxx +++ b/src/OpenGl/OpenGl_ShaderProgram.hxx @@ -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. diff --git a/src/OpenGl/OpenGl_ShaderStates.hxx b/src/OpenGl/OpenGl_ShaderStates.hxx index ef35e62004..12e390fb39 100755 --- a/src/OpenGl/OpenGl_ShaderStates.hxx +++ b/src/OpenGl/OpenGl_ShaderStates.hxx @@ -17,12 +17,11 @@ #define _OpenGl_State_HeaderFile #include - +#include #include #include #include - -#include +#include //! 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 diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index eb479e775d..652c0f25a7 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -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) {