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; }
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
//! 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; }
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; }
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; }
OpenGl_GraduatedTrihedron.hxx
OpenGl_GraduatedTrihedron.cxx
OpenGl_MapOfZLayerSettings.hxx
+OpenGl_Material.hxx
+OpenGl_MaterialState.hxx
OpenGl_Matrix.hxx
OpenGl_MatrixState.hxx
OpenGl_NamedStatus.hxx
// purpose :
// =======================================================================
OpenGl_Clipping::OpenGl_Clipping ()
-: myEmptyPlaneIds (new NCollection_Shared<Aspect_GenId> (1, 6)),
- myNbClipping (0),
+: myNbClipping (0),
myNbCapping (0),
myNbDisabled (0)
{}
// function : Init
// purpose :
// =======================================================================
-void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes)
+void OpenGl_Clipping::Init (const Standard_Integer )
{
myPlanesGlobal.Nullify();
myPlanesLocal.Nullify();
myNbClipping = 0;
myNbCapping = 0;
myNbDisabled = 0;
- myEmptyPlaneIds = new NCollection_Shared<Aspect_GenId> (1, theMaxPlanes);
}
// =======================================================================
// 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)
{
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)
{
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;
++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)
{
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)
{
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;
// 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)
{
}
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);
// function : RestoreDisabled
// purpose :
// =======================================================================
-void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
+void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
{
if (myNbDisabled == 0)
{
}
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());
}
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())
{
#ifndef _OpenGl_Clipping_H__
#define _OpenGl_Clipping_H__
-#include <Aspect_GenId.hxx>
#include <Graphic3d_SequenceOfHClipPlane.hxx>
#include <NCollection_Vector.hxx>
#include <Standard_TypeDef.hxx>
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
{
return Standard_False;
}
+ else if (myActiveProgram == theProgram)
+ {
+ return Standard_True;
+ }
if (theProgram.IsNull()
|| !theProgram->IsValid())
// 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)
+ {
+ myMatBack.Init (aMatBackSrc, aBackIntColor);
+ }
+ else
{
- 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);
-
- OpenGl_Material aParams;
- for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
- {
- const GLint aLoc = myActiveProgram->GetStateLocation (anIndex == 0
- ? OpenGl_OCCT_FRONT_MATERIAL
- : OpenGl_OCCT_BACK_MATERIAL);
- if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
- {
- continue;
- }
+ myMatBack = myMatFront;
+ }
- 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();
- }
+ // 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)
+ {
+ // if the material reflects the environment scene, the second pass is needed
+ theRenderingPassFlags |= OPENGL_NS_2NDPASSNEED;
+ }
- 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);
}
// =======================================================================
// =======================================================================
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());
}
// =======================================================================
void OpenGl_Context::ApplyWorldViewMatrix()
{
-#if !defined(GL_ES_VERSION_2_0)
- if (core11 != NULL)
+ if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
{
- core11->glMatrixMode (GL_MODELVIEW);
- core11->glLoadMatrixf (WorldViewState.Current());
+ myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
}
-#endif
-
- if (!myShaderManager->IsEmpty())
+ if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
{
- myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
}
}
// =======================================================================
void OpenGl_Context::ApplyModelViewMatrix()
{
-#if !defined(GL_ES_VERSION_2_0)
- if (core11 != NULL)
+ if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
{
- OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
- core11->glMatrixMode (GL_MODELVIEW);
- core11->glLoadMatrixf (aModelView.GetData());
+ myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
}
-#endif
-
- if (!myShaderManager->IsEmpty())
+ if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
{
- myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
- myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
+ myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
}
}
// =======================================================================
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 :
#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>
//! 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.
//! 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);
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)
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:
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__
--- /dev/null
+// 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
--- /dev/null
+// 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
#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
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)
return;
}
+ const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
+ const bool toHilight = theWorkspace->ToHighlight();
myVboAttribs->BindAllAttributes (aGlContext);
if (theHasVertColor && toHilight)
{
// bind with 0
myVboAttribs->UnbindAllAttributes (aGlContext);
-
- if (hasVColors)
- {
- theWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
- }
}
// =======================================================================
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;
{
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
#endif
}
}
-
- aCtx->BindProgram (NULL);
}
// =======================================================================
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
+
}
// =======================================================================
// 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)
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;
}
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
myLightTypeArray[0].Packed());
- theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
return;
}
aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
myLightParamsArray[0].Packed());
}
-
- theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
}
// =======================================================================
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());
{
theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
}
-
- theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
}
// =======================================================================
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());
{
theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
}
-
- theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
}
// =======================================================================
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());
{
theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
}
-
- theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
}
// =======================================================================
}
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)
{
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);
}
// =======================================================================
// =======================================================================
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;
}
#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.
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);
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);
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);
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);
//! 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.
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
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
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
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
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
{
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:
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];
#include <OpenGl_ShaderStates.hxx>
-#include <NCollection_Mat4.hxx>
-
// =======================================================================
// function : OpenGl_StateInterface
// purpose :
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
};
-//! 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
{
// 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
#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());
theWorkspace->TextSubtitleColor(),
theWorkspace->View()->RenderingParams().Resolution);
- aCtx->BindProgram (NULL);
-
// restore aspects
if (!aPrevTexture.IsNull())
{
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());
}
// =======================================================================
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())
#include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderManager.hxx>
#include <Standard_Assert.hxx>
-
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer,OpenGl_Resource)
// =======================================================================
{
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
//! 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
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;
#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 :
{
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;
}
Redraw();
}
+ // reset state for safety
+ aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
+ aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
+
// Swap the buffers
if (toSwap)
{
// 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();
}
// 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;
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);
// 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)
{
}
}
+ // 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
// ==============================================================
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);
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();
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())
#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>
myAspectFaceSet (&myDefaultAspectFace),
myAspectMarkerSet (&myDefaultAspectMarker),
myAspectTextSet (&myDefaultAspectText),
- myAspectFaceAppliedWithHL (false),
//
ViewMatrix_applied (&myDefaultMatrix),
StructureMatrix_applied (&myDefaultMatrix),
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;
}
{
myGlContext->BindDefaultVao();
- NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
+ NamedStatus = 0;
myHighlightStyle.Nullify();
myToAllowFaceCulling = false;
myAspectLineSet = &myDefaultAspectLine;
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 :
}
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();
}
}
- updateMaterial (TEL_FRONT_MATERIAL);
- if (myAspectFaceSet->Aspect()->Distinguish())
+ // 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;
+ }
+ else
{
- updateMaterial (TEL_BACK_MATERIAL);
+ myGlContext->SetShadingMaterial (myAspectFaceSet, myHighlightStyle, myUseDepthWrite, NamedStatus);
}
if (myAspectFaceSet->Aspect()->ToMapTexture())
#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>
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)
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);
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
#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>
{
// 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();