mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-03 14:10:33 +03:00
0028180: Visualization, TKOpenGl - Performance of Shaded presentation dropped due to FFP disabled by default
FFP state management (light sources, matrices, clipping planes) has been moved to OpenGl_ShaderManager for consistency with Programmable Pipeline. OpenGl_Context::BindProgram() does not re-bind already active Program. OpenGl_PrimitiveArray::Render() does not reset active Program at the end. OpenGl_Context::ApplyModelViewMatrix() now checks if matrix differs from already set one before modifying state in Shader Manager. This allows avoing redundant state changes, matrix uploads onto GPU and re-computation of inversed matrices. NCollection_Mat4 has been extended with equality check operators for proper comparison. OpenGl_ShaderManager - the tracking Material state has been added. Removed unreachable states OPENGL_NS_RESMAT, OPENGL_NS_TEXTURE and OPENGL_NS_WHITEBACK. Fixed resetting FFP material state after displaying GL_COLOR_ARRAY vertices; the Material state within Shader Manager is now invalidated within OpenGl_VertexBuffer::unbindFixedColor(). OpenGl_Workspace::ApplyAspectFace() - fixed invalidating Material State when only Highlighting style is changing.
This commit is contained in:
@@ -2793,6 +2793,10 @@ Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
else if (myActiveProgram == theProgram)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (theProgram.IsNull()
|
||||
|| !theProgram->IsValid())
|
||||
@@ -2843,56 +2847,100 @@ Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(O
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Context::SetShadingMaterial (const OpenGl_AspectFace* theAspect,
|
||||
const Handle(Graphic3d_PresentationAttributes)& theHighlight)
|
||||
const Handle(Graphic3d_PresentationAttributes)& theHighlight,
|
||||
const Standard_Boolean theUseDepthWrite,
|
||||
Standard_Integer& theRenderingPassFlags)
|
||||
{
|
||||
if (!myActiveProgram.IsNull())
|
||||
const Handle(Graphic3d_AspectFillArea3d)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
|
||||
? theHighlight->BasicFillAreaAspect()
|
||||
: theAspect->Aspect();
|
||||
|
||||
const bool toDistinguish = anAspect->Distinguish();
|
||||
const bool toMapTexture = anAspect->ToMapTexture();
|
||||
const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
|
||||
const Graphic3d_MaterialAspect& aMatBackSrc = toDistinguish
|
||||
? anAspect->BackMaterial()
|
||||
: aMatFrontSrc;
|
||||
const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
|
||||
const Quantity_Color& aBackIntColor = toDistinguish
|
||||
? anAspect->BackInteriorColor()
|
||||
: aFrontIntColor;
|
||||
|
||||
myMatFront.Init (aMatFrontSrc, aFrontIntColor);
|
||||
if (toDistinguish)
|
||||
{
|
||||
const Handle(Graphic3d_AspectFillArea3d)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
|
||||
? theHighlight->BasicFillAreaAspect()
|
||||
: theAspect->Aspect();
|
||||
myActiveProgram->SetUniform (this,
|
||||
myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
|
||||
anAspect->ToMapTexture() ? 1 : 0);
|
||||
myActiveProgram->SetUniform (this,
|
||||
myActiveProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
|
||||
anAspect->Distinguish() ? 1 : 0);
|
||||
myMatBack.Init (aMatBackSrc, aBackIntColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
myMatBack = myMatFront;
|
||||
}
|
||||
|
||||
OpenGl_Material aParams;
|
||||
for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
|
||||
// handling transparency
|
||||
float aTranspFront = (float )aMatFrontSrc.Transparency();
|
||||
float aTranspBack = (float )aMatBackSrc .Transparency();
|
||||
if (!theHighlight.IsNull()
|
||||
&& theHighlight->BasicFillAreaAspect().IsNull())
|
||||
{
|
||||
myMatFront.SetColor (theHighlight->ColorRGBA());
|
||||
myMatBack .SetColor (theHighlight->ColorRGBA());
|
||||
aTranspFront = theHighlight->Transparency();
|
||||
aTranspBack = theHighlight->Transparency();
|
||||
}
|
||||
if ((theRenderingPassFlags & OPENGL_NS_2NDPASSDO) != 0)
|
||||
{
|
||||
// second pass
|
||||
myMatFront.Diffuse.a() = aMatFrontSrc.EnvReflexion();
|
||||
myMatBack .Diffuse.a() = aMatBackSrc .EnvReflexion();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aMatFrontSrc.EnvReflexion() != 0.0f
|
||||
|| aMatBackSrc .EnvReflexion() != 0.0f)
|
||||
{
|
||||
const GLint aLoc = myActiveProgram->GetStateLocation (anIndex == 0
|
||||
? OpenGl_OCCT_FRONT_MATERIAL
|
||||
: OpenGl_OCCT_BACK_MATERIAL);
|
||||
if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// if the material reflects the environment scene, the second pass is needed
|
||||
theRenderingPassFlags |= OPENGL_NS_2NDPASSNEED;
|
||||
}
|
||||
|
||||
if (anIndex == 0 || !anAspect->Distinguish())
|
||||
{
|
||||
const Graphic3d_MaterialAspect& aSrcMat = anAspect->FrontMaterial();
|
||||
const Quantity_Color& aSrcIntColor = anAspect->InteriorColor();
|
||||
aParams.Init (aSrcMat, aSrcIntColor);
|
||||
aParams.Diffuse.a() = 1.0f - (float )aSrcMat.Transparency();
|
||||
}
|
||||
else
|
||||
{
|
||||
const Graphic3d_MaterialAspect& aSrcMat = anAspect->BackMaterial();
|
||||
const Quantity_Color& aSrcIntColor = anAspect->BackInteriorColor();
|
||||
aParams.Init (aSrcMat, aSrcIntColor);
|
||||
aParams.Diffuse.a() = 1.0f - (float )aSrcMat.Transparency();
|
||||
}
|
||||
if (!theHighlight.IsNull()
|
||||
&& theHighlight->BasicFillAreaAspect().IsNull())
|
||||
{
|
||||
aParams.SetColor (theHighlight->ColorRGBA());
|
||||
aParams.Diffuse.a() = theHighlight->ColorRGBA().Alpha();
|
||||
}
|
||||
|
||||
myActiveProgram->SetUniform (this, aLoc, OpenGl_Material::NbOfVec4(),
|
||||
aParams.Packed());
|
||||
GLboolean aDepthMask = GL_TRUE;
|
||||
if (aTranspFront != 0.0f
|
||||
|| aTranspBack != 0.0f)
|
||||
{
|
||||
// render transparent
|
||||
myMatFront.Diffuse.a() = 1.0f - aTranspFront;
|
||||
myMatBack .Diffuse.a() = 1.0f - aTranspBack;
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_BLEND);
|
||||
aDepthMask = GL_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// render opaque
|
||||
glBlendFunc (GL_ONE, GL_ZERO);
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
if (theUseDepthWrite)
|
||||
{
|
||||
glDepthMask (aDepthMask);
|
||||
}
|
||||
}
|
||||
|
||||
// do not update material properties in case of zero reflection mode,
|
||||
// because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
|
||||
if (theAspect->IsNoLighting())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (myMatFront == myShaderManager->MaterialState().FrontMaterial()
|
||||
&& myMatBack == myShaderManager->MaterialState().BackMaterial()
|
||||
&& toDistinguish == myShaderManager->MaterialState().ToDistinguish()
|
||||
&& toMapTexture == myShaderManager->MaterialState().ToMapTexture())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, toDistinguish, toMapTexture);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -3206,15 +3254,7 @@ Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_Ha
|
||||
// =======================================================================
|
||||
void OpenGl_Context::ApplyModelWorldMatrix()
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (core11 != NULL)
|
||||
{
|
||||
core11->glMatrixMode (GL_MODELVIEW);
|
||||
core11->glLoadMatrixf (ModelWorldState.Current());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!myShaderManager->IsEmpty())
|
||||
if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
|
||||
{
|
||||
myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
|
||||
}
|
||||
@@ -3226,17 +3266,12 @@ void OpenGl_Context::ApplyModelWorldMatrix()
|
||||
// =======================================================================
|
||||
void OpenGl_Context::ApplyWorldViewMatrix()
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (core11 != NULL)
|
||||
{
|
||||
core11->glMatrixMode (GL_MODELVIEW);
|
||||
core11->glLoadMatrixf (WorldViewState.Current());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!myShaderManager->IsEmpty())
|
||||
if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
|
||||
{
|
||||
myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
|
||||
}
|
||||
if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
|
||||
{
|
||||
myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
|
||||
}
|
||||
}
|
||||
@@ -3247,19 +3282,13 @@ void OpenGl_Context::ApplyWorldViewMatrix()
|
||||
// =======================================================================
|
||||
void OpenGl_Context::ApplyModelViewMatrix()
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (core11 != NULL)
|
||||
{
|
||||
OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
|
||||
core11->glMatrixMode (GL_MODELVIEW);
|
||||
core11->glLoadMatrixf (aModelView.GetData());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!myShaderManager->IsEmpty())
|
||||
if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
|
||||
{
|
||||
myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
|
||||
myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
|
||||
}
|
||||
if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
|
||||
{
|
||||
myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3269,21 +3298,12 @@ void OpenGl_Context::ApplyModelViewMatrix()
|
||||
// =======================================================================
|
||||
void OpenGl_Context::ApplyProjectionMatrix()
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (core11 != NULL)
|
||||
{
|
||||
core11->glMatrixMode (GL_PROJECTION);
|
||||
core11->glLoadMatrixf (ProjectionState.Current().GetData());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!myShaderManager->IsEmpty())
|
||||
if (myShaderManager->ProjectionState().ProjectionMatrix() != ProjectionState.Current())
|
||||
{
|
||||
myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// function : EnableFeatures
|
||||
// purpose :
|
||||
|
Reference in New Issue
Block a user