#include <OpenGl_Structure.hxx>
#include <OpenGl_ArbFBO.hxx>
+#include "../Textures/Textures_EnvLUT.pxx"
+
namespace
{
//! Format Frame Buffer format for logging messages.
}
}
+ // process PBR environment
+ if (myShadingModel == Graphic3d_TOSM_PBR
+ || myShadingModel == Graphic3d_TOSM_PBR_FACET)
+ {
+ if (!myPBREnvironment.IsNull()
+ && myPBREnvironment->SizesAreDifferent (myRenderParams.PbrEnvPow2Size,
+ myRenderParams.PbrEnvSpecMapNbLevels))
+ {
+ myPBREnvironment->Release (aCtx.get());
+ myPBREnvironment.Nullify();
+ myPBREnvState = OpenGl_PBREnvState_NONEXISTENT;
+ myPBREnvRequest = OpenGl_PBREnvRequest_BAKE;
+ ++myLightsRevision;
+ }
+
+ if (myPBREnvState == OpenGl_PBREnvState_NONEXISTENT
+ && aCtx->HasPBR())
+ {
+ myPBREnvironment = OpenGl_PBREnvironment::Create (aCtx, myRenderParams.PbrEnvPow2Size, myRenderParams.PbrEnvSpecMapNbLevels);
+ myPBREnvState = myPBREnvironment.IsNull() ? OpenGl_PBREnvState_UNAVAILABLE : OpenGl_PBREnvState_CREATED;
+ if (myPBREnvState == OpenGl_PBREnvState_CREATED)
+ {
+ Handle(OpenGl_Texture) anEnvLUT;
+ static const TCollection_AsciiString THE_SHARED_ENV_LUT_KEY("EnvLUT");
+ if (!aCtx->GetResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT))
+ {
+ Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams();
+ aParams->SetFilter (Graphic3d_TOTF_BILINEAR);
+ aParams->SetRepeat (Standard_False);
+ aParams->SetTextureUnit (aCtx->PBREnvLUTTexUnit());
+ anEnvLUT = new OpenGl_Texture(THE_SHARED_ENV_LUT_KEY, aParams);
+ Handle(Image_PixMap) aPixMap = new Image_PixMap();
+ aPixMap->InitWrapper (Image_Format_RGF, (Standard_Byte*)Textures_EnvLUT, Textures_EnvLUTSize, Textures_EnvLUTSize);
+ OpenGl_TextureFormat aTexFormat = OpenGl_TextureFormat::FindFormat (aCtx, aPixMap->Format(), false);
+ #if defined(GL_ES_VERSION_2_0)
+ // GL_RG32F is not texture-filterable format on OpenGL ES without OES_texture_float_linear extension.
+ // GL_RG16F is texture-filterable since OpenGL ES 3.0 and can be initialized from 32-bit floats.
+ // Note that it is expected that GL_RG16F has enough precision for this table, so that it can be used also on desktop OpenGL.
+ //if (!aCtx->hasTexFloatLinear)
+ aTexFormat.SetInternalFormat (GL_RG16F);
+ #endif
+ if (!aTexFormat.IsValid()
+ || !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TOT_2D, aPixMap.get()))
+ {
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Failed allocation of LUT for PBR");
+ anEnvLUT.Nullify();
+ }
+ aCtx->ShareResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT);
+ }
+ if (!anEnvLUT.IsNull())
+ {
+ anEnvLUT->Bind (aCtx);
+ }
+ myWorkspace->ApplyAspects();
+ }
+ }
+ processPBREnvRequest (aCtx);
+ }
+
// create color and coverage accumulation buffers required for OIT algorithm
if (toUseOit)
{
|| aLightsRevision != myLightsRevision)
{
myLightsRevision = aLightsRevision;
- aManager->UpdateLightSourceStateTo (aLights);
+ aManager->UpdateLightSourceStateTo (aLights, SpecIBLMapLevels());
myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
}
}
#endif
- aManager->SetShadingModel (myShadingModel);
+ aManager->SetShadingModel (OpenGl_ShaderManager::PBRShadingModelFallback (myShadingModel, checkPBRAvailability()));
// Redraw 3d scene
if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
}
return false; // color combination does not exist
}
+
+// =======================================================================
+// function : checkPBRAvailability
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_View::checkPBRAvailability() const
+{
+ return myWorkspace->GetGlContext()->HasPBR()
+ && !myPBREnvironment.IsNull();
+}
+
+// =======================================================================
+// function : bakePBREnvironment
+// purpose :
+// =======================================================================
+void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx)
+{
+ const Handle(OpenGl_TextureSet)& aTextureSet = myCubeMapParams->TextureSet (theCtx);
+ if (!aTextureSet.IsNull()
+ && !aTextureSet->IsEmpty())
+ {
+ myPBREnvironment->Bake (theCtx,
+ aTextureSet->First(),
+ myBackgroundCubeMap->ZIsInverted(),
+ myBackgroundCubeMap->IsTopDown(),
+ myRenderParams.PbrEnvBakingDiffNbSamples,
+ myRenderParams.PbrEnvBakingSpecNbSamples,
+ myRenderParams.PbrEnvBakingProbability);
+ }
+ else
+ {
+ 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;
+}