1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +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:
kgv 2016-12-22 12:48:16 +03:00
parent decdee7d3f
commit 8613985b2a
28 changed files with 861 additions and 816 deletions

View File

@ -185,6 +185,20 @@ public:
return std::memcmp (this, myIdentityArray, sizeof (NCollection_Mat4)) == 0;
}
//! Check this matrix for equality with another matrix (without tolerance!).
bool IsEqual (const NCollection_Mat4& theOther) const
{
return std::memcmp (this, &theOther, sizeof(NCollection_Mat4)) == 0;
}
//! Check this matrix for equality with another matrix (without tolerance!).
bool operator== (const NCollection_Mat4& theOther) { return IsEqual (theOther); }
bool operator== (const NCollection_Mat4& theOther) const { return IsEqual (theOther); }
//! Check this matrix for non-equality with another matrix (without tolerance!).
bool operator!= (const NCollection_Mat4& theOther) { return !IsEqual (theOther); }
bool operator!= (const NCollection_Mat4& theOther) const { return !IsEqual (theOther); }
//! Raw access to the data (for OpenGL exchange).
const Element_t* GetData() const { return myMat; }
Element_t* ChangeData() { return myMat; }
@ -456,4 +470,11 @@ Element_t NCollection_Mat4<Element_t>::myIdentityArray[] =
0, 0, 1, 0,
0, 0, 0, 1};
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
#include <type_traits>
static_assert(std::is_trivially_copyable<NCollection_Mat4<float>>::value, "NCollection_Mat4 is not is_trivially_copyable() structure!");
static_assert(std::is_standard_layout <NCollection_Mat4<float>>::value, "NCollection_Mat4 is not is_standard_layout() structure!");
#endif
#endif // _NCollection_Mat4_HeaderFile

View File

@ -72,6 +72,21 @@ public:
//! Alias to 2nd component as Y coordinate in XY.
Element_t& y() { return v[1]; }
//! Check this vector with another vector for equality (without tolerance!).
bool IsEqual (const NCollection_Vec2& theOther) const
{
return v[0] == theOther.v[0]
&& v[1] == theOther.v[1];
}
//! Check this vector with another vector for equality (without tolerance!).
bool operator== (const NCollection_Vec2& theOther) { return IsEqual (theOther); }
bool operator== (const NCollection_Vec2& theOther) const { return IsEqual (theOther); }
//! Check this vector with another vector for non-equality (without tolerance!).
bool operator!= (const NCollection_Vec2& theOther) { return !IsEqual (theOther); }
bool operator!= (const NCollection_Vec2& theOther) const { return !IsEqual (theOther); }
//! Raw access to the data (for OpenGL exchange).
const Element_t* GetData() const { return v; }
Element_t* ChangeData() { return v; }

View File

@ -129,6 +129,22 @@ public:
return *((NCollection_Vec2<Element_t>* )&v[1]);
}
//! Check this vector with another vector for equality (without tolerance!).
bool IsEqual (const NCollection_Vec3& theOther) const
{
return v[0] == theOther.v[0]
&& v[1] == theOther.v[1]
&& v[2] == theOther.v[2];
}
//! Check this vector with another vector for equality (without tolerance!).
bool operator== (const NCollection_Vec3& theOther) { return IsEqual (theOther); }
bool operator== (const NCollection_Vec3& theOther) const { return IsEqual (theOther); }
//! Check this vector with another vector for non-equality (without tolerance!).
bool operator!= (const NCollection_Vec3& theOther) { return !IsEqual (theOther); }
bool operator!= (const NCollection_Vec3& theOther) const { return !IsEqual (theOther); }
//! Raw access to the data (for OpenGL exchange).
const Element_t* GetData() const { return v; }
Element_t* ChangeData() { return v; }

View File

@ -175,6 +175,23 @@ public:
return *((NCollection_Vec3<Element_t>* )&v[1]);
}
//! Check this vector with another vector for equality (without tolerance!).
bool IsEqual (const NCollection_Vec4& theOther) const
{
return v[0] == theOther.v[0]
&& v[1] == theOther.v[1]
&& v[2] == theOther.v[2]
&& v[3] == theOther.v[3];
}
//! Check this vector with another vector for equality (without tolerance!).
bool operator== (const NCollection_Vec4& theOther) { return IsEqual (theOther); }
bool operator== (const NCollection_Vec4& theOther) const { return IsEqual (theOther); }
//! Check this vector with another vector for non-equality (without tolerance!).
bool operator!= (const NCollection_Vec4& theOther) { return !IsEqual (theOther); }
bool operator!= (const NCollection_Vec4& theOther) const { return !IsEqual (theOther); }
//! Raw access to the data (for OpenGL exchange).
const Element_t* GetData() const { return v; }
Element_t* ChangeData() { return v; }

View File

@ -36,6 +36,8 @@ OpenGl_Light.hxx
OpenGl_GraduatedTrihedron.hxx
OpenGl_GraduatedTrihedron.cxx
OpenGl_MapOfZLayerSettings.hxx
OpenGl_Material.hxx
OpenGl_MaterialState.hxx
OpenGl_Matrix.hxx
OpenGl_MatrixState.hxx
OpenGl_NamedStatus.hxx

View File

@ -42,8 +42,7 @@ OpenGl_ClippingIterator::OpenGl_ClippingIterator (const OpenGl_Clipping& theClip
// purpose :
// =======================================================================
OpenGl_Clipping::OpenGl_Clipping ()
: myEmptyPlaneIds (new NCollection_Shared<Aspect_GenId> (1, 6)),
myNbClipping (0),
: myNbClipping (0),
myNbCapping (0),
myNbDisabled (0)
{}
@ -52,7 +51,7 @@ OpenGl_Clipping::OpenGl_Clipping ()
// function : Init
// purpose :
// =======================================================================
void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes)
void OpenGl_Clipping::Init (const Standard_Integer )
{
myPlanesGlobal.Nullify();
myPlanesLocal.Nullify();
@ -60,7 +59,6 @@ void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes)
myNbClipping = 0;
myNbCapping = 0;
myNbDisabled = 0;
myEmptyPlaneIds = new NCollection_Shared<Aspect_GenId> (1, theMaxPlanes);
}
// =======================================================================
@ -105,7 +103,7 @@ void OpenGl_Clipping::SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx,
// function : add
// purpose :
// =======================================================================
void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx,
void OpenGl_Clipping::add (const Handle(OpenGl_Context)& ,
const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
const Standard_Integer theStartIndex)
{
@ -114,18 +112,6 @@ void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx,
return;
}
#if !defined(GL_ES_VERSION_2_0)
const bool toUseFfp = theGlCtx->core11 != NULL
&& theGlCtx->caps->ffpEnable;
if (toUseFfp)
{
// Set either identity or pure view matrix.
theGlCtx->ApplyWorldViewMatrix();
}
#else
(void )theGlCtx;
#endif
Standard_Integer aPlaneId = theStartIndex;
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneId)
{
@ -136,14 +122,6 @@ void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx,
continue;
}
#if !defined(GL_ES_VERSION_2_0)
if (toUseFfp && myEmptyPlaneIds->HasFree())
{
const Standard_Integer anFfpPlaneID = GL_CLIP_PLANE0 + myEmptyPlaneIds->Next();
::glEnable ((GLenum )anFfpPlaneID);
theGlCtx->core11->glClipPlane ((GLenum )anFfpPlaneID, aPlane->GetEquation());
}
#endif
if (aPlane->IsCapping())
{
++myNbCapping;
@ -153,21 +131,13 @@ void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx,
++myNbClipping;
}
}
#if !defined(GL_ES_VERSION_2_0)
// Restore combined model-view matrix.
if (toUseFfp)
{
theGlCtx->ApplyModelViewMatrix();
}
#endif
}
// =======================================================================
// function : remove
// purpose :
// =======================================================================
void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx,
void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& ,
const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
const Standard_Integer theStartIndex)
{
@ -176,13 +146,6 @@ void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx,
return;
}
#if !defined(GL_ES_VERSION_2_0)
const bool toUseFfp = theGlCtx->core11 != NULL
&& theGlCtx->caps->ffpEnable;
#else
(void )theGlCtx;
#endif
Standard_Integer aPlaneIndex = theStartIndex;
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneIndex)
{
@ -193,18 +156,6 @@ void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx,
continue;
}
#if !defined(GL_ES_VERSION_2_0)
const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIndex - 1;
if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
{
if (toUseFfp)
{
::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
}
myEmptyPlaneIds->Free (anFfpPlaneID);
}
#endif
if (aPlane->IsCapping())
{
--myNbCapping;
@ -220,7 +171,7 @@ void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx,
// function : SetEnabled
// purpose :
// =======================================================================
Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& theGlCtx,
Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& ,
const OpenGl_ClippingIterator& thePlane,
const Standard_Boolean theIsEnabled)
{
@ -232,29 +183,6 @@ Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& the
}
isDisabled = !theIsEnabled;
#if !defined(GL_ES_VERSION_2_0)
const bool toUseFfp = theGlCtx->core11 != NULL
&& theGlCtx->caps->ffpEnable;
if (toUseFfp)
{
const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIndex - 1;
if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
{
if (theIsEnabled)
{
::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
}
else
{
::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
}
}
}
#else
(void )theGlCtx;
#endif
if (thePlane.Value()->IsCapping())
{
myNbCapping += (theIsEnabled ? 1 : -1);
@ -271,7 +199,7 @@ Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& the
// function : RestoreDisabled
// purpose :
// =======================================================================
void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
{
if (myNbDisabled == 0)
{
@ -279,12 +207,6 @@ void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
}
myNbDisabled = 0;
#if !defined(GL_ES_VERSION_2_0)
const bool toUseFfp = theGlCtx->core11 != NULL
&& theGlCtx->caps->ffpEnable;
#else
(void )theGlCtx;
#endif
for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
{
Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIter.PlaneIndex());
@ -294,17 +216,6 @@ void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
}
isDisabled = Standard_False;
#if !defined(GL_ES_VERSION_2_0)
if (toUseFfp)
{
const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIter.PlaneIndex() - 1;
if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
{
::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
}
}
#endif
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
if (aPlane->IsCapping())
{

View File

@ -16,7 +16,6 @@
#ifndef _OpenGl_Clipping_H__
#define _OpenGl_Clipping_H__
#include <Aspect_GenId.hxx>
#include <Graphic3d_SequenceOfHClipPlane.hxx>
#include <NCollection_Vector.hxx>
#include <Standard_TypeDef.hxx>
@ -119,7 +118,6 @@ private:
Handle(Graphic3d_SequenceOfHClipPlane) myPlanesLocal; //!< object clipping planes
NCollection_Vector<Standard_Boolean> myDisabledPlanes; //!< ids of disabled planes
NCollection_Vector<Standard_Boolean> mySkipFilter; //!< ids of planes that were disabled before calling ::DisableAllExcept()
Handle(NCollection_Shared<Aspect_GenId>) myEmptyPlaneIds; //!< generator of empty ids for FFP clipping planes
Standard_Integer myNbClipping; //!< number of enabled clipping-only planes (NOT capping)
Standard_Integer myNbCapping; //!< number of enabled capping planes
Standard_Integer myNbDisabled; //!< number of defined but disabled planes

View File

@ -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 :

View File

@ -30,6 +30,7 @@
#include <Message.hxx>
#include <OpenGl_Caps.hxx>
#include <OpenGl_LineAttributes.hxx>
#include <OpenGl_Material.hxx>
#include <OpenGl_MatrixState.hxx>
#include <OpenGl_Vec.hxx>
#include <OpenGl_Resource.hxx>
@ -184,6 +185,8 @@ DEFINE_STANDARD_HANDLE(OpenGl_Context, Standard_Transient)
//! For this reason OpenGl_Context should be initialized and used for each GL context independently.
class OpenGl_Context : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
friend class OpenGl_Window;
public:
//! Function for getting power of to number larger or equal to input number.
@ -624,7 +627,9 @@ public: //! @name methods to alter or retrieve current state
//! Setup current shading material.
Standard_EXPORT void SetShadingMaterial (const OpenGl_AspectFace* theAspect,
const Handle(Graphic3d_PresentationAttributes)& theHighlight = Handle(Graphic3d_PresentationAttributes)());
const Handle(Graphic3d_PresentationAttributes)& theHighlight,
const Standard_Boolean theUseDepthWrite,
Standard_Integer& theRenderingPassFlags);
//! Setup current color.
Standard_EXPORT void SetColor4fv (const OpenGl_Vec4& theColor);
@ -739,6 +744,12 @@ public: //! @name extensions
Standard_Boolean atiMem; //!< GL_ATI_meminfo
Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info
public: //! @name public properties tracking current state
OpenGl_MatrixState<Standard_ShortReal> ModelWorldState; //!< state of orientation matrix
OpenGl_MatrixState<Standard_ShortReal> WorldViewState; //!< state of orientation matrix
OpenGl_MatrixState<Standard_ShortReal> ProjectionState; //!< state of projection matrix
private: // system-dependent fields
#if defined(HAVE_EGL)
@ -812,13 +823,9 @@ private: //! @name fields tracking current state
TCollection_AsciiString myVendor; //!< Graphics Driver's vendor
TColStd_PackedMapOfInteger myFilters[6]; //!< messages suppressing filter (for sources from GL_DEBUG_SOURCE_API_ARB to GL_DEBUG_SOURCE_OTHER_ARB)
Standard_ShortReal myResolutionRatio; //!< scaling factor for parameters like text size
//!< to be properly displayed on device (screen / printer)
public:
OpenGl_MatrixState<Standard_ShortReal> ModelWorldState; //!< state of orientation matrix
OpenGl_MatrixState<Standard_ShortReal> WorldViewState; //!< state of orientation matrix
OpenGl_MatrixState<Standard_ShortReal> ProjectionState; //!< state of projection matrix
//!< to be properly displayed on device (screen / printer)
OpenGl_Material myMatFront; //!< current front material state (cached to reduce GL context updates)
OpenGl_Material myMatBack; //!< current back material state
private:
@ -826,12 +833,6 @@ private:
OpenGl_Context (const OpenGl_Context& );
OpenGl_Context& operator= (const OpenGl_Context& );
public:
DEFINE_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient) // Type definition
friend class OpenGl_Window;
};
#endif // _OpenGl_Context_H__

View File

@ -0,0 +1,77 @@
// Created on: 2011-09-20
// Created by: Sergey ZERCHANINOV
// Copyright (c) 2011-2013 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _OpenGl_Material_Header
#define _OpenGl_Material_Header
#include <Graphic3d_MaterialAspect.hxx>
#include <OpenGl_Vec.hxx>
//! OpenGL material definition
struct OpenGl_Material
{
OpenGl_Vec4 Ambient; //!< ambient reflection coefficient
OpenGl_Vec4 Diffuse; //!< diffuse reflection coefficient
OpenGl_Vec4 Specular; //!< glossy reflection coefficient
OpenGl_Vec4 Emission; //!< material emission
OpenGl_Vec4 Params; //!< extra packed parameters
float Shine() const { return Params.x(); }
float& ChangeShine() { return Params.x(); }
float Transparency() const { return Params.y(); }
float& ChangeTransparency() { return Params.y(); }
//! Set material color.
void SetColor (const OpenGl_Vec4& theColor)
{
// apply the same formula as in Graphic3d_MaterialAspect::SetColor()
Ambient.xyz() = theColor.rgb() * 0.25f;
Diffuse.xyz() = theColor.rgb();
}
//! Initialize material
void Init (const Graphic3d_MaterialAspect& theProp,
const Quantity_Color& theInteriorColor);
//! Returns packed (serialized) representation of material properties
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
static Standard_Integer NbOfVec4() { return 5; }
//! Check this material for equality with another material (without tolerance!).
bool IsEqual (const OpenGl_Material& theOther) const
{
return std::memcmp (this, &theOther, sizeof(OpenGl_Material)) == 0;
}
//! Check this material for equality with another material (without tolerance!).
bool operator== (const OpenGl_Material& theOther) { return IsEqual (theOther); }
bool operator== (const OpenGl_Material& theOther) const { return IsEqual (theOther); }
//! Check this material for non-equality with another material (without tolerance!).
bool operator!= (const OpenGl_Material& theOther) { return !IsEqual (theOther); }
bool operator!= (const OpenGl_Material& theOther) const { return !IsEqual (theOther); }
};
//! Material flag
enum OpenGl_MaterialFlag
{
OpenGl_MaterialFlag_Front, //!< material for front faces
OpenGl_MaterialFlag_Back //!< material for back faces
};
#endif // _OpenGl_Material_Header

View File

@ -0,0 +1,63 @@
// Created on: 2013-10-02
// Created by: Denis BOGOLEPOV
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _OpenGl_MaterialState_HeaderFile
#define _OpenGl_MaterialState_HeaderFile
#include <OpenGl_ShaderStates.hxx>
#include <OpenGl_Material.hxx>
//! Defines generic state of material properties.
class OpenGl_MaterialState : public OpenGl_StateInterface
{
public:
//! Creates new material state.
OpenGl_MaterialState() : myToDistinguish (false), myToMapTexture (false) {}
//! Sets new material aspect.
void Set (const OpenGl_Material& theFrontMat,
const OpenGl_Material& theBackMat,
const bool theToDistinguish,
const bool theToMapTexture)
{
myMatFront = theFrontMat;
myMatBack = theBackMat;
myToDistinguish = theToDistinguish;
myToMapTexture = theToMapTexture;
}
//! Return front material.
const OpenGl_Material& FrontMaterial() const { return myMatFront; }
//! Return back material.
const OpenGl_Material& BackMaterial() const { return myMatBack; }
//! Distinguish front/back flag.
bool ToDistinguish() const { return myToDistinguish; }
//! Flag for mapping a texture.
bool ToMapTexture() const { return myToMapTexture; }
private:
OpenGl_Material myMatFront; //!< front material
OpenGl_Material myMatBack; //!< back material
bool myToDistinguish; //!< distinguish front/back flag
bool myToMapTexture; //!< flag for mapping a texture
};
#endif // _OpenGl_MaterialState_HeaderFile

View File

@ -17,10 +17,7 @@
#define _OpenGl_NamedStatus_Header
// Dynamic fields
#define OPENGL_NS_RESMAT (1<<2)
#define OPENGL_NS_TEXTURE (1<<4)
#define OPENGL_NS_2NDPASSNEED (1<<6)
#define OPENGL_NS_2NDPASSDO (1<<7)
#define OPENGL_NS_WHITEBACK (1<<8)
#endif //_OpenGl_NamedStatus_Header

View File

@ -360,9 +360,6 @@ void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorksp
const Graphic3d_Vec4* theFaceColors,
const Standard_Boolean theHasVertColor) const
{
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
const bool toHilight = theWorkspace->ToHighlight();
bool hasVColors = theHasVertColor && !toHilight;
if (myVboAttribs.IsNull())
{
#if !defined(GL_ES_VERSION_2_0)
@ -375,6 +372,8 @@ void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorksp
return;
}
const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
const bool toHilight = theWorkspace->ToHighlight();
myVboAttribs->BindAllAttributes (aGlContext);
if (theHasVertColor && toHilight)
{
@ -429,11 +428,6 @@ void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorksp
// bind with 0
myVboAttribs->UnbindAllAttributes (aGlContext);
if (hasVColors)
{
theWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
}
}
// =======================================================================
@ -721,20 +715,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
const Standard_Boolean isLightOn = !anAspectFace->IsNoLighting()
&& !myVboAttribs.IsNull()
&& myVboAttribs->HasNormalAttribute();
#if !defined(GL_ES_VERSION_2_0)
// manage FFP lighting
if (aCtx->core11 != NULL)
{
if (!isLightOn)
{
glDisable (GL_LIGHTING);
}
else
{
glEnable (GL_LIGHTING);
}
}
#endif
// Temporarily disable environment mapping
Handle(OpenGl_Texture) aTextureBack;
bool toDrawArray = true;
@ -759,60 +740,67 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
{
const bool toHilight = theWorkspace->ToHighlight();
const Standard_Boolean hasVertColor = hasColorAttrib && !toHilight;
if (aCtx->core20fwd != NULL)
switch (myDrawMode)
{
switch (myDrawMode)
case GL_POINTS:
{
case GL_POINTS:
const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
if (!aSpriteNorm.IsNull()
&& !aSpriteNorm->IsDisplayList())
{
const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
if (!aSpriteNorm.IsNull()
&& !aSpriteNorm->IsDisplayList())
{
const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid())
? anAspectMarker->SpriteHighlightRes (aCtx)
: aSpriteNorm;
theWorkspace->EnableTexture (aSprite);
aCtx->ShaderManager()->BindMarkerProgram (aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
}
else
{
aCtx->ShaderManager()->BindMarkerProgram (NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
}
break;
const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid())
? anAspectMarker->SpriteHighlightRes (aCtx)
: aSpriteNorm;
theWorkspace->EnableTexture (aSprite);
aCtx->ShaderManager()->BindMarkerProgram (aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
}
case GL_LINES:
case GL_LINE_STRIP:
else
{
aCtx->ShaderManager()->BindLineProgram (NULL,
anAspectLine->Aspect()->Type() != Aspect_TOL_SOLID,
isLightOn,
hasVertColor,
anAspectLine->ShaderProgramRes (aCtx));
break;
}
default:
{
const Handle(OpenGl_Texture)& aTexture = theWorkspace->ActiveTexture();
const Standard_Boolean isLightOnFace = isLightOn
&& (aTexture.IsNull()
|| aTexture->GetParams()->IsModulate());
const Standard_Boolean toEnableEnvMap = (!aTexture.IsNull() && (aTexture == theWorkspace->EnvironmentTexture()));
aCtx->ShaderManager()->BindFaceProgram (aTexture,
isLightOnFace,
hasVertColor,
toEnableEnvMap,
anAspectFace->ShaderProgramRes (aCtx));
break;
aCtx->ShaderManager()->BindMarkerProgram (NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
}
break;
}
case GL_LINES:
case GL_LINE_STRIP:
{
aCtx->ShaderManager()->BindLineProgram (NULL,
anAspectLine->Aspect()->Type() != Aspect_TOL_SOLID,
isLightOn,
hasVertColor,
anAspectLine->ShaderProgramRes (aCtx));
break;
}
default:
{
const Handle(OpenGl_Texture)& aTexture = theWorkspace->ActiveTexture();
const Standard_Boolean isLightOnFace = isLightOn
&& (aTexture.IsNull()
|| aTexture->GetParams()->IsModulate());
const Standard_Boolean toEnableEnvMap = (!aTexture.IsNull() && (aTexture == theWorkspace->EnvironmentTexture()));
aCtx->ShaderManager()->BindFaceProgram (aTexture,
isLightOnFace,
hasVertColor,
toEnableEnvMap,
anAspectFace->ShaderProgramRes (aCtx));
break;
}
}
// All primitives should gather material properties from the AspectFace in shading mode
if (isLightOn)
#if !defined(GL_ES_VERSION_2_0)
// manage FFP lighting
if (aCtx->ActiveProgram().IsNull()
&& aCtx->core11 != NULL)
{
aCtx->SetShadingMaterial (anAspectFace, theWorkspace->HighlightStyle());
if (!isLightOn)
{
glDisable (GL_LIGHTING);
}
else
{
glEnable (GL_LIGHTING);
}
}
#endif
if (!theWorkspace->ActiveTexture().IsNull()
&& myDrawMode != GL_POINTS) // transformation is not supported within point sprites
@ -894,8 +882,6 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
#endif
}
}
aCtx->BindProgram (NULL);
}
// =======================================================================

View File

@ -249,6 +249,88 @@ const char THE_FRAG_CLIP_PLANES_2[] =
EOL" discard;"
EOL" }";
#if !defined(GL_ES_VERSION_2_0)
static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
//! Bind FFP light source.
static void bindLight (const OpenGl_Light& theLight,
const GLenum theLightGlId,
const OpenGl_Mat4& theModelView,
OpenGl_Context* theCtx)
{
// the light is a headlight?
if (theLight.IsHeadlight)
{
theCtx->core11->glMatrixMode (GL_MODELVIEW);
theCtx->core11->glLoadIdentity();
}
// setup light type
switch (theLight.Type)
{
case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method
case Graphic3d_TOLS_DIRECTIONAL:
{
// if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
const OpenGl_Vec4 anInfDir = -theLight.Direction;
// to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
break;
}
case Graphic3d_TOLS_POSITIONAL:
{
// to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
theCtx->core11->glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
theCtx->core11->glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
break;
}
case Graphic3d_TOLS_SPOT:
{
const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
theCtx->core11->glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
theCtx->core11->glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
break;
}
}
// restore matrix in case of headlight
if (theLight.IsHeadlight)
{
theCtx->core11->glLoadMatrixf (theModelView.GetData());
}
glEnable (theLightGlId);
}
#endif
}
// =======================================================================
@ -256,7 +338,8 @@ const char THE_FRAG_CLIP_PLANES_2[] =
// purpose : Creates new empty shader manager
// =======================================================================
OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
: myShadingModel (Graphic3d_TOSM_VERTEX),
: myFfpProgram (new OpenGl_ShaderProgramFFP()),
myShadingModel (Graphic3d_TOSM_VERTEX),
myContext (theContext),
myHasLocalOrigin (Standard_False),
myLastView (NULL)
@ -480,54 +563,72 @@ void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldVi
myWorldViewState.Update();
}
// =======================================================================
// function : LightSourceState
// purpose : Returns current state of OCCT light sources
// =======================================================================
const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
{
return myLightSourceState;
}
// =======================================================================
// function : ProjectionState
// purpose : Returns current state of OCCT projection transform
// =======================================================================
const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
{
return myProjectionState;
}
// =======================================================================
// function : ModelWorldState
// purpose : Returns current state of OCCT model-world transform
// =======================================================================
const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
{
return myModelWorldState;
}
// =======================================================================
// function : WorldViewState
// purpose : Returns current state of OCCT world-view transform
// =======================================================================
const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
{
return myWorldViewState;
}
// =======================================================================
// function : PushLightSourceState
// purpose : Pushes state of OCCT light sources to the program
// =======================================================================
void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
{
if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
|| !theProgram->IsValid())
if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
{
return;
}
theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
if (theProgram == myFfpProgram)
{
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 == NULL)
{
return;
}
if (myContext->core11 != NULL)
{
GLenum aLightGlId = GL_LIGHT0;
OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
for (OpenGl_ListOfLight::Iterator aLightIt (*myLightSourceState.LightSources()); aLightIt.More(); aLightIt.Next())
{
const OpenGl_Light& aLight = aLightIt.Value();
if (aLight.Type == Graphic3d_TOLS_AMBIENT)
{
anAmbient += aLight.Color;
continue;
}
else if (aLightGlId > GL_LIGHT7) // OpenGLMaxLights - only 8 lights in OpenGL...
{
continue;
}
bindLight (aLightIt.Value(), aLightGlId, aModelView, myContext);
++aLightGlId;
}
// apply accumulated ambient color
anAmbient.a() = 1.0f;
myContext->core11->glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbient.GetData());
// GL_LIGHTING is managed by drawers to switch between shaded / no lighting output,
// therefore managing the state here does not have any effect - do it just for consistency.
if (aLightGlId != GL_LIGHT0)
{
::glEnable (GL_LIGHTING);
}
else
{
::glDisable (GL_LIGHTING);
}
// switch off unused lights
for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
{
::glDisable (aLightGlId);
}
}
#endif
return;
}
for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
{
myLightTypeArray[aLightIt].Type = -1;
@ -546,7 +647,6 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
myLightTypeArray[0].Packed());
theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
return;
}
@ -615,8 +715,6 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
myLightParamsArray[0].Packed());
}
theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
}
// =======================================================================
@ -630,6 +728,19 @@ void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgra
return;
}
theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
if (theProgram == myFfpProgram)
{
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 != NULL)
{
myContext->core11->glMatrixMode (GL_PROJECTION);
myContext->core11->glLoadMatrixf (myProjectionState.ProjectionMatrix());
}
#endif
return;
}
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
myProjectionState.ProjectionMatrix());
@ -649,8 +760,6 @@ void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgra
{
theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
}
theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
}
// =======================================================================
@ -664,6 +773,21 @@ void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgra
return;
}
theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
if (theProgram == myFfpProgram)
{
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 != NULL)
{
const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
myContext->core11->glMatrixMode (GL_MODELVIEW);
myContext->core11->glLoadMatrixf (aModelView.GetData());
theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
}
#endif
return;
}
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
myModelWorldState.ModelWorldMatrix());
@ -683,8 +807,6 @@ void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgra
{
theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
}
theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
}
// =======================================================================
@ -698,6 +820,21 @@ void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram
return;
}
theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
if (theProgram == myFfpProgram)
{
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 != NULL)
{
const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
myContext->core11->glMatrixMode (GL_MODELVIEW);
myContext->core11->glLoadMatrixf (aModelView.GetData());
theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
}
#endif
return;
}
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
myWorldViewState.WorldViewMatrix());
@ -717,8 +854,6 @@ void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram
{
theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
}
theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
}
// =======================================================================
@ -751,6 +886,77 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
}
theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
if (theProgram == myFfpProgram)
{
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 == NULL)
{
return;
}
const Standard_Integer aNbMaxPlanes = Min (myContext->MaxClipPlanes(), THE_MAX_CLIP_PLANES);
OpenGl_Vec4d anEquations[THE_MAX_CLIP_PLANES];
Standard_Integer aPlaneId = 0;
Standard_Boolean toRestoreModelView = Standard_False;
for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
if (aPlaneIter.IsDisabled())
{
continue;
}
else if (aPlaneId >= aNbMaxPlanes)
{
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
TCollection_ExtendedString("Warning: clipping planes limit (") + aNbMaxPlanes + ") has been exceeded.");
break;
}
const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
OpenGl_Vec4d& aPlaneEq = anEquations[aPlaneId];
aPlaneEq.x() = anEquation.x();
aPlaneEq.y() = anEquation.y();
aPlaneEq.z() = anEquation.z();
aPlaneEq.w() = anEquation.w();
if (myHasLocalOrigin)
{
const gp_XYZ aPos = aPlane->ToPlane().Position().Location().XYZ() - myLocalOrigin;
const Standard_Real aD = -(anEquation.x() * aPos.X() + anEquation.y() * aPos.Y() + anEquation.z() * aPos.Z());
aPlaneEq.w() = aD;
}
const GLenum anFfpPlaneID = GL_CLIP_PLANE0 + aPlaneId;
if (anFfpPlaneID == GL_CLIP_PLANE0)
{
// set either identity or pure view matrix
toRestoreModelView = Standard_True;
myContext->core11->glMatrixMode (GL_MODELVIEW);
myContext->core11->glLoadMatrixf (myWorldViewState.WorldViewMatrix().GetData());
}
::glEnable (anFfpPlaneID);
myContext->core11->glClipPlane (anFfpPlaneID, aPlaneEq);
++aPlaneId;
}
// switch off unused lights
for (; aPlaneId < aNbMaxPlanes; ++aPlaneId)
{
::glDisable (GL_CLIP_PLANE0 + aPlaneId);
}
// restore combined model-view matrix
if (toRestoreModelView)
{
const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
myContext->core11->glLoadMatrixf (aModelView.GetData());
}
#endif
return;
}
const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION)
{
@ -801,17 +1007,81 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
theProgram->SetUniform (myContext, aLocEquations, THE_MAX_CLIP_PLANES, anEquations);
}
// =======================================================================
// function : PushMaterialState
// purpose :
// =======================================================================
void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
{
if (myMaterialState.Index() == theProgram->ActiveState (OpenGl_MATERIAL_STATE))
{
return;
}
const OpenGl_Material& aFrontMat = myMaterialState.FrontMaterial();
const OpenGl_Material& aBackMat = myMaterialState.BackMaterial();
theProgram->UpdateState (OpenGl_MATERIAL_STATE, myMaterialState.Index());
if (theProgram == myFfpProgram)
{
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 == NULL)
{
return;
}
const GLenum aFrontFace = myMaterialState.ToDistinguish() ? GL_FRONT : GL_FRONT_AND_BACK;
myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT, aFrontMat.Ambient.GetData());
myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE, aFrontMat.Diffuse.GetData());
myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR, aFrontMat.Specular.GetData());
myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION, aFrontMat.Emission.GetData());
myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Shine());
if (myMaterialState.ToDistinguish())
{
myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT, aBackMat.Ambient.GetData());
myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE, aBackMat.Diffuse.GetData());
myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR, aBackMat.Specular.GetData());
myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION, aBackMat.Emission.GetData());
myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Shine());
}
#endif
return;
}
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
myMaterialState.ToMapTexture() ? 1 : 0);
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
myMaterialState.ToDistinguish() ? 1 : 0);
const GLint aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL);
if (aLocFront != OpenGl_ShaderProgram::INVALID_LOCATION)
{
theProgram->SetUniform (myContext, aLocFront, OpenGl_Material::NbOfVec4(),
aFrontMat.Packed());
}
const GLint aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_BACK_MATERIAL);
if (aLocBack != OpenGl_ShaderProgram::INVALID_LOCATION)
{
theProgram->SetUniform (myContext, aLocBack, OpenGl_Material::NbOfVec4(),
aBackMat.Packed());
}
}
// =======================================================================
// function : PushState
// purpose : Pushes state of OCCT graphics parameters to the program
// =======================================================================
void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
{
PushClippingState (theProgram);
PushWorldViewState (theProgram);
PushModelWorldState (theProgram);
PushProjectionState (theProgram);
PushLightSourceState (theProgram);
const Handle(OpenGl_ShaderProgram)& aProgram = !theProgram.IsNull() ? theProgram : myFfpProgram;
PushClippingState (aProgram);
PushWorldViewState (aProgram);
PushModelWorldState (aProgram);
PushProjectionState (aProgram);
PushLightSourceState (aProgram);
PushMaterialState (aProgram);
}
// =======================================================================
@ -1776,12 +2046,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
// =======================================================================
Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram)
{
if (!myContext->BindProgram (theProgram))
const Standard_Boolean isBound = myContext->BindProgram (theProgram);
if (isBound
&& !theProgram.IsNull())
{
return Standard_False;
theProgram->ApplyVariables (myContext);
}
theProgram->ApplyVariables (myContext);
PushState (theProgram);
return Standard_True;
return isBound;
}

View File

@ -29,22 +29,19 @@
#include <OpenGl_AspectLine.hxx>
#include <OpenGl_AspectText.hxx>
#include <OpenGl_AspectMarker.hxx>
#include <OpenGl_MaterialState.hxx>
#include <OpenGl_Texture.hxx>
class OpenGl_View;
//! List of shader programs.
typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList;
class OpenGl_ShaderManager;
DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)
//! This class is responsible for managing shader programs.
class OpenGl_ShaderManager : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
friend class OpenGl_ShaderProgram;
public:
//! Creates new empty shader manager.
@ -191,7 +188,7 @@ public:
public:
//! Returns current state of OCCT light sources.
Standard_EXPORT const OpenGl_LightSourceState& LightSourceState() const;
const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
//! Updates state of OCCT light sources.
Standard_EXPORT void UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights);
@ -205,7 +202,7 @@ public:
public:
//! Returns current state of OCCT projection transform.
Standard_EXPORT const OpenGl_ProjectionState& ProjectionState() const;
const OpenGl_ProjectionState& ProjectionState() const { return myProjectionState; }
//! Updates state of OCCT projection transform.
Standard_EXPORT void UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix);
@ -216,7 +213,7 @@ public:
public:
//! Returns current state of OCCT model-world transform.
Standard_EXPORT const OpenGl_ModelWorldState& ModelWorldState() const;
const OpenGl_ModelWorldState& ModelWorldState() const { return myModelWorldState; }
//! Updates state of OCCT model-world transform.
Standard_EXPORT void UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix);
@ -227,7 +224,7 @@ public:
public:
//! Returns current state of OCCT world-view transform.
Standard_EXPORT const OpenGl_WorldViewState& WorldViewState() const;
const OpenGl_WorldViewState& WorldViewState() const { return myWorldViewState; }
//! Updates state of OCCT world-view transform.
Standard_EXPORT void UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix);
@ -246,6 +243,30 @@ public:
//! Pushes current state of OCCT clipping planes to specified program.
Standard_EXPORT void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
public:
//! Returns current state of material.
const OpenGl_MaterialState& MaterialState() const { return myMaterialState; }
//! Updates state of material.
void UpdateMaterialStateTo (const OpenGl_Material& theFrontMat,
const OpenGl_Material& theBackMat,
const bool theToDistinguish,
const bool theToMapTexture)
{
myMaterialState.Set (theFrontMat, theBackMat, theToDistinguish, theToMapTexture);
myMaterialState.Update();
}
//! Updates state of material.
void UpdateMaterialState()
{
myMaterialState.Update();
}
//! Pushes current state of material to specified program.
void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
public:
//! Pushes current state of OCCT graphics parameters to specified program.
@ -418,8 +439,19 @@ protected:
static Standard_Integer NbOfVec2i() { return 1; }
};
//! Fake OpenGL program for tracking FFP state in the way consistent to programmable pipeline.
class OpenGl_ShaderProgramFFP : public OpenGl_ShaderProgram
{
DEFINE_STANDARD_RTTI_INLINE(OpenGl_ShaderProgramFFP, OpenGl_ShaderProgram)
friend class OpenGl_ShaderManager;
protected:
OpenGl_ShaderProgramFFP() {}
};
protected:
Handle(OpenGl_ShaderProgramFFP) myFfpProgram;
Graphic3d_TypeOfShadingModel myShadingModel; //!< lighting shading model
OpenGl_ShaderProgramList myProgramList; //!< The list of shader programs
Handle(OpenGl_SetOfShaderPrograms) myLightPrograms; //!< pointer to active lighting programs matrix
@ -439,6 +471,8 @@ 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_MaterialState myMaterialState; //!< State of Front and Back materials
gp_XYZ myLocalOrigin; //!< local camera transformation
Standard_Boolean myHasLocalOrigin; //!< flag indicating that local camera transformation has been set
@ -449,9 +483,8 @@ private:
const OpenGl_View* myLastView; //!< Pointer to the last view shader manager used with
public:
DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
};
DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)
#endif // _OpenGl_ShaderManager_HeaderFile

View File

@ -477,32 +477,6 @@ Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Contex
return Standard_True;
}
// =======================================================================
// function : ActiveState
// purpose : Returns index of last modification for specified state type
// =======================================================================
Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
{
if (theType < MaxStateTypes)
{
return myCurrentState[theType];
}
return 0;
}
// =======================================================================
// function : UpdateState
// purpose : Updates index of last modification for specified state type
// =======================================================================
void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
const Standard_Size theIndex)
{
if (theType < MaxStateTypes)
{
myCurrentState[theType] = theIndex;
}
}
// =======================================================================
// function : GetUniformLocation
// purpose : Returns location (index) of the specific uniform variable

View File

@ -122,13 +122,11 @@ enum OpenGl_UniformStateType
OpenGl_MODEL_WORLD_STATE,
OpenGl_WORLD_VIEW_STATE,
OpenGl_PROJECTION_STATE,
OpenGl_MATERIALS_STATE,
OpenGl_SURF_DETAIL_STATE
OpenGl_MATERIAL_STATE,
OpenGl_SURF_DETAIL_STATE,
OpenGl_UniformStateType_NB
};
//! Total number of state types.
const int MaxStateTypes = 6;
//! Wrapper for OpenGL program object.
class OpenGl_ShaderProgram : public OpenGl_Resource
{
@ -210,11 +208,22 @@ public:
private:
//! Returns index of last modification of variables of specified state type.
Standard_EXPORT Standard_Size ActiveState (const OpenGl_UniformStateType theType) const;
Standard_Size ActiveState (const OpenGl_UniformStateType theType) const
{
return theType < OpenGl_UniformStateType_NB
? myCurrentState[theType]
: 0;
}
//! Updates index of last modification of variables of specified state type.
Standard_EXPORT void UpdateState (const OpenGl_UniformStateType theType,
const Standard_Size theIndex);
void UpdateState (const OpenGl_UniformStateType theType,
const Standard_Size theIndex)
{
if (theType < OpenGl_UniformStateType_NB)
{
myCurrentState[theType] = theIndex;
}
}
public:
@ -540,7 +549,7 @@ protected:
protected:
Standard_Size myCurrentState[MaxStateTypes]; //!< defines last modification for variables of each state type
Standard_Size myCurrentState[OpenGl_UniformStateType_NB]; //!< defines last modification for variables of each state type
//! Stores locations of OCCT state uniform variables.
GLint myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];

View File

@ -15,8 +15,6 @@
#include <OpenGl_ShaderStates.hxx>
#include <NCollection_Mat4.hxx>
// =======================================================================
// function : OpenGl_StateInterface
// purpose :
@ -190,34 +188,6 @@ const OpenGl_ListOfLight* OpenGl_LightSourceState::LightSources() const
return myLightSources;
}
// =======================================================================
// function : OpenGl_MaterialState
// purpose : Creates uninitialized material state
// =======================================================================
OpenGl_MaterialState::OpenGl_MaterialState (const OpenGl_Element* theAspect)
: myAspect (theAspect)
{
//
}
// =======================================================================
// function : Set
// purpose : Sets new material aspect
// =======================================================================
void OpenGl_MaterialState::Set (const OpenGl_Element* theAspect)
{
myAspect = theAspect;
}
// =======================================================================
// function : Aspect
// purpose : Returns material aspect
// =======================================================================
const OpenGl_Element* OpenGl_MaterialState::Aspect() const
{
return myAspect;
}
// =======================================================================
// function : OpenGl_ClippingState
// purpose : Creates new clipping state

View File

@ -136,26 +136,6 @@ private:
};
//! Defines generic state of OCCT material properties.
class OpenGl_MaterialState : public OpenGl_StateInterface
{
public:
//! Creates new material state.
OpenGl_MaterialState (const OpenGl_Element* theAspect = NULL);
//! Sets new material aspect.
void Set (const OpenGl_Element* theAspect);
//! Returns material aspect.
const OpenGl_Element* Aspect() const;
private:
const OpenGl_Element* myAspect; //!< OCCT material aspect
};
//! Defines generic state of OCCT clipping state.
class OpenGl_ClippingState
{

View File

@ -70,6 +70,9 @@ public:
// Apply line aspect
const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
theWorkspace->GetGlContext()->BindProgram (Handle(OpenGl_ShaderProgram)());
theWorkspace->GetGlContext()->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
glDisable (GL_LIGHTING);
// Use highlight colors

View File

@ -429,10 +429,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
#endif
// Bind custom shader program or generate default version
if (aCtx->core20fwd != NULL)
{
aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
}
aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
myProjMatrix.Convert (aCtx->ProjectionState.Current());
@ -444,8 +441,6 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
theWorkspace->TextSubtitleColor(),
theWorkspace->View()->RenderingParams().Resolution);
aCtx->BindProgram (NULL);
// restore aspects
if (!aPrevTexture.IsNull())
{
@ -569,11 +564,8 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
theCtx->ApplyProjectionMatrix();
}
if (!theCtx->ActiveProgram().IsNull())
{
// Upload updated state to shader program
theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
}
// Upload updated state to shader program
theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
}
// =======================================================================
@ -728,11 +720,9 @@ void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
myBndVertsVbo->Init (theCtx, 2, 4, aQuad[0].GetData());
}
if (theCtx->core20fwd != NULL)
{
// bind flat program
theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_Texture)(), Standard_False, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
}
// bind flat program
theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_Texture)(), Standard_False, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
#if !defined(GL_ES_VERSION_2_0)
if (theCtx->core11 != NULL
&& theCtx->ActiveProgram().IsNull())

View File

@ -15,9 +15,9 @@
#include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <Standard_Assert.hxx>
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer,OpenGl_Resource)
// =======================================================================
@ -235,3 +235,18 @@ bool OpenGl_VertexBuffer::HasNormalAttribute() const
{
return false;
}
#if !defined(GL_ES_VERSION_2_0)
// =======================================================================
// function : unbindFixedColor
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::unbindFixedColor (const Handle(OpenGl_Context)& theCtx)
{
theCtx->core11->glDisableClientState (GL_COLOR_ARRAY);
theCtx->core11fwd->glDisable (GL_COLOR_MATERIAL);
// invalidate FFP material state after GL_COLOR_MATERIAL has modified it (took values from the vertex color)
theCtx->ShaderManager()->UpdateMaterialState();
}
#endif

View File

@ -298,6 +298,10 @@ private:
//! Disable FFP array pointer.
static void unbindFixed (const Handle(OpenGl_Context)& theGlCtx,
const Graphic3d_TypeOfAttribute theMode);
//! Disable FFP color array pointer.
static void unbindFixedColor (const Handle(OpenGl_Context)& theCtx);
#endif
public: //! @name methods for interleaved attributes array

View File

@ -120,12 +120,7 @@ inline void OpenGl_VertexBuffer::unbindFixed (const Handle(OpenGl_Context)& th
case Graphic3d_TOA_POS: theCtx->core11->glDisableClientState (GL_VERTEX_ARRAY); return;
case Graphic3d_TOA_NORM: theCtx->core11->glDisableClientState (GL_NORMAL_ARRAY); return;
case Graphic3d_TOA_UV: theCtx->core11->glDisableClientState (GL_TEXTURE_COORD_ARRAY); return;
case Graphic3d_TOA_COLOR:
{
theCtx->core11->glDisableClientState (GL_COLOR_ARRAY);
theCtx->core11fwd->glDisable (GL_COLOR_MATERIAL);
return;
}
case Graphic3d_TOA_COLOR: unbindFixedColor (theCtx); return;
case Graphic3d_TOA_CUSTOM:
{
return;

View File

@ -38,115 +38,6 @@
#include <OpenGl_Structure.hxx>
#include <OpenGl_ArbFBO.hxx>
#define EPSI 0.0001
namespace
{
static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
}
extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
#if !defined(GL_ES_VERSION_2_0)
//=======================================================================
//function : bindLight
//purpose :
//=======================================================================
static void bindLight (const OpenGl_Light& theLight,
GLenum& theLightGlId,
Graphic3d_Vec4& theAmbientColor,
const Handle(OpenGl_Workspace)& theWorkspace)
{
// Only 8 lights in OpenGL...
if (theLightGlId > GL_LIGHT7)
{
return;
}
if (theLight.Type == Graphic3d_TOLS_AMBIENT)
{
// add RGBA intensity of the ambient light
theAmbientColor += theLight.Color;
return;
}
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
// the light is a headlight?
if (theLight.IsHeadlight)
{
aContext->WorldViewState.Push();
aContext->WorldViewState.SetIdentity();
aContext->ApplyWorldViewMatrix();
}
// setup light type
switch (theLight.Type)
{
case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method
case Graphic3d_TOLS_DIRECTIONAL:
{
// if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
const OpenGl_Vec4 anInfDir = -theLight.Direction;
// to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
break;
}
case Graphic3d_TOLS_POSITIONAL:
{
// to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
break;
}
case Graphic3d_TOLS_SPOT:
{
const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
break;
}
}
// restore matrix in case of headlight
if (theLight.IsHeadlight)
{
aContext->WorldViewState.Pop();
}
glEnable (theLightGlId++);
}
#endif
//=======================================================================
//function : drawBackground
//purpose :
@ -155,9 +46,8 @@ void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
{
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
|| (!myBgTextureArray->IsDefined() // no texture
&& !myBgGradientArray->IsDefined())) // no gradient
if (!myBgTextureArray->IsDefined() // no texture
&& !myBgGradientArray->IsDefined()) // no gradient
{
return;
}
@ -457,6 +347,10 @@ void OpenGl_View::Redraw()
Redraw();
}
// reset state for safety
aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
// Swap the buffers
if (toSwap)
{
@ -603,6 +497,10 @@ void OpenGl_View::RedrawImmediate()
// bind default FBO
bindDefaultFbo();
// reset state for safety
aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
if (toSwap && !aCtx->caps->buffersNoSwap)
{
aCtx->SwapBuffers();
@ -634,7 +532,8 @@ void OpenGl_View::redraw (const Graphic3d_Camera::Projection theProjection, Open
}
// request reset of material
myWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
aCtx->ShaderManager()->UpdateMaterialState();
myWorkspace->UseZBuffer() = Standard_True;
myWorkspace->UseDepthWrite() = Standard_True;
GLbitfield toClear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
@ -648,16 +547,8 @@ void OpenGl_View::redraw (const Graphic3d_Camera::Projection theProjection, Open
glClearDepthf (1.0f);
#endif
if (myWorkspace->NamedStatus & OPENGL_NS_WHITEBACK)
{
// set background to white
glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
}
else
{
const OpenGl_Vec4& aBgColor = myBgColor;
glClearColor (aBgColor.r(), aBgColor.g(), aBgColor.b(), 0.0f);
}
const OpenGl_Vec4& aBgColor = myBgColor;
glClearColor (aBgColor.r(), aBgColor.g(), aBgColor.b(), 0.0f);
glClear (toClear);
@ -874,12 +765,6 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
// before drawing auxiliary stuff (trihedrons, overlayer)
myWorkspace->ResetAppliedAspect();
// We need to disable (unbind) all shaders programs to ensure
// that all objects without specified aspect will be drawn
// correctly (such as background)
aContext->BindProgram (NULL);
// Render trihedron
if (!theToDrawImmediate)
{
@ -898,6 +783,10 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
}
}
// reset FFP state for safety
aContext->BindProgram (Handle(OpenGl_ShaderProgram)());
aContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
// ==============================================================
// Step 6: Keep shader manager informed about last View
// ==============================================================
@ -1049,39 +938,6 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection,
aContext->ShaderManager()->UpdateClippingState();
}
#if !defined(GL_ES_VERSION_2_0)
// Apply Lights
if (aContext->core11 != NULL)
{
// setup lights
Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
THE_DEFAULT_AMBIENT[1],
THE_DEFAULT_AMBIENT[2],
THE_DEFAULT_AMBIENT[3]);
GLenum aLightGlId = GL_LIGHT0;
OpenGl_ListOfLight::Iterator aLightIt (myShadingModel == Graphic3d_TOSM_NONE ? myNoShadingLight : myLights);
for (; aLightIt.More(); aLightIt.Next())
{
bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, myWorkspace);
}
// apply accumulated ambient color
anAmbientColor.a() = 1.0f;
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
if (aLightGlId != GL_LIGHT0)
{
glEnable (GL_LIGHTING);
}
// switch off unused lights
for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
{
glDisable (aLightGlId);
}
}
#endif
// Clear status bitfields
myWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
@ -1565,9 +1421,11 @@ void OpenGl_View::copyBackToFront()
OpenGl_Mat4 aProjectMat;
Graphic3d_TransformUtils::Ortho2D (aProjectMat,
0.f, static_cast<GLfloat> (myWindow->Width()), 0.f, static_cast<GLfloat> (myWindow->Height()));
0.0f, static_cast<GLfloat> (myWindow->Width()),
0.0f, static_cast<GLfloat> (myWindow->Height()));
const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
aCtx->WorldViewState.Push();
aCtx->ProjectionState.Push();
@ -1577,6 +1435,9 @@ void OpenGl_View::copyBackToFront()
aCtx->ApplyProjectionMatrix();
aCtx->ApplyWorldViewMatrix();
// synchronize FFP state before copying pixels
aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
aCtx->DisableFeatures();
switch (aCtx->DrawBuffer())

View File

@ -27,6 +27,7 @@
#include <OpenGl_SceneGeometry.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_Sampler.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_Texture.hxx>
#include <OpenGl_View.hxx>
#include <OpenGl_Window.hxx>
@ -140,7 +141,6 @@ OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Wi
myAspectFaceSet (&myDefaultAspectFace),
myAspectMarkerSet (&myDefaultAspectMarker),
myAspectTextSet (&myDefaultAspectText),
myAspectFaceAppliedWithHL (false),
//
ViewMatrix_applied (&myDefaultMatrix),
StructureMatrix_applied (&myDefaultMatrix),
@ -193,6 +193,13 @@ Standard_Boolean OpenGl_Workspace::Activate()
ResetAppliedAspect();
// reset state for safety
myGlContext->BindProgram (Handle(OpenGl_ShaderProgram)());
if (myGlContext->core20fwd != NULL)
{
myGlContext->core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
}
myGlContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
return Standard_True;
}
@ -204,7 +211,7 @@ void OpenGl_Workspace::ResetAppliedAspect()
{
myGlContext->BindDefaultVao();
NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
NamedStatus = 0;
myHighlightStyle.Nullify();
myToAllowFaceCulling = false;
myAspectLineSet = &myDefaultAspectLine;
@ -563,163 +570,6 @@ Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Text
return aPrevTexture;
}
// =======================================================================
// function : updateMaterial
// purpose :
// =======================================================================
void OpenGl_Workspace::updateMaterial (const int theFlag)
{
// Case of hidden line
if (myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
{
// copy all values including line edge aspect
*myAspectFaceHl.Aspect().operator->() = *myAspectFaceSet->Aspect();
myAspectFaceHl.SetAspectEdge (myAspectFaceSet->AspectEdge());
myAspectFaceHl.Aspect()->SetInteriorColor (myView->BackgroundColor().GetRGB());
myAspectFaceHl.SetNoLighting (true);
myAspectFaceSet = &myAspectFaceHl;
return;
}
const Graphic3d_MaterialAspect* aSrcMat = &myAspectFaceSet->Aspect()->FrontMaterial();
const Quantity_Color* aSrcIntColor = &myAspectFaceSet->Aspect()->InteriorColor();
GLenum aFace = GL_FRONT_AND_BACK;
if (theFlag == TEL_BACK_MATERIAL)
{
aFace = GL_BACK;
aSrcMat = &myAspectFaceSet->Aspect()->BackMaterial();
aSrcIntColor = &myAspectFaceSet->Aspect()->BackInteriorColor();
}
else if (myAspectFaceSet->Aspect()->Distinguish()
&& !(NamedStatus & OPENGL_NS_RESMAT))
{
aFace = GL_FRONT;
}
myMatTmp.Init (*aSrcMat, *aSrcIntColor);
if (!myHighlightStyle.IsNull())
{
myMatTmp.SetColor (myHighlightStyle->ColorRGBA());
}
// handling transparency
if (NamedStatus & OPENGL_NS_2NDPASSDO)
{
// second pass
myMatTmp.Diffuse.a() = aSrcMat->EnvReflexion();
}
else
{
if (aSrcMat->EnvReflexion() != 0.0f)
{
// if the material reflects the environment scene, the second pass is needed
NamedStatus |= OPENGL_NS_2NDPASSNEED;
}
const float aTransp = (float )aSrcMat->Transparency();
if (aTransp != 0.0f)
{
// render transparent
myMatTmp.Diffuse.a() = 1.0f - aTransp;
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
if (myUseDepthWrite)
{
glDepthMask (GL_FALSE);
}
}
else
{
// render opaque
glBlendFunc (GL_ONE, GL_ZERO);
glDisable (GL_BLEND);
if (myUseDepthWrite)
{
glDepthMask (GL_TRUE);
}
}
}
// do not update material properties in case of zero reflection mode,
// because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
if (myAspectFaceSet->IsNoLighting())
{
return;
}
// reset material
if (NamedStatus & OPENGL_NS_RESMAT)
{
#if !defined(GL_ES_VERSION_2_0)
if (myGlContext->core11 != NULL)
{
myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
}
#endif
if (theFlag == TEL_FRONT_MATERIAL)
{
myMatFront = myMatTmp;
myMatBack = myMatTmp;
}
else
{
myMatBack = myMatTmp;
}
NamedStatus &= ~OPENGL_NS_RESMAT;
return;
}
// reduce updates
OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
? myMatFront
: myMatBack;
#if !defined(GL_ES_VERSION_2_0)
if (myGlContext->core11 != NULL)
{
if (myMatTmp.Ambient.r() != anOld.Ambient.r()
|| myMatTmp.Ambient.g() != anOld.Ambient.g()
|| myMatTmp.Ambient.b() != anOld.Ambient.b())
{
myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
}
if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
|| myMatTmp.Diffuse.g() != anOld.Diffuse.g()
|| myMatTmp.Diffuse.b() != anOld.Diffuse.b()
|| fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
{
myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
}
if (myMatTmp.Specular.r() != anOld.Specular.r()
|| myMatTmp.Specular.g() != anOld.Specular.g()
|| myMatTmp.Specular.b() != anOld.Specular.b())
{
myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
}
if (myMatTmp.Emission.r() != anOld.Emission.r()
|| myMatTmp.Emission.g() != anOld.Emission.g()
|| myMatTmp.Emission.b() != anOld.Emission.b())
{
myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
}
if (myMatTmp.Shine() != anOld.Shine())
{
myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
}
}
#endif
anOld = myMatTmp;
if (aFace == GL_FRONT_AND_BACK)
{
myMatBack = myMatTmp;
}
}
// =======================================================================
// function : SetAspectLine
// purpose :
@ -796,11 +646,11 @@ const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace()
}
if (myAspectFaceSet->Aspect() == myAspectFaceApplied
&& !myHighlightStyle.IsNull() == myAspectFaceAppliedWithHL)
&& myHighlightStyle == myAspectFaceAppliedWithHL)
{
return myAspectFaceSet;
}
myAspectFaceAppliedWithHL = !myHighlightStyle.IsNull();
myAspectFaceAppliedWithHL = myHighlightStyle;
#if !defined(GL_ES_VERSION_2_0)
const Aspect_InteriorStyle anIntstyle = myAspectFaceSet->Aspect()->InteriorStyle();
@ -853,10 +703,19 @@ const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace()
}
}
updateMaterial (TEL_FRONT_MATERIAL);
if (myAspectFaceSet->Aspect()->Distinguish())
// Case of hidden line
if (myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
{
updateMaterial (TEL_BACK_MATERIAL);
// copy all values including line edge aspect
*myAspectFaceHl.Aspect().operator->() = *myAspectFaceSet->Aspect();
myAspectFaceHl.SetAspectEdge (myAspectFaceSet->AspectEdge());
myAspectFaceHl.Aspect()->SetInteriorColor (myView->BackgroundColor().GetRGB());
myAspectFaceHl.SetNoLighting (true);
myAspectFaceSet = &myAspectFaceHl;
}
else
{
myGlContext->SetShadingMaterial (myAspectFaceSet, myHighlightStyle, myUseDepthWrite, NamedStatus);
}
if (myAspectFaceSet->Aspect()->ToMapTexture())

View File

@ -21,6 +21,7 @@
#include <OpenGl_AspectFace.hxx>
#include <OpenGl_CappingAlgo.hxx>
#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_Material.hxx>
#include <OpenGl_Matrix.hxx>
#include <OpenGl_NamedStatus.hxx>
#include <OpenGl_RenderFilter.hxx>
@ -34,40 +35,6 @@
class OpenGl_View;
class Image_PixMap;
//! OpenGL material definition
struct OpenGl_Material
{
OpenGl_Vec4 Ambient; //!< ambient reflection coefficient
OpenGl_Vec4 Diffuse; //!< diffuse reflection coefficient
OpenGl_Vec4 Specular; //!< glossy reflection coefficient
OpenGl_Vec4 Emission; //!< material emission
OpenGl_Vec4 Params; //!< extra packed parameters
Standard_ShortReal Shine() const { return Params.x(); }
Standard_ShortReal& ChangeShine() { return Params.x(); }
Standard_ShortReal Transparency() const { return Params.y(); }
Standard_ShortReal& ChangeTransparency() { return Params.y(); }
//! Set material color.
void SetColor (const OpenGl_Vec4& theColor)
{
// apply the same formula as in Graphic3d_MaterialAspect::SetColor()
Ambient.xyz() = theColor.rgb() * 0.25f;
Diffuse.xyz() = theColor.rgb();
}
//! Initialize material
void Init (const Graphic3d_MaterialAspect& theProp,
const Quantity_Color& theInteriorColor);
//! Returns packed (serialized) representation of material properties
const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
static Standard_Integer NbOfVec4() { return 5; }
};
class OpenGl_RaytraceFilter;
DEFINE_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
@ -335,14 +302,6 @@ public:
protected:
enum
{
TEL_FRONT_MATERIAL = 1,
TEL_BACK_MATERIAL = 2
};
void updateMaterial (const int theFlag);
void setTextureParams (Handle(OpenGl_Texture)& theTexture,
const Handle(Graphic3d_TextureParams)& theParams);
@ -367,14 +326,11 @@ protected: //! @name fields related to status
const OpenGl_AspectMarker* myAspectMarkerSet;
Handle(Graphic3d_AspectMarker3d) myAspectMarkerApplied;
const OpenGl_AspectText* myAspectTextSet;
bool myAspectFaceAppliedWithHL;
Handle(Graphic3d_PresentationAttributes) myAspectFaceAppliedWithHL;
const OpenGl_Matrix* ViewMatrix_applied;
const OpenGl_Matrix* StructureMatrix_applied;
OpenGl_Material myMatFront; //!< current front material state (cached to reduce GL context updates)
OpenGl_Material myMatBack; //!< current back material state
OpenGl_Material myMatTmp; //!< temporary variable
bool myToAllowFaceCulling; //!< allow back face culling
Handle(Graphic3d_PresentationAttributes) myHighlightStyle; //!< active highlight style

View File

@ -30,6 +30,7 @@
#include <OpenGl_Element.hxx>
#include <OpenGl_GlCore20.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_Workspace.hxx>
#include <OSD_Environment.hxx>
#include <OSD_File.hxx>
@ -156,7 +157,8 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
{
// this sample does not use GLSL programs - make sure it is disabled
Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
aCtx->BindProgram (NULL);
aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
// To test linking against OpenGl_Workspace and all aspect classes
const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker();