diff --git a/src/Graphic3d/Graphic3d_CView.cxx b/src/Graphic3d/Graphic3d_CView.cxx index 4328c08d62..1461965552 100644 --- a/src/Graphic3d/Graphic3d_CView.cxx +++ b/src/Graphic3d/Graphic3d_CView.cxx @@ -26,6 +26,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager) //======================================================================= Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theMgr) : myBgColor (Quantity_NOC_BLACK), + myBackgroundType (Graphic3d_TOB_NONE), myStructureManager (theMgr), myCamera (new Graphic3d_Camera()), myHiddenObjects (new Graphic3d_NMapOfTransient()), diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index 999b9b4a4e..f9279b7e75 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -372,7 +373,7 @@ public: virtual void SetGradientBackground (const Aspect_GradientBackground& theBackground) = 0; //! Returns background image texture map. - virtual Handle(Graphic3d_TextureMap) BackgroundImage() = 0; + const Handle(Graphic3d_TextureMap)& BackgroundImage() { return myBackgroundImage; } //! Sets image texture or environment cubemap as background. //! @param theTextureMap [in] source to set a background; @@ -389,7 +390,7 @@ public: virtual void SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) = 0; //! Returns cubemap being set last time on background. - virtual Handle(Graphic3d_CubeMap) BackgroundCubeMap() const = 0; + const Handle(Graphic3d_CubeMap)& BackgroundCubeMap() const { return myCubeMapBackground; } //! Generates PBR specular probe and irradiance map //! in order to provide environment indirect illumination in PBR shading model (Image Based Lighting). @@ -405,7 +406,7 @@ public: virtual void ClearPBREnvironment() = 0; //! Returns environment texture set for the view. - virtual Handle(Graphic3d_TextureEnv) TextureEnv() const = 0; + const Handle(Graphic3d_TextureEnv)& TextureEnv() const { return myTextureEnvData; } //! Sets environment texture for the view. virtual void SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) = 0; @@ -568,7 +569,14 @@ protected: Standard_Integer myId; Graphic3d_RenderingParams myRenderParams; - Quantity_ColorRGBA myBgColor; + + Quantity_ColorRGBA myBgColor; + Handle(Graphic3d_TextureMap) myBackgroundImage; + Handle(Graphic3d_CubeMap) myCubeMapBackground; //!< Cubemap displayed at background + Handle(Graphic3d_CubeMap) myCubeMapEnvironment; //!< Cubemap used for environment lighting + Handle(Graphic3d_TextureEnv) myTextureEnvData; + Graphic3d_TypeOfBackground myBackgroundType; //!< Current type of background + Handle(Graphic3d_StructureManager) myStructureManager; Handle(Graphic3d_Camera) myCamera; Graphic3d_SequenceOfStructure myStructsToCompute; diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index ed411f2fc4..b8e1a83e35 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -129,9 +129,8 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, myIsImmediateDrawn (Standard_False), myTextureParams (new OpenGl_Aspects()), myCubeMapParams (new OpenGl_Aspects()), - myBackgroundType (Graphic3d_TOB_NONE), myPBREnvState (OpenGl_PBREnvState_NONEXISTENT), - myPBREnvRequest (OpenGl_PBREnvRequest_NONE), + myPBREnvRequest (Standard_False), // ray-tracing fields initialization myRaytraceInitStatus (OpenGl_RT_NONE), myIsRaytraceDataValid (Standard_False), @@ -553,49 +552,58 @@ void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBac void OpenGl_View::SetBackgroundImage (const Handle(Graphic3d_TextureMap)& theTextureMap, Standard_Boolean theToUpdatePBREnv) { + Handle(Graphic3d_TextureMap) aNewMap = theTextureMap; if (theTextureMap.IsNull() || !theTextureMap->IsDone()) + { + if (!theTextureMap.IsNull()) + { + Message::SendFail ("Error: unable to set image background"); + } + aNewMap.Nullify(); + } + + Handle(Graphic3d_CubeMap) aCubeMap = Handle(Graphic3d_CubeMap)::DownCast (aNewMap); + if (theToUpdatePBREnv) + { + const TCollection_AsciiString anIdOld = !myCubeMapEnvironment.IsNull() + ? myCubeMapEnvironment->GetId() + : TCollection_AsciiString(); + const TCollection_AsciiString anIdNew = !aCubeMap.IsNull() + ? aCubeMap->GetId() + : TCollection_AsciiString(); + myPBREnvRequest = anIdNew != anIdOld; + myCubeMapEnvironment = aCubeMap; + } + + if (aNewMap.IsNull()) { if (myBackgroundType == Graphic3d_TOB_TEXTURE || myBackgroundType == Graphic3d_TOB_CUBEMAP) { myBackgroundType = Graphic3d_TOB_NONE; - if (theToUpdatePBREnv) - { - myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; - } } return; } Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); - Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (theTextureMap); + Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNewMap); anAspect->SetInteriorStyle (Aspect_IS_SOLID); anAspect->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_DoubleSided); anAspect->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit); anAspect->SetTextureSet (aTextureSet); anAspect->SetTextureMapOn (true); - if (Handle(Graphic3d_Texture2D) aTextureMap = Handle(Graphic3d_Texture2D)::DownCast (theTextureMap)) + if (Handle(Graphic3d_Texture2D) aTextureMap = Handle(Graphic3d_Texture2D)::DownCast (aNewMap)) { - if (theToUpdatePBREnv && myBackgroundType == Graphic3d_TOB_CUBEMAP) - { - myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; - } - myTextureParams->SetAspect (anAspect); myBackgroundType = Graphic3d_TOB_TEXTURE; myBackgroundImage = aTextureMap; return; } - if (Handle(Graphic3d_CubeMap) aCubeMap = Handle(Graphic3d_CubeMap)::DownCast (theTextureMap)) + if (!aCubeMap.IsNull()) { - if (theToUpdatePBREnv) - { - myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; - } - aCubeMap->SetMipmapsGeneration (Standard_True); if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext()) { @@ -610,7 +618,7 @@ void OpenGl_View::SetBackgroundImage (const Handle(Graphic3d_TextureMap)& theTex myWorkspace->ApplyAspects(); myBackgroundType = Graphic3d_TOB_CUBEMAP; - myBackgroundCubeMap = aCubeMap; + myCubeMapBackground = aCubeMap; return; } @@ -635,15 +643,6 @@ void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) myBackgrounds[Graphic3d_TOB_TEXTURE]->SetTextureFillMethod (theFillStyle); } -// ======================================================================= -// function : BackgroundCubeMap -// purpose : -// ======================================================================= -Handle(Graphic3d_CubeMap) OpenGl_View::BackgroundCubeMap() const -{ - return myBackgroundCubeMap; -} - // ======================================================================= // function : SpecIBLMapLevels // purpose : @@ -955,8 +954,8 @@ void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace, if (myBackgroundType == Graphic3d_TOB_CUBEMAP) { - myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uZCoeff", myBackgroundCubeMap->ZIsInverted() ? -1 : 1); - myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uYCoeff", myBackgroundCubeMap->IsTopDown() ? 1 : -1); + myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uZCoeff", myCubeMapBackground->ZIsInverted() ? -1 : 1); + myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uYCoeff", myCubeMapBackground->IsTopDown() ? 1 : -1); const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myCubeMapParams); myBackgrounds[Graphic3d_TOB_CUBEMAP]->Render (theWorkspace, theProjection); @@ -1203,7 +1202,7 @@ bool OpenGl_View::prepareFrameBuffers (Graphic3d_Camera::Projection& theProj) myPBREnvironment->Release (aCtx.get()); myPBREnvironment.Nullify(); myPBREnvState = OpenGl_PBREnvState_NONEXISTENT; - myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; + myPBREnvRequest = true; ++myLightsRevision; } @@ -1297,7 +1296,7 @@ bool OpenGl_View::prepareFrameBuffers (Graphic3d_Camera::Projection& theProj) myWorkspace->ApplyAspects(); } } - processPBREnvRequest (aCtx); + updatePBREnvironment (aCtx); } // create color and coverage accumulation buffers required for OIT algorithm @@ -3042,19 +3041,51 @@ Standard_Boolean OpenGl_View::checkPBRAvailability() const } // ======================================================================= -// function : bakePBREnvironment +// function : updatePBREnvironment // purpose : // ======================================================================= -void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx) +void OpenGl_View::updatePBREnvironment (const Handle(OpenGl_Context)& theCtx) { - const Handle(OpenGl_TextureSet)& aTextureSet = myCubeMapParams->TextureSet (theCtx); - if (!aTextureSet.IsNull() - && !aTextureSet->IsEmpty()) + if (myPBREnvState != OpenGl_PBREnvState_CREATED + || !myPBREnvRequest) + { + myPBREnvRequest = false; + return; + } + + myPBREnvRequest = false; + + Handle(OpenGl_TextureSet) aGlTextureSet; + OpenGl_Aspects* aTmpGlAspects = NULL; + if (!myCubeMapEnvironment.IsNull() + && myCubeMapEnvironment == myCubeMapBackground) + { + aGlTextureSet = myCubeMapParams->TextureSet (theCtx); + } + else if (!myCubeMapEnvironment.IsNull()) + { + myCubeMapEnvironment->SetMipmapsGeneration (Standard_True); + + Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); + { + Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myCubeMapEnvironment); + anAspect->SetInteriorStyle (Aspect_IS_SOLID); + anAspect->SetTextureSet (aTextureSet); + anAspect->SetTextureMapOn (true); + } + + aTmpGlAspects = new OpenGl_Aspects(); + aTmpGlAspects->SetAspect (anAspect); + aGlTextureSet = aTmpGlAspects->TextureSet (theCtx); + } + + if (!aGlTextureSet.IsNull() + && !aGlTextureSet->IsEmpty()) { myPBREnvironment->Bake (theCtx, - aTextureSet->First(), - myBackgroundCubeMap->ZIsInverted(), - myBackgroundCubeMap->IsTopDown(), + aGlTextureSet->First(), + myCubeMapEnvironment->ZIsInverted(), + myCubeMapEnvironment->IsTopDown(), myRenderParams.PbrEnvBakingDiffNbSamples, myRenderParams.PbrEnvBakingSpecNbSamples, myRenderParams.PbrEnvBakingProbability); @@ -3063,31 +3094,6 @@ void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx) { myPBREnvironment->Clear (theCtx); } -} - -// ======================================================================= -// function : clearPBREnvironment -// purpose : -// ======================================================================= -void OpenGl_View::clearPBREnvironment (const Handle(OpenGl_Context)& theCtx) -{ - myPBREnvironment->Clear (theCtx); -} - -// ======================================================================= -// function : clearPBREnvironment -// purpose : -// ======================================================================= -void OpenGl_View::processPBREnvRequest (const Handle(OpenGl_Context)& theCtx) -{ - if (myPBREnvState == OpenGl_PBREnvState_CREATED) - { - switch (myPBREnvRequest) - { - case OpenGl_PBREnvRequest_NONE: return; - case OpenGl_PBREnvRequest_BAKE: bakePBREnvironment (theCtx); break; - case OpenGl_PBREnvRequest_CLEAR: clearPBREnvironment (theCtx); break; - } - } - myPBREnvRequest = OpenGl_PBREnvRequest_NONE; + aGlTextureSet.Nullify(); + OpenGl_Element::Destroy (theCtx.get(), aTmpGlAspects); } diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index fde391e89c..69f4c63341 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -16,15 +16,11 @@ #ifndef _OpenGl_View_Header #define _OpenGl_View_Header -#include -#include #include #include #include #include #include -#include -#include #include #include #include @@ -41,7 +37,6 @@ #include #include -class Graphic3d_StructureManager; class OpenGl_BackgroundArray; class OpenGl_DepthPeeling; class OpenGl_GraphicDriver; @@ -206,9 +201,6 @@ public: //! Sets gradient background fill colors. Standard_EXPORT virtual void SetGradientBackground (const Aspect_GradientBackground& theBackground) Standard_OVERRIDE; - //! Returns background image texture map. - virtual Handle(Graphic3d_TextureMap) BackgroundImage() Standard_OVERRIDE { return myBackgroundImage; } - //! Sets image texture or environment cubemap as background. //! @param theTextureMap [in] source to set a background; //! should be either Graphic3d_Texture2D or Graphic3d_CubeMap @@ -217,38 +209,39 @@ public: Standard_EXPORT virtual void SetBackgroundImage (const Handle(Graphic3d_TextureMap)& theTextureMap, Standard_Boolean theToUpdatePBREnv = Standard_True) Standard_OVERRIDE; + //! Sets environment texture for the view. + Standard_EXPORT virtual void SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) Standard_OVERRIDE; + //! Returns background image fill style. Standard_EXPORT virtual Aspect_FillMethod BackgroundImageStyle() const Standard_OVERRIDE; //! Sets background image fill style. Standard_EXPORT virtual void SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) Standard_OVERRIDE; - //! Returns cubemap being set last time on background. - Standard_EXPORT Handle(Graphic3d_CubeMap) BackgroundCubeMap() const Standard_OVERRIDE; - //! Generates PBR specular probe and irradiance map //! in order to provide environment indirect illumination in PBR shading model (Image Based Lighting). //! The source of environment data is background cubemap. //! If PBR is unavailable it does nothing. //! If PBR is available but there is no cubemap being set to background it clears all IBL maps (see 'ClearPBREnvironment'). - virtual void GeneratePBREnvironment() Standard_OVERRIDE { myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; } + virtual void GeneratePBREnvironment() Standard_OVERRIDE + { + myPBREnvRequest = true; + } //! Fills PBR specular probe and irradiance map with white color. //! So that environment indirect illumination will be constant //! and will be fully controlled by ambient light sources. //! If PBR is unavailable it does nothing. - virtual void ClearPBREnvironment() Standard_OVERRIDE { myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; } + virtual void ClearPBREnvironment() Standard_OVERRIDE + { + myPBREnvRequest = true; + myCubeMapEnvironment.Nullify(); + } //! Returns number of mipmap levels used in specular IBL map. //! 0 if PBR environment is not created. Standard_EXPORT unsigned int SpecIBLMapLevels() const; - //! Returns environment texture set for the view. - virtual Handle(Graphic3d_TextureEnv) TextureEnv() const Standard_OVERRIDE { return myTextureEnvData; } - - //! Sets environment texture for the view. - Standard_EXPORT virtual void SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) Standard_OVERRIDE; - //! Returns local camera origin currently set for rendering, might be modified during rendering. const gp_XYZ& LocalOrigin() const { return myLocalOrigin; } @@ -470,8 +463,6 @@ protected: gp_XYZ myLocalOrigin; Handle(OpenGl_FrameBuffer) myFBO; Standard_Boolean myToShowGradTrihedron; - Handle(Graphic3d_TextureMap) myBackgroundImage; - Handle(Graphic3d_TextureEnv) myTextureEnvData; Graphic3d_GraduatedTrihedron myGTrihedronData; Handle(Graphic3d_LightSet) myNoShadingLight; @@ -495,8 +486,6 @@ protected: OpenGl_GraduatedTrihedron myGraduatedTrihedron; OpenGl_FrameStatsPrs myFrameStatsPrs; - Handle(OpenGl_TextureSet) myTextureEnv; - //! Framebuffers for OpenGL output. Handle(OpenGl_FrameBuffer) myOpenGlFBO; Handle(OpenGl_FrameBuffer) myOpenGlFBO2; @@ -532,9 +521,8 @@ protected: //! @name Background parameters OpenGl_Aspects* myTextureParams; //!< Stores texture and its parameters for textured background OpenGl_Aspects* myCubeMapParams; //!< Stores cubemap and its parameters for cubemap background - Handle(Graphic3d_CubeMap) myBackgroundCubeMap; //!< Cubemap has been set as background - Graphic3d_TypeOfBackground myBackgroundType; //!< Current type of background OpenGl_BackgroundArray* myBackgrounds[Graphic3d_TypeOfBackground_NB]; //!< Array of primitive arrays of different background types + Handle(OpenGl_TextureSet) myTextureEnv; protected: //! @name methods related to PBR @@ -543,14 +531,7 @@ protected: //! @name methods related to PBR //! Generates IBL maps used in PBR pipeline. //! If background cubemap is not set clears all IBL maps. - Standard_EXPORT void bakePBREnvironment (const Handle(OpenGl_Context)& theCtx); - - //! Fills all IBL maps with white color. - //! So that environment lighting is considered to be constant and is completely controls by ambient light sources. - Standard_EXPORT void clearPBREnvironment (const Handle(OpenGl_Context)& theCtx); - - //! Process requests to generate or to clear PBR environment. - Standard_EXPORT void processPBREnvRequest (const Handle(OpenGl_Context)& theCtx); + Standard_EXPORT void updatePBREnvironment (const Handle(OpenGl_Context)& theCtx); protected: //! @name fields and types related to PBR @@ -562,17 +543,9 @@ protected: //! @name fields and types related to PBR OpenGl_PBREnvState_CREATED }; - //! Type of action which can be done with PBR environment. - enum PBREnvironmentRequest - { - OpenGl_PBREnvRequest_NONE, - OpenGl_PBREnvRequest_BAKE, - OpenGl_PBREnvRequest_CLEAR - }; - Handle(OpenGl_PBREnvironment) myPBREnvironment; //!< manager of IBL maps used in PBR pipeline PBREnvironmentState myPBREnvState; //!< state of PBR environment - PBREnvironmentRequest myPBREnvRequest; //!< type of action is requested to be done with PBR environment + Standard_Boolean myPBREnvRequest; //!< update PBR environment protected: //! @name data types related to ray-tracing @@ -761,7 +734,7 @@ protected: //! @name data types related to ray-tracing //! Enables/disables depth-of-field effect (path tracing, perspective camera). Standard_Boolean DepthOfField; - //! Enables/disables cubemap backgraund. + //! Enables/disables cubemap background. Standard_Boolean CubemapForBack; //! Tone mapping method for path tracing. diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index 6088506e74..7b3b171877 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -1422,7 +1422,7 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS } myTileSampler.SetSize (myRenderParams, myRaytraceParameters.AdaptiveScreenSampling ? Graphic3d_Vec2i (theSizeX, theSizeY) : Graphic3d_Vec2i (0, 0)); - const bool isCubemapForBack = !myBackgroundCubeMap.IsNull(); + const bool isCubemapForBack = !myCubeMapBackground.IsNull(); if (myRaytraceParameters.CubemapForBack != isCubemapForBack) { myRaytraceParameters.CubemapForBack = isCubemapForBack; @@ -2694,8 +2694,8 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer the toDisableEnvironmentMap ? 0 : 1); if (myRaytraceParameters.CubemapForBack) { - theProgram->SetUniform (theGlContext, "uZCoeff", myBackgroundCubeMap->ZIsInverted() ? -1 : 1); - theProgram->SetUniform (theGlContext, "uYCoeff", myBackgroundCubeMap->IsTopDown() ? 1 : -1); + theProgram->SetUniform (theGlContext, "uZCoeff", myCubeMapBackground->ZIsInverted() ? -1 : 1); + theProgram->SetUniform (theGlContext, "uYCoeff", myCubeMapBackground->IsTopDown() ? 1 : -1); theProgram->SetUniform (theGlContext, myUniformLocations[theProgramId][OpenGl_RT_uEnvMapForBack], myBackgroundType == Graphic3d_TOB_CUBEMAP ? 1 : 0); }