diff --git a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx index 5550e3faa5..f45397a018 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx @@ -21,6 +21,15 @@ #include #include +IMPLEMENT_STANDARD_HANDLE (Graphic3d_Buffer, NCollection_Buffer) +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Buffer, NCollection_Buffer) + +IMPLEMENT_STANDARD_HANDLE (Graphic3d_BoundBuffer, NCollection_Buffer) +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_BoundBuffer, NCollection_Buffer) + +IMPLEMENT_STANDARD_HANDLE (Graphic3d_IndexBuffer, Graphic3d_Buffer) +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_IndexBuffer, Graphic3d_Buffer) + Graphic3d_ArrayOfPrimitives::Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOfPrimitiveArray theType, const Standard_Integer theMaxVertexs, const Standard_Integer theMaxBounds, diff --git a/src/Graphic3d/Graphic3d_BoundBuffer.hxx b/src/Graphic3d/Graphic3d_BoundBuffer.hxx index 7c93703020..4c92734a48 100644 --- a/src/Graphic3d/Graphic3d_BoundBuffer.hxx +++ b/src/Graphic3d/Graphic3d_BoundBuffer.hxx @@ -63,8 +63,12 @@ public: Standard_Integer* Bounds; //!< pointer to bounds array Standard_Integer NbBounds; //!< number of bounds +public: + + DEFINE_STANDARD_RTTI(Graphic3d_BoundBuffer) // Type definition + }; -typedef NCollection_Handle Handle(Graphic3d_BoundBuffer); +DEFINE_STANDARD_HANDLE(Graphic3d_BoundBuffer, NCollection_Buffer) #endif // _Graphic3d_BoundBuffer_HeaderFile diff --git a/src/Graphic3d/Graphic3d_Buffer.hxx b/src/Graphic3d/Graphic3d_Buffer.hxx index d16efe68e9..de4f1ae6c7 100644 --- a/src/Graphic3d/Graphic3d_Buffer.hxx +++ b/src/Graphic3d/Graphic3d_Buffer.hxx @@ -201,8 +201,12 @@ public: Standard_Integer NbElements; //!< number of the elements Standard_Integer NbAttributes; //!< number of vertex attributes +public: + + DEFINE_STANDARD_RTTI(Graphic3d_Buffer) // Type definition + }; -typedef NCollection_Handle Handle(Graphic3d_Buffer); +DEFINE_STANDARD_HANDLE(Graphic3d_Buffer, NCollection_Buffer) #endif // _Graphic3d_Buffer_HeaderFile diff --git a/src/Graphic3d/Graphic3d_IndexBuffer.hxx b/src/Graphic3d/Graphic3d_IndexBuffer.hxx index ec69dfc49b..a8d5dd3049 100644 --- a/src/Graphic3d/Graphic3d_IndexBuffer.hxx +++ b/src/Graphic3d/Graphic3d_IndexBuffer.hxx @@ -70,8 +70,12 @@ public: } } +public: + + DEFINE_STANDARD_RTTI(Graphic3d_IndexBuffer) // Type definition + }; -typedef NCollection_Handle Handle(Graphic3d_IndexBuffer); +DEFINE_STANDARD_HANDLE(Graphic3d_IndexBuffer, Graphic3d_Buffer) #endif // _Graphic3d_IndexBuffer_HeaderFile diff --git a/src/Image/Image_PixMap.cxx b/src/Image/Image_PixMap.cxx index e0558e85e2..61cac86dad 100644 --- a/src/Image/Image_PixMap.cxx +++ b/src/Image/Image_PixMap.cxx @@ -21,6 +21,9 @@ IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient) IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient) +IMPLEMENT_STANDARD_HANDLE (Image_PixMapData, NCollection_Buffer) +IMPLEMENT_STANDARD_RTTIEXT(Image_PixMapData, NCollection_Buffer) + // ======================================================================= // function : Image_PixMap // purpose : diff --git a/src/Image/Image_PixMapData.hxx b/src/Image/Image_PixMapData.hxx index 155ee61d97..2f46f7d302 100644 --- a/src/Image/Image_PixMapData.hxx +++ b/src/Image/Image_PixMapData.hxx @@ -124,8 +124,13 @@ public: Standard_Size SizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX) Standard_Size TopToDown; //!< image scanlines direction in memory from Top to the Down + +public: + + DEFINE_STANDARD_RTTI(Image_PixMapData) // Type definition + }; -typedef NCollection_Handle Handle(Image_PixMapData); +DEFINE_STANDARD_HANDLE(Image_PixMapData, NCollection_Buffer) #endif // _Image_PixMapData_H__ diff --git a/src/NCollection/NCollection_AlignedAllocator.cxx b/src/NCollection/NCollection_AlignedAllocator.cxx index 5a9680ea9a..7b4831de15 100644 --- a/src/NCollection/NCollection_AlignedAllocator.cxx +++ b/src/NCollection/NCollection_AlignedAllocator.cxx @@ -14,10 +14,14 @@ // commercial license or contractual agreement. #include +#include IMPLEMENT_STANDARD_HANDLE (NCollection_AlignedAllocator, NCollection_BaseAllocator) IMPLEMENT_STANDARD_RTTIEXT (NCollection_AlignedAllocator, NCollection_BaseAllocator) +IMPLEMENT_STANDARD_HANDLE (NCollection_Buffer, Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT (NCollection_Buffer, Standard_Transient) + //======================================================================= //function : NCollection_AlignedAllocator() //purpose : Constructor diff --git a/src/NCollection/NCollection_Buffer.hxx b/src/NCollection/NCollection_Buffer.hxx index 61d2cea9c5..2210127d23 100644 --- a/src/NCollection/NCollection_Buffer.hxx +++ b/src/NCollection/NCollection_Buffer.hxx @@ -17,10 +17,10 @@ #define _NCollection_Buffer_HeaderFile #include -#include +#include //! Low-level buffer object. -class NCollection_Buffer +class NCollection_Buffer : public Standard_Transient { public: @@ -128,8 +128,12 @@ protected: Standard_Size mySize; //!< buffer length in bytes Handle(NCollection_BaseAllocator) myAllocator; //!< buffer allocator +public: + + DEFINE_STANDARD_RTTI(NCollection_Buffer) // Type definition + }; -typedef NCollection_Handle Handle(NCollection_Buffer); +DEFINE_STANDARD_HANDLE(NCollection_Buffer, Standard_Transient) #endif // _NCollection_Buffer_HeaderFile diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index bf9ffb2615..d8ab579bc2 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -117,8 +117,11 @@ OpenGl_TextureBufferArb.hxx OpenGl_TextureBufferArb.cxx OpenGl_Vec.hxx OpenGl_VertexBuffer.hxx +OpenGl_VertexBuffer.lxx OpenGl_VertexBuffer.cxx OpenGl_VertexBufferEditor.hxx +OpenGl_VertexBufferCompat.hxx +OpenGl_VertexBufferCompat.cxx OpenGl_RenderFilter.hxx OpenGl_RenderFilter.cxx OpenGl_CappingAlgo.hxx diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index c35f712708..000304beaa 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -110,9 +110,9 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) myMaxClipPlanes (6), myGlVerMajor (0), myGlVerMinor (0), - myRenderMode (GL_RENDER), myIsInitialized (Standard_False), myIsStereoBuffers (Standard_False), + myRenderMode (GL_RENDER), myDrawBuffer (0) { #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX) @@ -1976,3 +1976,24 @@ void OpenGl_Context::ReleaseDelayed() myDelayed->UnBind (aDeadList.Value (anIter)); } } + +// ======================================================================= +// function : BindProgram +// purpose : +// ======================================================================= +void OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram) +{ + if (theProgram.IsNull() + || !theProgram->IsValid()) + { + if (!myActiveProgram.IsNull()) + { + core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM); + myActiveProgram.Nullify(); + } + return; + } + + myActiveProgram = theProgram; + core20fwd->glUseProgram (theProgram->ProgramId()); +} diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index 0adac0b87e..5d8e292e1d 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -352,6 +353,13 @@ public: //! @return value for GL_MAX_CLIP_PLANES Standard_EXPORT Standard_Integer MaxClipPlanes() const; + //! Returns true if VBO is supported and permitted. + inline bool ToUseVbo() const + { + return core15fwd != NULL + && !caps->vboDisable; + } + public: //! @return messenger instance @@ -381,6 +389,8 @@ public: return myIsStereoBuffers; } +public: //! @name methods to alter or retrieve current state + //! Switch to left stereographic rendering buffer. //! This method can be used to keep unchanged choise //! of front/back/both buffer rendering. @@ -402,6 +412,16 @@ public: //! OpenGl state variables has a possibility of being out-of-date. Standard_EXPORT void FetchState(); + //! @return active GLSL program + const Handle(OpenGl_ShaderProgram)& ActiveProgram() const + { + return myActiveProgram; + } + + //! Bind specified program to current context, + //! or unbind previous one when NULL specified. + Standard_EXPORT void BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram); + private: //! Wrapper to system function to retrieve GL function pointer by name. @@ -490,13 +510,17 @@ private: // context info Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES Standard_Integer myGlVerMajor; //!< cached GL version major number Standard_Integer myGlVerMinor; //!< cached GL version minor number - Standard_Integer myRenderMode; //!< value for active rendering mode Standard_Boolean myIsInitialized; //!< flag indicates initialization state Standard_Boolean myIsStereoBuffers; //!< context supports stereo buffering - Standard_Integer myDrawBuffer; //!< current draw buffer. Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs +private: //! @name fields tracking current state + + Handle(OpenGl_ShaderProgram) myActiveProgram; //!< currently active GLSL program + Standard_Integer myRenderMode; //!< value for active rendering mode + Standard_Integer myDrawBuffer; //!< current draw buffer + private: //! Copying allowed only within Handles diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 05071382c3..766acf788c 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -22,22 +22,24 @@ #include #include #include +#include #include namespace { template - void BindProgramWithMaterial (const Handle(OpenGl_Workspace)& theWS, - const T* theAspect) + const Handle(OpenGl_ShaderProgram)& bindProgram (const Handle(OpenGl_Workspace)& theWS, + const T* theAspect) { - const Handle(OpenGl_Context)& aCtx = theWS->GetGlContext(); + const Handle(OpenGl_Context)& aCtx = theWS->GetGlContext(); const Handle(OpenGl_ShaderProgram)& aProgram = theAspect->ShaderProgramRes (theWS); + aCtx->BindProgram (aProgram); if (aProgram.IsNull()) { - OpenGl_ShaderProgram::Unbind (aCtx); - return; + return aCtx->ActiveProgram(); } - aProgram->BindWithVariables (aCtx); + + aProgram->ApplyVariables (aCtx); const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram); if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect) @@ -46,6 +48,28 @@ namespace } aCtx->ShaderManager()->PushState (aProgram); + return aProgram; + } + + inline const Handle(OpenGl_ShaderProgram)& bindProgram (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_AspectFace* theAspectFace, + const OpenGl_AspectLine* theAspectLine, + const OpenGl_AspectMarker* theAspectMarker, + const GLint theDrawMode) + { + if (!theWorkspace->GetGlContext()->IsGlGreaterEqual (2, 0)) + { + return theWorkspace->GetGlContext()->ActiveProgram(); + } + switch (theDrawMode) + { + case GL_POINTS: + return bindProgram (theWorkspace, theAspectMarker); + case GL_LINES: + case GL_LINE_STRIP: + return bindProgram (theWorkspace, theAspectLine); + } + return bindProgram (theWorkspace, theAspectFace); } //! Convert index data type from size @@ -91,8 +115,8 @@ namespace } //! Auxiliary template for VBO with interleaved attributes. -template -class OpenGl_VertexBufferT : public OpenGl_VertexBuffer +template +class OpenGl_VertexBufferT : public TheBaseClass { public: @@ -125,16 +149,29 @@ public: return false; } - virtual void BindFixedPosition (const Handle(OpenGl_Context)& theGlCtx) const + virtual bool HasNormalAttribute() const { - if (!IsValid()) + for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) + { + const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; + if (anAttrib.Id == Graphic3d_TOA_NORM) + { + return true; + } + } + return false; + } + + virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const + { + if (!TheBaseClass::IsValid()) { return; } - Bind (theGlCtx); + TheBaseClass::Bind (theGlCtx); GLint aNbComp; - const GLubyte* anOffset = NULL; + const GLubyte* anOffset = TheBaseClass::myOffset; for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) { const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; @@ -145,7 +182,7 @@ public: } else if (anAttrib.Id == Graphic3d_TOA_POS) { - bindFixed (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset); + TheBaseClass::bindAttribute (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset); break; } @@ -153,16 +190,16 @@ public: } } - virtual void BindFixed (const Handle(OpenGl_Context)& theGlCtx) const + virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const { - if (!IsValid()) + if (!TheBaseClass::IsValid()) { return; } - Bind (theGlCtx); + TheBaseClass::Bind (theGlCtx); GLint aNbComp; - const GLubyte* anOffset = NULL; + const GLubyte* anOffset = TheBaseClass::myOffset; for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) { const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; @@ -172,23 +209,23 @@ public: continue; } - bindFixed (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset); + TheBaseClass::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset); anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType); } } - virtual void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx) const + virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const { - if (!IsValid()) + if (!TheBaseClass::IsValid()) { return; } - Unbind (theGlCtx); + TheBaseClass::Unbind (theGlCtx); for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) { const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; - unbindFixed (theGlCtx, anAttrib.Id); + TheBaseClass::unbindAttribute (theGlCtx, anAttrib.Id); } } @@ -218,399 +255,316 @@ void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCt } // ======================================================================= -// function : BuildVBO +// function : initNormalVbo // purpose : // ======================================================================= -Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const +Standard_Boolean OpenGl_PrimitiveArray::initNormalVbo (const Handle(OpenGl_Context)& theCtx) const { - const Handle(OpenGl_Context)& aGlCtx = theWorkspace->GetGlContext(); + switch (myAttribs->NbAttributes) + { + case 1: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 2: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 3: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 4: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 5: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 6: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 7: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 8: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 9: myVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 10: myVboAttribs = new OpenGl_VertexBufferT(*myAttribs); break; + } + + if (!myVboAttribs->init (theCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride)) + { + TCollection_ExtendedString aMsg; + aMsg += "VBO creation for Primitive Array has failed for "; + aMsg += myAttribs->NbElements; + aMsg += " vertices. Out of memory?"; + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg); + + clearMemoryGL (theCtx); + return Standard_False; + } + else if (myIndices.IsNull()) + { + return Standard_True; + } + + myVboIndices = new OpenGl_IndexBuffer(); + bool isOk = false; + switch (myIndices->Stride) + { + case 2: + { + isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast (myIndices->Data())); + break; + } + case 4: + { + isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast (myIndices->Data())); + break; + } + default: + { + clearMemoryGL (theCtx); + return Standard_False; + } + } + if (!isOk) + { + TCollection_ExtendedString aMsg; + aMsg += "VBO creation for Primitive Array has failed for "; + aMsg += myIndices->NbElements; + aMsg += " indices. Out of memory?"; + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg); + clearMemoryGL (theCtx); + return Standard_False; + } + return Standard_True; +} + +// ======================================================================= +// function : buildVBO +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)& theCtx, + const Standard_Boolean theToKeepData) const +{ + bool isNormalMode = theCtx->ToUseVbo(); if (myAttribs.IsNull() || myAttribs->IsEmpty() - || myAttribs->NbElements < 1) + || myAttribs->NbElements < 1 + || myAttribs->NbAttributes < 1 + || myAttribs->NbAttributes > 10) { // vertices should be always defined - others are optional return Standard_False; } + if (isNormalMode + && initNormalVbo (theCtx)) + { + if (!theCtx->caps->keepArrayData + && !theToKeepData) + { + myIndices.Nullify(); + myAttribs.Nullify(); + } + return Standard_True; + } + + Handle(OpenGl_VertexBufferCompat) aVboAttribs; switch (myAttribs->NbAttributes) { - case 1: myVboAttribs = new OpenGl_VertexBufferT<1> (*myAttribs); break; - case 2: myVboAttribs = new OpenGl_VertexBufferT<2> (*myAttribs); break; - case 3: myVboAttribs = new OpenGl_VertexBufferT<3> (*myAttribs); break; - case 4: myVboAttribs = new OpenGl_VertexBufferT<4> (*myAttribs); break; - case 5: myVboAttribs = new OpenGl_VertexBufferT<5> (*myAttribs); break; - case 6: myVboAttribs = new OpenGl_VertexBufferT<6> (*myAttribs); break; - case 7: myVboAttribs = new OpenGl_VertexBufferT<7> (*myAttribs); break; - case 8: myVboAttribs = new OpenGl_VertexBufferT<8> (*myAttribs); break; - case 9: myVboAttribs = new OpenGl_VertexBufferT<9> (*myAttribs); break; - case 10: myVboAttribs = new OpenGl_VertexBufferT<10>(*myAttribs); break; - default: return Standard_False; + case 1: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 2: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 3: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 4: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 5: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 6: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 7: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 8: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 9: aVboAttribs = new OpenGl_VertexBufferT (*myAttribs); break; + case 10: aVboAttribs = new OpenGl_VertexBufferT(*myAttribs); break; } - - if (!myVboAttribs->init (aGlCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride)) - { - clearMemoryGL (aGlCtx); - return Standard_False; - } - + aVboAttribs->initLink (myAttribs, 0, myAttribs->NbElements, GL_NONE); if (!myIndices.IsNull()) { - myVboIndices = new OpenGl_IndexBuffer(); - bool isOk = Standard_False; + Handle(OpenGl_VertexBufferCompat) aVboIndices = new OpenGl_VertexBufferCompat(); switch (myIndices->Stride) { case 2: { - isOk = myVboIndices->Init (aGlCtx, 1, myIndices->NbElements, reinterpret_cast (myIndices->Data())); + aVboIndices->initLink (myIndices, 1, myIndices->NbElements, GL_UNSIGNED_SHORT); break; } case 4: { - isOk = myVboIndices->Init (aGlCtx, 1, myIndices->NbElements, reinterpret_cast (myIndices->Data())); + aVboIndices->initLink (myIndices, 1, myIndices->NbElements, GL_UNSIGNED_INT); break; } - default: break; - } - if (!isOk) - { - clearMemoryGL (aGlCtx); - return Standard_False; + default: + { + return Standard_False; + } } + myVboIndices = aVboIndices; + } + myVboAttribs = aVboAttribs; + if (!theCtx->caps->keepArrayData + && !theToKeepData) + { + // does not make sense for compatibility mode + //myIndices.Nullify(); + //myAttribs.Nullify(); } - if (!aGlCtx->caps->keepArrayData) - { - myIndices.Nullify(); - myAttribs.Nullify(); - } - return Standard_True; } // ======================================================================= -// function : DrawArray +// function : drawArray // purpose : // ======================================================================= -void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel, - const Aspect_InteriorStyle theInteriorStyle, - Tint theEdgeFlag, - const TEL_COLOUR* theInteriorColour, - const TEL_COLOUR* theLineColour, - const TEL_COLOUR* theEdgeColour, - const Handle(OpenGl_Workspace)& theWorkspace) const +void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorkspace, + const Graphic3d_Vec4* theFaceColors) const { const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext(); - const Graphic3d_Vec4* aFaceColors = myBounds.IsNull() ? NULL : myBounds->Colors; const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0; bool hasVColors = false; - - glColor3fv (myDrawMode <= GL_LINE_STRIP ? theLineColour->rgb : theInteriorColour->rgb); - - // Temporarily disable environment mapping - if (myDrawMode <= GL_LINE_STRIP) + if (myVboAttribs.IsNull()) { - glPushAttrib (GL_ENABLE_BIT); - glDisable (GL_TEXTURE_1D); - glDisable (GL_TEXTURE_2D); + if (myDrawMode == GL_POINTS) + { + // extreme compatibility mode - without sprites but with markers + drawMarkers (theWorkspace); + } + return; } - if ((myDrawMode > GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) || - (myDrawMode <= GL_LINE_STRIP)) + myVboAttribs->BindAllAttributes (aGlContext); + if (myVboAttribs->HasColorAttribute()) { if (toHilight) { - aFaceColors = NULL; - } - - if (theInteriorStyle == Aspect_IS_HIDDENLINE) - { - theEdgeFlag = 1; - aFaceColors = NULL; - } - - // Sometimes the GL_LIGHTING mode is activated here - // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary - // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism* - if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP) - glDisable (GL_LIGHTING); - else - glEnable (GL_LIGHTING); - - if (!myVboAttribs.IsNull()) - { - myVboAttribs->BindFixed (aGlContext); - if (myVboAttribs->HasColorAttribute()) - { - if (toHilight) - { - // disable per-vertex colors - OpenGl_VertexBuffer::unbindFixed (aGlContext, Graphic3d_TOA_COLOR); - } - else - { - hasVColors = true; - } - } - if (!myVboIndices.IsNull()) - { - myVboIndices->Bind (aGlContext); - if (!myBounds.IsNull()) - { - // draw primitives by vertex count with the indices - const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); - GLubyte* anOffset = NULL; - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData()); - glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset); - anOffset += aStride * aNbElemsInGroup; - } - } - else - { - // draw one (or sequential) primitive by the indices - glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), NULL); - } - myVboIndices->Unbind (aGlContext); - } - else if (!myBounds.IsNull()) - { - GLint aFirstElem = 0; - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData()); - glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); - aFirstElem += aNbElemsInGroup; - } - } - else - { - if (myDrawMode == GL_POINTS) - { - DrawMarkers (theWorkspace); - } - else - { - glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb()); - } - } - - // bind with 0 - myVboAttribs->UnbindFixed (aGlContext); + // disable per-vertex colors + OpenGl_VertexBuffer::unbindAttribute (aGlContext, Graphic3d_TOA_COLOR); } else { - GLint aNbComp; - for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter) - { - const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter); - if (anAttrib.Id == Graphic3d_TOA_COLOR) - { - if (toHilight) - { - continue; - } - hasVColors = true; - } - const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp); - const GLvoid* aData = myAttribs->Data (anAttribIter); - if (aDataType == GL_NONE) - { - continue; - } - - OpenGl_VertexBuffer::bindFixed (aGlContext, anAttrib.Id, aNbComp, aDataType, myAttribs->Stride, aData); - } - - if (!myBounds.IsNull()) - { - GLint aFirstElem = 0; - if (!myIndices.IsNull()) - { - const GLenum anIndexType = toGlIndexType (myIndices->Stride); - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData()); - glDrawElements (myDrawMode, aNbElemsInGroup, anIndexType, myIndices->value (aFirstElem)); - aFirstElem += aNbElemsInGroup; - } - } - else - { - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData()); - glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); - aFirstElem += aNbElemsInGroup; - } - } - } - else if (!myIndices.IsNull()) - { - glDrawElements (myDrawMode, myIndices->NbElements, toGlIndexType (myIndices->Stride), myIndices->Data()); - } - else - { - if (myDrawMode == GL_POINTS) - { - DrawMarkers (theWorkspace); - } - else - { - glDrawArrays (myDrawMode, 0, myAttribs->NbElements); - } - } - - for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter) - { - const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter); - OpenGl_VertexBuffer::unbindFixed (aGlContext, anAttrib.Id); - } + hasVColors = true; } } + if (!myVboIndices.IsNull()) + { + myVboIndices->Bind (aGlContext); + GLubyte* anOffset = myVboIndices->GetDataOffset(); + if (!myBounds.IsNull()) + { + // draw primitives by vertex count with the indices + const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); + for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) + { + const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; + if (theFaceColors != NULL) glColor3fv (theFaceColors[aGroupIter].GetData()); + glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset); + anOffset += aStride * aNbElemsInGroup; + } + } + else + { + // draw one (or sequential) primitive by the indices + glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset); + } + myVboIndices->Unbind (aGlContext); + } + else if (!myBounds.IsNull()) + { + GLint aFirstElem = 0; + for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) + { + const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; + if (theFaceColors != NULL) glColor3fv (theFaceColors[aGroupIter].GetData()); + glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); + aFirstElem += aNbElemsInGroup; + } + } + else + { + if (myDrawMode == GL_POINTS) + { + drawMarkers (theWorkspace); + } + else + { + glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb()); + } + } + + // bind with 0 + myVboAttribs->UnbindAllAttributes (aGlContext); if (hasVColors) { theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; } - - if (theEdgeFlag && myDrawMode > GL_LINE_STRIP) - { - DrawEdges (theEdgeColour, theWorkspace); - } - - if (myDrawMode <= GL_LINE_STRIP) - glPopAttrib(); } // ======================================================================= -// function : DrawEdges +// function : drawEdges // purpose : // ======================================================================= -void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeColour, +void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR* theEdgeColour, const Handle(OpenGl_Workspace)& theWorkspace) const { + if (myVboAttribs.IsNull()) + { + return; + } + glDisable (GL_LIGHTING); const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext(); const OpenGl_AspectLine* anAspectLineOld = NULL; - if (myDrawMode > GL_LINE_STRIP) + + anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge()); + const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True); + + glPushAttrib (GL_POLYGON_BIT); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + if (aGlContext->IsGlGreaterEqual (2, 0)) { - anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge()); - const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True); - - glPushAttrib (GL_POLYGON_BIT); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - if (aGlContext->IsGlGreaterEqual (2, 0)) - { - BindProgramWithMaterial (theWorkspace, anAspect); - } + bindProgram (theWorkspace, anAspect); } /// OCC22236 NOTE: draw edges for all situations: /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indices array /// 2) draw elements from vertex array, when bounds defines count of primitive's vertices. /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified - if (!myVboAttribs.IsNull()) + myVboAttribs->BindPositionAttribute (aGlContext); + glColor3fv (theEdgeColour->rgb); + if (!myVboIndices.IsNull()) { - myVboAttribs->BindFixedPosition (aGlContext); - glColor3fv (theEdgeColour->rgb); - if (!myVboIndices.IsNull()) - { - myVboIndices->Bind (aGlContext); + myVboIndices->Bind (aGlContext); + GLubyte* anOffset = myVboIndices->GetDataOffset(); - // draw primitives by vertex count with the indices - if (!myBounds.IsNull()) - { - const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); - GLubyte* anOffset = NULL; - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset); - anOffset += aStride * aNbElemsInGroup; - } - } - // draw one (or sequential) primitive by the indices - else - { - glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), NULL); - } - myVboIndices->Unbind (aGlContext); - } - else if (!myBounds.IsNull()) + // draw primitives by vertex count with the indices + if (!myBounds.IsNull()) { - GLint aFirstElem = 0; + const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) { const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); - aFirstElem += aNbElemsInGroup; + glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset); + anOffset += aStride * aNbElemsInGroup; } } + // draw one (or sequential) primitive by the indices else { - glDrawArrays (myDrawMode, 0, myAttribs->NbElements); + glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset); + } + myVboIndices->Unbind (aGlContext); + } + else if (!myBounds.IsNull()) + { + GLint aFirstElem = 0; + for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) + { + const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; + glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); + aFirstElem += aNbElemsInGroup; } - - // unbind buffers - myVboAttribs->UnbindFixed (aGlContext, GL_VERTEX_ARRAY); } else { - GLint aNbComp; - for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter) - { - const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter); - if (anAttrib.Id == Graphic3d_TOA_POS) - { - const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp); - const GLvoid* aData = myAttribs->Data (anAttribIter); - OpenGl_VertexBuffer::bindFixed (aGlContext, anAttrib.Id, aNbComp, aDataType, myAttribs->Stride, aData); - break; - } - } - - glColor3fv (theEdgeColour->rgb); - if (!myBounds.IsNull()) - { - if (!myIndices.IsNull()) - { - const GLenum anIndexType = toGlIndexType (myIndices->Stride); - GLint aFirstElem = 0; - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - glDrawElements (myDrawMode, aNbElemsInGroup, anIndexType, myIndices->value (aFirstElem)); - aFirstElem += aNbElemsInGroup; - } - } - else - { - GLint aFirstElem = 0; - for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) - { - const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; - glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); - aFirstElem += aNbElemsInGroup; - } - } - } - else if (!myIndices.IsNull()) - { - glDrawElements (myDrawMode, myIndices->NbElements, toGlIndexType (myIndices->Stride), myIndices->Data()); - } - else - { - glDrawArrays (myDrawMode, 0, myAttribs->NbElements); - } + glDrawArrays (myDrawMode, 0, myAttribs->NbElements); } + // unbind buffers + myVboAttribs->UnbindAttribute (aGlContext, Graphic3d_TOA_POS); + if (myDrawMode > GL_LINE_STRIP) { // Restore line context @@ -620,10 +574,10 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR* theEdgeCo } // ======================================================================= -// function : DrawMarkers +// function : drawMarkers // purpose : // ======================================================================= -void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const +void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const { const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (Standard_True); const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); @@ -815,27 +769,16 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace // create VBOs on first render call const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); - if (!myIsVboInit - && !aCtx->caps->vboDisable - && aCtx->core15 != NULL - && (myDrawMode != GL_POINTS || anAspectMarker->SpriteRes (theWorkspace).IsNull() || !anAspectMarker->SpriteRes (theWorkspace)->IsDisplayList())) + if (!myIsVboInit) { - if (!BuildVBO (theWorkspace)) - { - TCollection_ExtendedString aMsg; - aMsg += "VBO creation for Primitive Array has failed for "; - aMsg += myAttribs->NbElements; - aMsg += " vertices. Out of memory?"; - aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg); - } + // compatibility - keep data to draw markers using display lists + const Standard_Boolean toKeepData = myDrawMode == GL_POINTS + && !anAspectMarker->SpriteRes (theWorkspace).IsNull() + && anAspectMarker->SpriteRes (theWorkspace)->IsDisplayList(); + buildVBO (aCtx, toKeepData); myIsVboInit = Standard_True; } - if (myDrawMode <= GL_LINE_STRIP) - { - glDisable (GL_LIGHTING); - } - Tint aFrontLightingModel = anAspectFace->IntFront().color_mask; const TEL_COLOUR* anInteriorColor = &anAspectFace->IntFront().matcol; const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color(); @@ -848,34 +791,53 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace aFrontLightingModel = 0; } - if (aCtx->IsGlGreaterEqual (2, 0)) + // Temporarily disable environment mapping + if (myDrawMode <= GL_LINE_STRIP) { - switch (myDrawMode) + glPushAttrib (GL_ENABLE_BIT); + glDisable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + } + // manage FFP lighting + if (aFrontLightingModel == 0 + || myVboAttribs.IsNull() + || !myVboAttribs->HasNormalAttribute()) + { + glDisable (GL_LIGHTING); + } + else + { + glEnable (GL_LIGHTING); + } + + bindProgram (theWorkspace, + anAspectFace, anAspectLine, anAspectMarker, + myDrawMode); + + if ((myDrawMode > GL_LINE_STRIP && anAspectFace->InteriorStyle() != Aspect_IS_EMPTY) || + (myDrawMode <= GL_LINE_STRIP)) + { + const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0; + const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->InteriorStyle() != Aspect_IS_HIDDENLINE + ? myBounds->Colors + : NULL; + glColor3fv (myDrawMode <= GL_LINE_STRIP ? aLineColor->rgb : anInteriorColor->rgb); + + drawArray (theWorkspace, aFaceColors); + } + + if (myDrawMode > GL_LINE_STRIP) + { + if (anAspectFace->Edge() + || anAspectFace->InteriorStyle() == Aspect_IS_HIDDENLINE) { - case GL_POINTS: - { - BindProgramWithMaterial (theWorkspace, anAspectMarker); - break; - } - case GL_LINES: - case GL_LINE_STRIP: - { - BindProgramWithMaterial (theWorkspace, anAspectLine); - break; - } - default: // polygonal array - { - BindProgramWithMaterial (theWorkspace, anAspectFace); - break; - } + drawEdges (anEdgeColor, theWorkspace); } } - DrawArray (aFrontLightingModel, - anAspectFace->InteriorStyle(), - anAspectFace->Edge(), - anInteriorColor, - aLineColor, - anEdgeColor, - theWorkspace); + if (myDrawMode <= GL_LINE_STRIP) + { + glPopAttrib(); + } + aCtx->BindProgram (NULL); } diff --git a/src/OpenGl/OpenGl_PrimitiveArray.hxx b/src/OpenGl/OpenGl_PrimitiveArray.hxx index 025d91dcb4..c7d300e5a6 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.hxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.hxx @@ -28,7 +28,9 @@ #include class OpenGl_GraphicDriver; +class Handle(OpenGl_ShaderProgram); +//! Class for rendering of arbitrary primitive array. class OpenGl_PrimitiveArray : public OpenGl_Element { public: @@ -69,24 +71,25 @@ public: private: + //! Initialize normal (OpenGL-provided) VBO + Standard_Boolean initNormalVbo (const Handle(OpenGl_Context)& theCtx) const; + //! VBO initialization procedures - Standard_Boolean BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const; + //! @param theCtx bound GL context + //! @param theToKeepData when true, myAttribs will not be nullified after VBO creation + Standard_Boolean buildVBO (const Handle(OpenGl_Context)& theCtx, + const Standard_Boolean theToKeepData) const; void clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const; //! Main procedure to draw array - void DrawArray (Tint theLightingModel, - const Aspect_InteriorStyle theInteriorStyle, - Tint theEdgeFlag, - const TEL_COLOUR* theInteriorColour, - const TEL_COLOUR* theLineColour, - const TEL_COLOUR* theEdgeColour, - const Handle(OpenGl_Workspace)& theWorkspace) const; + void drawArray (const Handle(OpenGl_Workspace)& theWorkspace, + const Graphic3d_Vec4* theFaceColors) const; //! Auxiliary procedures - void DrawEdges (const TEL_COLOUR* theEdgeColour, + void drawEdges (const TEL_COLOUR* theEdgeColour, const Handle(OpenGl_Workspace)& theWorkspace) const; - void DrawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const; + void drawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const; protected: @@ -95,7 +98,7 @@ protected: protected: - mutable Handle(OpenGl_IndexBuffer) myVboIndices; + mutable Handle(OpenGl_VertexBuffer) myVboIndices; mutable Handle(OpenGl_VertexBuffer) myVboAttribs; mutable Handle(Graphic3d_IndexBuffer) myIndices; diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 5eb2a137a6..4f0e1de974 100755 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -34,7 +34,6 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient) // ======================================================================= OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext) : myContext (theContext), - myIsPP (Standard_False), myLastView (NULL) { // diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index 4ea5d32165..1da56c278f 100755 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -187,7 +187,6 @@ protected: private: - Standard_Boolean myIsPP; //!< Is any program object bound (programmable pipeline)? const OpenGl_View* myLastView; //!< Pointer to the last view shader manager used with. }; diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx index 2068089d61..4931090734 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/OpenGl/OpenGl_ShaderProgram.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -262,6 +263,12 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& } } + // bind locations for pre-defined Vertex Attributes + SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex"); + SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal"); + SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord"); + SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occColor"); + if (!Link (theCtx)) { TCollection_AsciiString aLog; @@ -413,21 +420,6 @@ Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context return Standard_True; } -// ======================================================================= -// function : Bind -// purpose : Sets the program object as part of current rendering state -// ======================================================================= -void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const -{ - if (myProgramID == NO_PROGRAM) - { - return; - } - - theCtx->core20->glUseProgram (myProgramID); - theCtx->ShaderManager()->myIsPP = Standard_True; -} - // ======================================================================= // function : ApplyVariables // purpose : Fetches uniform variables from proxy shader program @@ -448,29 +440,6 @@ Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Contex return Standard_True; } -// ======================================================================= -// function : BindWithVariables -// purpose : Binds the program object and applies variables -// ======================================================================= -Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx) -{ - Bind (theCtx); - return ApplyVariables (theCtx); -} - -// ======================================================================= -// function : Unbind -// purpose : Reverts to fixed-function graphics pipeline (FFP) -// ======================================================================= -void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx) -{ - if (theCtx->ShaderManager()->myIsPP) - { - theCtx->core20->glUseProgram (NO_PROGRAM); - theCtx->ShaderManager()->myIsPP = Standard_False; - } -} - // ======================================================================= // function : ActiveState // purpose : Returns index of last modification for specified state type diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx index e1fa54f722..9b5163f7cd 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.hxx +++ b/src/OpenGl/OpenGl_ShaderProgram.hxx @@ -181,21 +181,18 @@ public: //! Fetches uniform variables from proxy shader program. Standard_EXPORT Standard_Boolean ApplyVariables (const Handle(OpenGl_Context)& theCtx); - //! Sets the program object as part of current rendering state. - Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx) const; - - //! Binds the program object and applies variables from proxy shader program. - Standard_EXPORT Standard_Boolean BindWithVariables (const Handle(OpenGl_Context)& theCtx); - - //! Reverts to fixed-function graphics pipeline (FFP). - Standard_EXPORT static void Unbind (const Handle(OpenGl_Context)& theCtx); - //! @return true if current object was initialized inline bool IsValid() const { return myProgramID != NO_PROGRAM; } + //! @return program ID + inline GLuint ProgramId() const + { + return myProgramID; + } + private: //! Returns index of last modification of variables of specified state type. diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index 1d8da4141f..75e19ab122 100755 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -285,8 +285,6 @@ void OpenGl_Text::releaseVbos (OpenGl_Context* theCtx) myTextures.Clear(); myVertsVbo.Clear(); myTCrdsVbo.Clear(); - myVertsArray.Clear(); - myTCrdsArray.Clear(); } // ======================================================================= @@ -384,11 +382,11 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const if (aCtx->IsGlGreaterEqual (2, 0)) { - Handle(OpenGl_ShaderProgram) aProgram = aTextAspect->ShaderProgramRes (theWorkspace); - + const Handle(OpenGl_ShaderProgram)& aProgram = aTextAspect->ShaderProgramRes (theWorkspace); + aCtx->BindProgram (aProgram); if (!aProgram.IsNull()) { - aProgram->BindWithVariables (aCtx); + aProgram->ApplyVariables (aCtx); const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram); @@ -397,10 +395,6 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const aCtx->ShaderManager()->PushState (aProgram); } - else - { - OpenGl_ShaderProgram::Unbind (aCtx); - } } // use highlight color or colors from aspect @@ -513,45 +507,28 @@ void OpenGl_Text::drawText (const Handle(OpenGl_PrinterContext)& , } #endif - if (myVertsVbo.Length() == myTextures.Length()) + if (myVertsVbo.Length() != myTextures.Length() + || myTextures.IsEmpty()) { - for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter) - { - const GLuint aTexId = myTextures.Value (anIter); - const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter); - const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter); - aVerts->BindFixed (theCtx, GL_VERTEX_ARRAY); - aTCrds->BindFixed (theCtx, GL_TEXTURE_COORD_ARRAY); - glBindTexture (GL_TEXTURE_2D, aTexId); - - glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb())); - - glBindTexture (GL_TEXTURE_2D, 0); - aTCrds->UnbindFixed (theCtx, GL_TEXTURE_COORD_ARRAY); - aVerts->UnbindFixed (theCtx, GL_VERTEX_ARRAY); - } + return; } - else if (myVertsArray.Length() == myTextures.Length()) + + for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter) { - glEnableClientState (GL_VERTEX_ARRAY); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter) - { - const GLuint aTexId = myTextures.Value (anIter); - const Handle(OpenGl_Vec2Array)& aVerts = myVertsArray.Value (anIter); - const Handle(OpenGl_Vec2Array)& aTCrds = myTCrdsArray.Value (anIter); + const GLuint aTexId = myTextures.Value (anIter); + glBindTexture (GL_TEXTURE_2D, aTexId); - glVertexPointer (2, GL_FLOAT, 0, (GLfloat* )&aVerts->First()); - glTexCoordPointer (2, GL_FLOAT, 0, (GLfloat* )&aTCrds->First()); - glBindTexture (GL_TEXTURE_2D, aTexId); + const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter); + const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter); + aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS); + aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV); - glDrawArrays (GL_TRIANGLES, 0, aVerts->Length()); + glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb())); - glBindTexture (GL_TEXTURE_2D, 0); - } - glDisableClientState (GL_TEXTURE_COORD_ARRAY); - glDisableClientState (GL_VERTEX_ARRAY); + aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_UV); + aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS); } + glBindTexture (GL_TEXTURE_2D, 0); } // ======================================================================= @@ -654,14 +631,7 @@ void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx, aFormatter.Append (theCtx, myString, *myFont.operator->()); aFormatter.Format(); - if (!theCtx->caps->vboDisable && theCtx->core15 != NULL) - { - aFormatter.Result (theCtx, myTextures, myVertsVbo, myTCrdsVbo); - } - else - { - aFormatter.Result (theCtx, myTextures, myVertsArray, myTCrdsArray); - } + aFormatter.Result (theCtx, myTextures, myVertsVbo, myTCrdsVbo); aFormatter.BndBox (myBndBox); } diff --git a/src/OpenGl/OpenGl_Text.hxx b/src/OpenGl/OpenGl_Text.hxx index 1824586a2c..31a79aa140 100755 --- a/src/OpenGl/OpenGl_Text.hxx +++ b/src/OpenGl/OpenGl_Text.hxx @@ -133,8 +133,6 @@ protected: mutable NCollection_Vector myTextures; //!< textures' IDs mutable NCollection_Vector myVertsVbo; //!< VBOs of vertices mutable NCollection_Vector myTCrdsVbo; //!< VBOs of texture coordinates - mutable NCollection_Vector myVertsArray; //!< arrays of vertices (for compatibility mode) - mutable NCollection_Vector myTCrdsArray; //!< arrays of vertices (for compatibility mode) mutable Font_FTFont::Rect myBndBox; protected: diff --git a/src/OpenGl/OpenGl_TextFormatter.cxx b/src/OpenGl/OpenGl_TextFormatter.cxx index dbef616271..f715f9d7d0 100755 --- a/src/OpenGl/OpenGl_TextFormatter.cxx +++ b/src/OpenGl/OpenGl_TextFormatter.cxx @@ -15,7 +15,7 @@ #include -#include +#include #include @@ -220,10 +220,20 @@ void OpenGl_TextFormatter::Result (const Handle(OpenGl_Context)& theVertsPerTexture.Clear(); theTCrdsPerTexture.Clear(); + const bool isNormalMode = theCtx->ToUseVbo(); + Handle(OpenGl_VertexBuffer) aVertsVbo, aTcrdsVbo; while (theVertsPerTexture.Length() < theTextures.Length()) { - Handle(OpenGl_VertexBuffer) aVertsVbo = new OpenGl_VertexBuffer(); - Handle(OpenGl_VertexBuffer) aTcrdsVbo = new OpenGl_VertexBuffer(); + if (isNormalMode) + { + aVertsVbo = new OpenGl_VertexBuffer(); + aTcrdsVbo = new OpenGl_VertexBuffer(); + } + else + { + aVertsVbo = new OpenGl_VertexBufferCompat(); + aTcrdsVbo = new OpenGl_VertexBufferCompat(); + } theVertsPerTexture.Append (aVertsVbo); theTCrdsPerTexture.Append (aTcrdsVbo); aVertsVbo->Create (theCtx); @@ -262,42 +272,6 @@ void OpenGl_TextFormatter::Result (const Handle(OpenGl_Context)& myVboEditor.Init (NULL, NULL); } -// ======================================================================= -// function : Result -// purpose : -// ======================================================================= -void OpenGl_TextFormatter::Result (const Handle(OpenGl_Context)& /*theCtx*/, - NCollection_Vector& theTextures, - NCollection_Vector& theVertsPerTexture, - NCollection_Vector& theTCrdsPerTexture) const -{ - NCollection_Vector< NCollection_Handle > > aVertsPerTexture; - NCollection_Vector< NCollection_Handle > > aTCrdsPerTexture; - Result (theTextures, aVertsPerTexture, aTCrdsPerTexture); - - theVertsPerTexture.Clear(); - theTCrdsPerTexture.Clear(); - - for (Standard_Integer aTextureIter = 0; aTextureIter < theTextures.Length(); ++aTextureIter) - { - const NCollection_Vector& aVerts = *aVertsPerTexture.Value (aTextureIter); - const NCollection_Vector& aTCrds = *aTCrdsPerTexture.Value (aTextureIter); - Handle(OpenGl_Vec2Array) aVertsArray = new OpenGl_Vec2Array (1, aVerts.Length()); - Handle(OpenGl_Vec2Array) aTCrdsArray = new OpenGl_Vec2Array (1, aVerts.Length()); - theVertsPerTexture.Append (aVertsArray); - theTCrdsPerTexture.Append (aTCrdsArray); - - for (Standard_Integer aVertIter = 0; aVertIter < aVerts.Length(); ++aVertIter) - { - aVertsArray->ChangeValue (aVertIter + 1) = aVerts.Value (aVertIter); - } - for (Standard_Integer aVertIter = 0; aVertIter < aVerts.Length(); ++aVertIter) - { - aTCrdsArray->ChangeValue (aVertIter + 1) = aTCrds.Value (aVertIter); - } - } -} - // ======================================================================= // function : Append // purpose : diff --git a/src/OpenGl/OpenGl_TextFormatter.hxx b/src/OpenGl/OpenGl_TextFormatter.hxx index 39d8ed2fc4..adca108a8d 100755 --- a/src/OpenGl/OpenGl_TextFormatter.hxx +++ b/src/OpenGl/OpenGl_TextFormatter.hxx @@ -24,9 +24,6 @@ #include -typedef NCollection_Array1 OpenGl_Vec2Array; -typedef NCollection_Handle Handle(OpenGl_Vec2Array); - //! This class intended to prepare formatted text. class OpenGl_TextFormatter : public Standard_Transient { @@ -63,12 +60,6 @@ public: NCollection_Vector& theVertsPerTexture, NCollection_Vector& theTCrdsPerTexture) const; - //! Retrieve formatting results. - Standard_EXPORT void Result (const Handle(OpenGl_Context)& theCtx, - NCollection_Vector& theTextures, - NCollection_Vector& theVertsPerTexture, - NCollection_Vector& theTCrdsPerTexture) const; - //! @return width of formatted text. inline Standard_ShortReal ResultWidth() const { diff --git a/src/OpenGl/OpenGl_VertexBuffer.cxx b/src/OpenGl/OpenGl_VertexBuffer.cxx index 8f6609085a..9f06b96ba3 100644 --- a/src/OpenGl/OpenGl_VertexBuffer.cxx +++ b/src/OpenGl/OpenGl_VertexBuffer.cxx @@ -26,6 +26,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer, OpenGl_Resource) // ======================================================================= OpenGl_VertexBuffer::OpenGl_VertexBuffer() : OpenGl_Resource(), + myOffset (NULL), myBufferId (NO_BUFFER), myComponentsNb (4), myElemsNb (0), @@ -84,6 +85,7 @@ void OpenGl_VertexBuffer::Release (OpenGl_Context* theGlCtx) { theGlCtx->core15->glDeleteBuffers (1, &myBufferId); } + myOffset = NULL; myBufferId = NO_BUFFER; } @@ -171,7 +173,7 @@ void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlC } Bind (theGlCtx); theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc); - theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, NULL); + theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, myOffset); } // ======================================================================= @@ -190,91 +192,30 @@ void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theG } // ======================================================================= -// function : BindFixed +// function : BindAllAttributes // purpose : // ======================================================================= -void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx, - const GLenum theMode) const -{ - if (!IsValid()) - { - return; - } - - Bind (theGlCtx); - glEnableClientState (theMode); - switch (theMode) - { - case GL_VERTEX_ARRAY: - { - glVertexPointer (static_cast (myComponentsNb), myDataType, 0, NULL); - break; - } - case GL_NORMAL_ARRAY: - { - glNormalPointer (myDataType, 0, NULL); - break; - } - case GL_TEXTURE_COORD_ARRAY: - { - glTexCoordPointer (static_cast (myComponentsNb), myDataType, 0, NULL); - break; - } - case GL_COLOR_ARRAY: - { - glColorPointer (static_cast (myComponentsNb), myDataType, 0, NULL); - glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - glEnable (GL_COLOR_MATERIAL); - break; - } - default: break; - } -} - -// ======================================================================= -// function : UnbindFixed -// purpose : -// ======================================================================= -void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx, - const GLenum theMode) const -{ - if (!IsValid()) - { - return; - } - Unbind (theGlCtx); - glDisableClientState (theMode); - if (theMode == GL_COLOR_ARRAY) - { - glDisable (GL_COLOR_MATERIAL); - } -} - -// ======================================================================= -// function : BindFixed -// purpose : -// ======================================================================= -void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& ) const +void OpenGl_VertexBuffer::BindAllAttributes (const Handle(OpenGl_Context)& ) const { // } // ======================================================================= -// function : BindFixedPosition +// function : BindPositionAttribute // purpose : // ======================================================================= -void OpenGl_VertexBuffer::BindFixedPosition (const Handle(OpenGl_Context)& ) const +void OpenGl_VertexBuffer::BindPositionAttribute (const Handle(OpenGl_Context)& ) const { // } // ======================================================================= -// function : UnbindFixed +// function : UnbindAllAttributes // purpose : // ======================================================================= -void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& ) const +void OpenGl_VertexBuffer::UnbindAllAttributes (const Handle(OpenGl_Context)& ) const { - // + // } // ======================================================================= @@ -285,3 +226,12 @@ bool OpenGl_VertexBuffer::HasColorAttribute() const { return false; } + +// ======================================================================= +// function : HasNormalAttribute +// purpose : +// ======================================================================= +bool OpenGl_VertexBuffer::HasNormalAttribute() const +{ + return false; +} diff --git a/src/OpenGl/OpenGl_VertexBuffer.hxx b/src/OpenGl/OpenGl_VertexBuffer.hxx index 3a04cc469e..d029c00a35 100644 --- a/src/OpenGl/OpenGl_VertexBuffer.hxx +++ b/src/OpenGl/OpenGl_VertexBuffer.hxx @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -65,18 +66,24 @@ public: return myDataType; } + //! @return offset to data, NULL by default + inline GLubyte* GetDataOffset() const + { + return myOffset; + } + //! Creates VBO name (id) if not yet generated. //! Data should be initialized by another method. - Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theGlCtx); + Standard_EXPORT virtual bool Create (const Handle(OpenGl_Context)& theGlCtx); //! Destroy object - will release GPU memory if any. Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx); //! Bind this VBO. - Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theGlCtx) const; + Standard_EXPORT virtual void Bind (const Handle(OpenGl_Context)& theGlCtx) const; //! Unbind this VBO. - Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theGlCtx) const; + Standard_EXPORT virtual void Unbind (const Handle(OpenGl_Context)& theGlCtx) const; //! Notice that VBO will be unbound after this call. //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; @@ -190,17 +197,31 @@ public: Standard_EXPORT void UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx, const GLuint theAttribLoc) const; - //! Bind this VBO as fixed pipeline attribute. + //! Bind this VBO and enable specified attribute in OpenGl_Context::ActiveProgram() or FFP. //! @param theGlCtx - handle to bound GL context; //! @param theMode - array mode (GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY). - Standard_EXPORT void BindFixed (const Handle(OpenGl_Context)& theGlCtx, - const GLenum theMode) const; + void BindAttribute (const Handle(OpenGl_Context)& theCtx, + const Graphic3d_TypeOfAttribute theMode) const + { + if (IsValid()) + { + Bind (theCtx); + bindAttribute (theCtx, theMode, static_cast (myComponentsNb), myDataType, 0, myOffset); + } + } - //! Unbind this VBO as fixed pipeline attribute. - //! @param theGlCtx - handle to bound GL context; - //! @param theMode - array mode. - Standard_EXPORT void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx, - const GLenum theMode) const; + //! Unbind this VBO and disable specified attribute in OpenGl_Context::ActiveProgram() or FFP. + //! @param theCtx handle to bound GL context + //! @param theMode array mode + void UnbindAttribute (const Handle(OpenGl_Context)& theCtx, + const Graphic3d_TypeOfAttribute theMode) const + { + if (IsValid()) + { + Unbind (theCtx); + unbindAttribute (theCtx, theMode); + } + } public: //! @name advanced methods @@ -222,12 +243,12 @@ public: //! @name advanced methods } //! Initialize buffer with new data. - Standard_EXPORT bool init (const Handle(OpenGl_Context)& theGlCtx, - const GLuint theComponentsNb, - const GLsizei theElemsNb, - const void* theData, - const GLenum theDataType, - const GLsizei theStride); + Standard_EXPORT virtual bool init (const Handle(OpenGl_Context)& theGlCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const void* theData, + const GLenum theDataType, + const GLsizei theStride); //! Initialize buffer with new data. bool init (const Handle(OpenGl_Context)& theGlCtx, @@ -240,11 +261,27 @@ public: //! @name advanced methods } //! Update part of the buffer with new data. - Standard_EXPORT bool subData (const Handle(OpenGl_Context)& theGlCtx, - const GLsizei theElemFrom, - const GLsizei theElemsNb, - const void* theData, - const GLenum theDataType); + Standard_EXPORT virtual bool subData (const Handle(OpenGl_Context)& theGlCtx, + const GLsizei theElemFrom, + const GLsizei theElemsNb, + const void* theData, + const GLenum theDataType); + + //! Setup array pointer - either for active GLSL program OpenGl_Context::ActiveProgram() + //! or for FFP using bindFixed() when no program bound. + static void bindAttribute (const Handle(OpenGl_Context)& theGlCtx, + const Graphic3d_TypeOfAttribute theMode, + const GLint theNbComp, + const GLenum theDataType, + const GLsizei theStride, + const GLvoid* theOffset); + + //! Disable GLSL array pointer - either for active GLSL program OpenGl_Context::ActiveProgram() + //! or for FFP using unbindFixed() when no program bound. + static void unbindAttribute (const Handle(OpenGl_Context)& theGlCtx, + const Graphic3d_TypeOfAttribute theMode); + +private: //! Setup FFP array pointer. static void bindFixed (const Handle(OpenGl_Context)& theGlCtx, @@ -252,85 +289,37 @@ public: //! @name advanced methods const GLint theNbComp, const GLenum theDataType, const GLsizei theStride, - const GLvoid* theOffset) - { - switch (theMode) - { - case Graphic3d_TOA_POS: - { - theGlCtx->core11->glEnableClientState (GL_VERTEX_ARRAY); - theGlCtx->core11->glVertexPointer (theNbComp, theDataType, theStride, theOffset); - break; - } - case Graphic3d_TOA_NORM: - { - theGlCtx->core11->glEnableClientState (GL_NORMAL_ARRAY); - theGlCtx->core11->glNormalPointer (theDataType, theStride, theOffset); - break; - } - case Graphic3d_TOA_UV: - { - theGlCtx->core11->glEnableClientState (GL_TEXTURE_COORD_ARRAY); - theGlCtx->core11->glTexCoordPointer (theNbComp, theDataType, theStride, theOffset); - break; - } - case Graphic3d_TOA_COLOR: - { - theGlCtx->core11->glEnableClientState (GL_COLOR_ARRAY); - theGlCtx->core11->glColorPointer (theNbComp, theDataType, theStride, theOffset); - theGlCtx->core11->glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); - theGlCtx->core11fwd->glEnable (GL_COLOR_MATERIAL); - break; - } - case Graphic3d_TOA_CUSTOM: - { - break; - } - } - } + const GLvoid* theOffset); //! Disable FFP array pointer. static void unbindFixed (const Handle(OpenGl_Context)& theGlCtx, - const Graphic3d_TypeOfAttribute theMode) - { - switch (theMode) - { - case Graphic3d_TOA_POS: theGlCtx->core11->glDisableClientState (GL_VERTEX_ARRAY); break; - case Graphic3d_TOA_NORM: theGlCtx->core11->glDisableClientState (GL_NORMAL_ARRAY); break; - case Graphic3d_TOA_UV: theGlCtx->core11->glDisableClientState (GL_TEXTURE_COORD_ARRAY); break; - case Graphic3d_TOA_COLOR: - { - theGlCtx->core11->glDisableClientState (GL_COLOR_ARRAY); - theGlCtx->core11fwd->glDisable (GL_COLOR_MATERIAL); - break; - } - case Graphic3d_TOA_CUSTOM: - { - break; - } - } - } + const Graphic3d_TypeOfAttribute theMode); public: //! @name methods for interleaved attributes array - //! Bind all vertex attributes. Default implementation does nothing. - Standard_EXPORT virtual void BindFixed (const Handle(OpenGl_Context)& theGlCtx) const; - - //! Bind all vertex position attribute only. Default implementation does nothing. - Standard_EXPORT virtual void BindFixedPosition (const Handle(OpenGl_Context)& theGlCtx) const; - - //! Unbind all vertex attributes. Default implementation does nothing. - Standard_EXPORT virtual void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx) const; - //! @return true if buffer contains per-vertex color attribute Standard_EXPORT virtual bool HasColorAttribute() const; + //! @return true if buffer contains per-vertex normal attribute + Standard_EXPORT virtual bool HasNormalAttribute() const; + + //! Bind all vertex attributes to active program OpenGl_Context::ActiveProgram() or for FFP. + //! Default implementation does nothing. + Standard_EXPORT virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const; + + //! Bind vertex position attribute only. Default implementation does nothing. + Standard_EXPORT virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const; + + //! Unbind all vertex attributes. Default implementation does nothing. + Standard_EXPORT virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const; + protected: - GLuint myBufferId; //!< VBO name (index) - GLuint myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4 - GLsizei myElemsNb; //!< Number of vertex attributes / number of vertices - GLenum myDataType; //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.) + GLubyte* myOffset; //!< offset to data + GLuint myBufferId; //!< VBO name (index) + GLuint myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4 + GLsizei myElemsNb; //!< Number of vertex attributes / number of vertices + GLenum myDataType; //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.) public: @@ -340,4 +329,6 @@ public: DEFINE_STANDARD_HANDLE(OpenGl_VertexBuffer, OpenGl_Resource) +#include + #endif // _OpenGl_VertexBuffer_H__ diff --git a/src/OpenGl/OpenGl_VertexBuffer.lxx b/src/OpenGl/OpenGl_VertexBuffer.lxx new file mode 100644 index 0000000000..866e5738bf --- /dev/null +++ b/src/OpenGl/OpenGl_VertexBuffer.lxx @@ -0,0 +1,121 @@ +// Created by: Kirill GAVRILOV +// Copyright (c) 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. + +// ======================================================================= +// function : bindAttribute +// purpose : +// ======================================================================= +inline void OpenGl_VertexBuffer::bindAttribute (const Handle(OpenGl_Context)& theCtx, + const Graphic3d_TypeOfAttribute theAttribute, + const GLint theNbComp, + const GLenum theDataType, + const GLsizei theStride, + const GLvoid* theOffset) +{ + if (theCtx->ActiveProgram().IsNull()) + { + bindFixed (theCtx, theAttribute, theNbComp, theDataType, theStride, theOffset); + return; + } + + theCtx->core20fwd->glEnableVertexAttribArray (theAttribute); + theCtx->core20fwd->glVertexAttribPointer (theAttribute, theNbComp, theDataType, GL_FALSE, theStride, theOffset); +} + +// ======================================================================= +// function : bindFixed +// purpose : +// ======================================================================= +inline void OpenGl_VertexBuffer::bindFixed (const Handle(OpenGl_Context)& theCtx, + const Graphic3d_TypeOfAttribute theMode, + const GLint theNbComp, + const GLenum theDataType, + const GLsizei theStride, + const GLvoid* theOffset) +{ + switch (theMode) + { + case Graphic3d_TOA_POS: + { + theCtx->core11->glEnableClientState (GL_VERTEX_ARRAY); + theCtx->core11->glVertexPointer (theNbComp, theDataType, theStride, theOffset); + return; + } + case Graphic3d_TOA_NORM: + { + theCtx->core11->glEnableClientState (GL_NORMAL_ARRAY); + theCtx->core11->glNormalPointer (theDataType, theStride, theOffset); + return; + } + case Graphic3d_TOA_UV: + { + theCtx->core11->glEnableClientState (GL_TEXTURE_COORD_ARRAY); + theCtx->core11->glTexCoordPointer (theNbComp, theDataType, theStride, theOffset); + return; + } + case Graphic3d_TOA_COLOR: + { + theCtx->core11->glEnableClientState (GL_COLOR_ARRAY); + theCtx->core11->glColorPointer (theNbComp, theDataType, theStride, theOffset); + theCtx->core11->glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); + theCtx->core11fwd->glEnable (GL_COLOR_MATERIAL); + return; + } + case Graphic3d_TOA_CUSTOM: + { + return; + } + } +} + +// ======================================================================= +// function : unbindAttribute +// purpose : +// ======================================================================= +inline void OpenGl_VertexBuffer::unbindAttribute (const Handle(OpenGl_Context)& theCtx, + const Graphic3d_TypeOfAttribute theAttribute) +{ + if (theCtx->ActiveProgram().IsNull()) + { + unbindFixed (theCtx, theAttribute); + return; + } + + theCtx->core20fwd->glDisableVertexAttribArray (theAttribute); +} + +// ======================================================================= +// function : unbindAttribute +// purpose : +// ======================================================================= +inline void OpenGl_VertexBuffer::unbindFixed (const Handle(OpenGl_Context)& theCtx, + const Graphic3d_TypeOfAttribute theMode) +{ + switch (theMode) + { + 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_CUSTOM: + { + return; + } + } +} diff --git a/src/OpenGl/OpenGl_VertexBufferCompat.cxx b/src/OpenGl/OpenGl_VertexBufferCompat.cxx new file mode 100644 index 0000000000..5d8c194fef --- /dev/null +++ b/src/OpenGl/OpenGl_VertexBufferCompat.cxx @@ -0,0 +1,225 @@ +// Created by: Kirill GAVRILOV +// 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. + +#include + +#include + +IMPLEMENT_STANDARD_HANDLE (OpenGl_VertexBufferCompat, OpenGl_VertexBuffer) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBufferCompat, OpenGl_VertexBuffer) + +// ======================================================================= +// function : OpenGl_VertexBufferCompat +// purpose : +// ======================================================================= +OpenGl_VertexBufferCompat::OpenGl_VertexBufferCompat() +{ + // +} + +// ======================================================================= +// function : ~OpenGl_VertexBufferCompat +// purpose : +// ======================================================================= +OpenGl_VertexBufferCompat::~OpenGl_VertexBufferCompat() +{ + Release (NULL); +} + +// ======================================================================= +// function : Create +// purpose : +// ======================================================================= +bool OpenGl_VertexBufferCompat::Create (const Handle(OpenGl_Context)& ) +{ + if (myBufferId == NO_BUFFER) + { + myBufferId = (GLuint )-1; // dummy identifier... + Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); + myData = new NCollection_Buffer (anAlloc); + } + return myBufferId != NO_BUFFER; +} + +// ======================================================================= +// function : Release +// purpose : +// ======================================================================= +void OpenGl_VertexBufferCompat::Release (OpenGl_Context* ) +{ + if (myBufferId == NO_BUFFER) + { + return; + } + + myOffset = NULL; + myBufferId = NO_BUFFER; + myData.Nullify(); +} + +// ======================================================================= +// function : Bind +// purpose : +// ======================================================================= +void OpenGl_VertexBufferCompat::Bind (const Handle(OpenGl_Context)& ) const +{ + // +} + +// ======================================================================= +// function : Unbind +// purpose : +// ======================================================================= +void OpenGl_VertexBufferCompat::Unbind (const Handle(OpenGl_Context)& ) const +{ + // +} + +//! Convert GL type to Graphic3d enumeration +static inline bool toGraphic3dDataType (const GLuint theNbComponents, + const GLenum theGlType, + Graphic3d_TypeOfData& theType) +{ + switch (theGlType) + { + case GL_UNSIGNED_BYTE: + { + if (theNbComponents == 4) + { + theType = Graphic3d_TOD_VEC4UB; + return true; + } + return false; + } + case GL_UNSIGNED_SHORT: + { + if (theNbComponents == 1) + { + theType = Graphic3d_TOD_USHORT; + return true; + } + return false; + } + case GL_UNSIGNED_INT: + { + if (theNbComponents == 1) + { + theType = Graphic3d_TOD_UINT; + return true; + } + return false; + } + case GL_FLOAT: + { + switch (theNbComponents) + { + case 2: theType = Graphic3d_TOD_VEC2; return true; + case 3: theType = Graphic3d_TOD_VEC3; return true; + case 4: theType = Graphic3d_TOD_VEC4; return true; + } + return false; + } + } + return false; +} + +// ======================================================================= +// function : initLink +// purpose : +// ======================================================================= +bool OpenGl_VertexBufferCompat::initLink (const Handle(NCollection_Buffer)& theData, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const GLenum theDataType) +{ + if (theData.IsNull()) + { + myOffset = NULL; + return false; + } + + if (myBufferId == NO_BUFFER) + { + myBufferId = (GLuint )-1; // dummy identifier... + } + myData = theData; + myDataType = theDataType; + myComponentsNb = theComponentsNb; + myElemsNb = theElemsNb; + myOffset = myData->ChangeData(); + return true; +} + +// ======================================================================= +// function : init +// purpose : +// ======================================================================= +bool OpenGl_VertexBufferCompat::init (const Handle(OpenGl_Context)& theCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const void* theData, + const GLenum theDataType, + const GLsizei theStride) +{ + if (!Create (theCtx)) + { + myOffset = NULL; + return false; + } + + myDataType = theDataType; + myComponentsNb = theComponentsNb; + myElemsNb = theElemsNb; + + const size_t aNbBytes = size_t(myElemsNb) * theStride; + if (!myData->Allocate (aNbBytes)) + { + myOffset = NULL; + return false; + } + + myOffset = myData->ChangeData(); + if (theData != NULL) + { + memcpy (myData->ChangeData(), theData, aNbBytes); + } + return true; +} + +// ======================================================================= +// function : subData +// purpose : +// ======================================================================= +bool OpenGl_VertexBufferCompat::subData (const Handle(OpenGl_Context)& , + const GLsizei theElemFrom, + const GLsizei theElemsNb, + const void* theData, + const GLenum theDataType) +{ + if (!IsValid() || myDataType != theDataType || + theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb)) + { + return false; + } + else if (theData == NULL) + { + return true; + } + + const size_t aDataSize = sizeOfGlType (theDataType); + const size_t anOffset = size_t(theElemFrom) * size_t(myComponentsNb) * aDataSize; + const size_t aNbBytes = size_t(theElemsNb) * size_t(myComponentsNb) * aDataSize; + memcpy (myData->ChangeData() + anOffset, theData, aNbBytes); + return true; +} diff --git a/src/OpenGl/OpenGl_VertexBufferCompat.hxx b/src/OpenGl/OpenGl_VertexBufferCompat.hxx new file mode 100644 index 0000000000..48793f7f57 --- /dev/null +++ b/src/OpenGl/OpenGl_VertexBufferCompat.hxx @@ -0,0 +1,94 @@ +// Created by: Kirill GAVRILOV +// Copyright (c) 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_VertexBufferCompat_HeaderFile +#define _OpenGl_VertexBufferCompat_HeaderFile + +#include + +//! Compatibility layer for old OpenGL without VBO. +//! Make sure to pass pointer from GetDataOffset() instead of NULL. +//! Method GetDataOffset() returns pointer to real data in this class +//! (while base class OpenGl_VertexBuffer always return NULL). +//! +//! Methods Bind()/Unbind() do nothing (do not affect OpenGL state) +//! and ::GetTarget() is never used. +//! For this reason there is no analog for OpenGl_IndexBuffer. +//! Just pass GetDataOffset() to glDrawElements() directly as last argument. +//! +//! Class overrides methods init() and subData() to copy data into own memory buffer. +//! Extra method initLink() might be used to pass existing buffer through handle without copying the data. +//! +//! Method Create() creates dummy identifier for this object which should NOT be passed to OpenGL functions. +class OpenGl_VertexBufferCompat : public OpenGl_VertexBuffer +{ + +public: + + //! Create uninitialized VBO. + Standard_EXPORT OpenGl_VertexBufferCompat(); + + //! Destroy object. + Standard_EXPORT virtual ~OpenGl_VertexBufferCompat(); + + //! Creates VBO name (id) if not yet generated. + //! Data should be initialized by another method. + Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theGlCtx); + + //! Destroy object - will release memory if any. + Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx) Standard_OVERRIDE; + + //! Bind this VBO. + Standard_EXPORT virtual void Bind (const Handle(OpenGl_Context)& theGlCtx) const Standard_OVERRIDE; + + //! Unbind this VBO. + Standard_EXPORT virtual void Unbind (const Handle(OpenGl_Context)& theGlCtx) const Standard_OVERRIDE; + +public: //! @name advanced methods + + //! Initialize buffer with existing data. + //! Data will NOT be copied by this method! + Standard_EXPORT bool initLink (const Handle(NCollection_Buffer)& theData, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const GLenum theDataType); + + //! Initialize buffer with new data (data will be copied). + Standard_EXPORT virtual bool init (const Handle(OpenGl_Context)& theGlCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const void* theData, + const GLenum theDataType, + const GLsizei theStride) Standard_OVERRIDE; + + //! Update part of the buffer with new data. + Standard_EXPORT virtual bool subData (const Handle(OpenGl_Context)& theGlCtx, + const GLsizei theElemFrom, + const GLsizei theElemsNb, + const void* theData, + const GLenum theDataType) Standard_OVERRIDE; + +protected: + + Handle(NCollection_Buffer) myData; //!< buffer data + +public: + + DEFINE_STANDARD_RTTI(OpenGl_VertexBufferCompat) // Type definition + +}; + +DEFINE_STANDARD_HANDLE(OpenGl_VertexBufferCompat, OpenGl_VertexBuffer) + +#endif // _OpenGl_VertexBufferCompat_HeaderFile diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index 3bd7bd530c..74cb064117 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -600,7 +600,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, // We need to disable (unbind) all shaders programs to ensure // that all objects without specified aspect will be drawn // correctly (such as background) - OpenGl_ShaderProgram::Unbind (aContext); + aContext->BindProgram (NULL); } // Render trihedron diff --git a/src/OpenGl/OpenGl_Workspace_Raytrace.cxx b/src/OpenGl/OpenGl_Workspace_Raytrace.cxx index 3c408cebbe..fa896d5bcb 100644 --- a/src/OpenGl/OpenGl_Workspace_Raytrace.cxx +++ b/src/OpenGl/OpenGl_Workspace_Raytrace.cxx @@ -947,7 +947,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceEnvironmentMap() if (!aProgram.IsNull()) { - aProgram->Bind (myGlContext); + myGlContext->BindProgram (aProgram); if (!myView->TextureEnv().IsNull() && myView->SurfaceDetail() != Visual3d_TOD_NONE) { @@ -965,10 +965,8 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceEnvironmentMap() } } - OpenGl_ShaderProgram::Unbind (myGlContext); - + myGlContext->BindProgram (NULL); myViewModificationStatus = myView->ModificationState(); - return Standard_True; } @@ -1192,6 +1190,8 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& return Standard_False; } + myRaytraceProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex"); + myPostFSAAProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex"); if (!myRaytraceProgram->Link (myGlContext) || !myPostFSAAProgram->Link (myGlContext)) { @@ -1286,6 +1286,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& return SafeFailBack ("Failed to attach ray-trace shader objects"); } + myRaytraceProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex"); if (!myRaytraceProgram->Link (myGlContext)) { TCollection_AsciiString aLinkLog; @@ -1342,6 +1343,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& return SafeFailBack ("Failed to attach FSAA shader objects"); } + myPostFSAAProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex"); if (!myPostFSAAProgram->Link (myGlContext)) { TCollection_AsciiString aLinkLog; @@ -1365,7 +1367,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& Handle(OpenGl_ShaderProgram)& aShaderProgram = (anIndex == 0) ? myRaytraceProgram : myPostFSAAProgram; - aShaderProgram->Bind (myGlContext); + myGlContext->BindProgram (aShaderProgram); aShaderProgram->SetSampler (myGlContext, "uSceneMinPointTexture", OpenGl_RT_SceneMinPointTexture); @@ -1406,7 +1408,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& } myUniformLocations[anIndex][OpenGl_RT_aPosition] = - aShaderProgram->GetAttributeLocation (myGlContext, "aPosition"); + aShaderProgram->GetAttributeLocation (myGlContext, "occVertex"); myUniformLocations[anIndex][OpenGl_RT_uOriginLB] = aShaderProgram->GetUniformLocation (myGlContext, "uOriginLB"); @@ -1453,7 +1455,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& aShaderProgram->GetUniformLocation (myGlContext, "uEnvironmentEnable"); } - OpenGl_ShaderProgram::Unbind (myGlContext); + myGlContext->BindProgram (NULL); } if (myComputeInitStatus != OpenGl_RT_NONE) @@ -1956,7 +1958,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th glDisable (GL_BLEND); } - myRaytraceProgram->Bind (myGlContext); + myGlContext->BindProgram (myRaytraceProgram); Standard_Integer aLightSourceBufferSize = static_cast (myRaytraceGeometry.Sources.size()); @@ -1992,20 +1994,16 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th myRaytraceProgram->SetUniform (myGlContext, myUniformLocations[0][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0); - myGlContext->core20fwd->glEnableVertexAttribArray ( - myUniformLocations[0][OpenGl_RT_aPosition]); + myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS); { - myGlContext->core20fwd->glVertexAttribPointer ( - myUniformLocations[0][OpenGl_RT_aPosition], 3, GL_FLOAT, GL_FALSE, 0, NULL); - + myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL); myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6); } - myGlContext->core20fwd->glDisableVertexAttribArray ( - myUniformLocations[0][OpenGl_RT_aPosition]); + myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS); if (!theCView.RenderParams.IsAntialiasingEnabled) { - myRaytraceProgram->Unbind (myGlContext); + myGlContext->BindProgram (NULL); myOpenGlFBO->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture); myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture); @@ -2029,7 +2027,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th myRaytraceFBO1->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture); - myPostFSAAProgram->Bind (myGlContext); + myGlContext->BindProgram (myPostFSAAProgram); myPostFSAAProgram->SetUniform (myGlContext, myUniformLocations[1][OpenGl_RT_uOriginLB], theOrigins[0]); @@ -2065,11 +2063,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th const Standard_ShortReal aMaxOffset = 0.559017f; const Standard_ShortReal aMinOffset = 0.186339f; - myGlContext->core20fwd->glEnableVertexAttribArray ( - myUniformLocations[1][OpenGl_RT_aPosition]); - - myGlContext->core20fwd->glVertexAttribPointer ( - myUniformLocations[1][OpenGl_RT_aPosition], 3, GL_FLOAT, GL_FALSE, 0, NULL); + myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS); + myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL); // Perform multi-pass adaptive FSAA using ping-pong technique // rotated grid AA always uses 4 samples @@ -2119,10 +2114,9 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th } } - myGlContext->core20fwd->glDisableVertexAttribArray ( - myUniformLocations[1][OpenGl_RT_aPosition]); + myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS); - myPostFSAAProgram->Unbind (myGlContext); + myGlContext->BindProgram (NULL); myRaytraceFBO1->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture); myOpenGlFBO->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture); myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture); diff --git a/src/Shaders/Declarations.glsl b/src/Shaders/Declarations.glsl index 0653b4c6af..a23cf64681 100644 --- a/src/Shaders/Declarations.glsl +++ b/src/Shaders/Declarations.glsl @@ -23,10 +23,10 @@ // vertex attributes from compatibility profile. In the next // release old functionality will be removed from shader API. #ifdef VERTEX_SHADER - #define occColor gl_Color //!< Vertex color - #define occNormal gl_Normal //!< Normal coordinates - #define occVertex gl_Vertex //!< Vertex coordinates - #define occTexCoord gl_MultiTexCoord0 //!< Texture coordinates + attribute vec4 occVertex; + attribute vec3 occNormal; + attribute vec4 occTexCoord; + attribute vec4 occColor; #endif // Matrix state diff --git a/src/Shaders/RaytraceBase.vs b/src/Shaders/RaytraceBase.vs index 6ff4d01a6c..8b16abedb0 100644 --- a/src/Shaders/RaytraceBase.vs +++ b/src/Shaders/RaytraceBase.vs @@ -1,12 +1,12 @@ -in vec4 aPosition; +in vec4 occVertex; //! Normalized pixel coordinates. out vec2 vPixel; void main (void) { - vPixel = vec2 ((aPosition.x + 1.f) * 0.5f, - (aPosition.y + 1.f) * 0.5f); - - gl_Position = aPosition; -} \ No newline at end of file + vPixel = vec2 ((occVertex.x + 1.f) * 0.5f, + (occVertex.y + 1.f) * 0.5f); + + gl_Position = occVertex; +}