From 4a535d3fd697447c30499b7959a73e1a515365c0 Mon Sep 17 00:00:00 2001 From: kgv Date: Sat, 20 Feb 2016 13:10:41 +0300 Subject: [PATCH] 0026969: Visualization - support custom vertex attributes in GLSL program Graphic3d_TypeOfData - added Graphic3d_TOD_FLOAT for passing single-float vertex attributes. Graphic3d_TOA_CUSTOM - changed value to increase the range for custom vertex attributes locations (to fit into hardware limits). Graphic3d_ShaderProgram::SetVertexAttributes() - introduced API for defining custom vertex attributes. For compatibility with automated wrappers: - Graphic3d_Buffer::Init() - added prototype taking NCollection_Array1 instead of C array - Graphic3d_IndexBuffer::InitInt32() - added typed initialization method. - Graphic3d_ShaderProgram::PushVariableVec3() and others - added typed methods to push uniform varibales. --- src/Graphic3d/FILES | 2 + src/Graphic3d/Graphic3d_Buffer.hxx | 14 ++++- src/Graphic3d/Graphic3d_IndexBuffer.hxx | 6 +++ src/Graphic3d/Graphic3d_ShaderAttribute.cxx | 39 ++++++++++++++ src/Graphic3d/Graphic3d_ShaderAttribute.hxx | 59 +++++++++++++++++++++ src/Graphic3d/Graphic3d_ShaderProgram.cxx | 9 ++++ src/Graphic3d/Graphic3d_ShaderProgram.hxx | 49 +++++++++++++++-- src/OpenGl/OpenGl_PrimitiveArray.cxx | 3 ++ src/OpenGl/OpenGl_ShaderProgram.cxx | 10 ++++ 9 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 src/Graphic3d/Graphic3d_ShaderAttribute.cxx create mode 100644 src/Graphic3d/Graphic3d_ShaderAttribute.hxx diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index ef47d46dc2..770c6f9ea7 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -100,6 +100,8 @@ Graphic3d_RenderingParams.hxx Graphic3d_SequenceOfGroup.hxx Graphic3d_SequenceOfHClipPlane.hxx Graphic3d_SequenceOfStructure.hxx +Graphic3d_ShaderAttribute.cxx +Graphic3d_ShaderAttribute.hxx Graphic3d_ShaderObject.cxx Graphic3d_ShaderObject.hxx Graphic3d_ShaderProgram.cxx diff --git a/src/Graphic3d/Graphic3d_Buffer.hxx b/src/Graphic3d/Graphic3d_Buffer.hxx index a8e6fbbb8d..6aaa671a37 100644 --- a/src/Graphic3d/Graphic3d_Buffer.hxx +++ b/src/Graphic3d/Graphic3d_Buffer.hxx @@ -15,6 +15,7 @@ #define _Graphic3d_Buffer_HeaderFile #include +#include #include //! Type of attribute in Vertex Buffer @@ -24,7 +25,7 @@ enum Graphic3d_TypeOfAttribute Graphic3d_TOA_NORM, //!< normal Graphic3d_TOA_UV, //!< texture coordinates Graphic3d_TOA_COLOR, //!< per-vertex color - Graphic3d_TOA_CUSTOM = 10, //!< custom attributes + Graphic3d_TOA_CUSTOM, //!< custom attributes }; //! Type of the element in Vertex or Index Buffer @@ -36,6 +37,7 @@ enum Graphic3d_TypeOfData Graphic3d_TOD_VEC3, //!< 3-components float vector Graphic3d_TOD_VEC4, //!< 4-components float vector Graphic3d_TOD_VEC4UB, //!< 4-components unsigned byte vector + Graphic3d_TOD_FLOAT, //!< float value }; //! Vertex attribute definition. @@ -57,12 +59,15 @@ struct Graphic3d_Attribute case Graphic3d_TOD_VEC3: return sizeof(Graphic3d_Vec3); case Graphic3d_TOD_VEC4: return sizeof(Graphic3d_Vec4); case Graphic3d_TOD_VEC4UB: return sizeof(Graphic3d_Vec4ub); + case Graphic3d_TOD_FLOAT: return sizeof(float); } return 0; } }; +typedef NCollection_Array1 Graphic3d_Array1OfAttribute; + //! Buffer of vertex attributes. class Graphic3d_Buffer : public NCollection_Buffer { @@ -195,6 +200,13 @@ public: return true; } + //! Allocates new empty array + bool Init (const Standard_Integer theNbElems, + const Graphic3d_Array1OfAttribute& theAttribs) + { + return Init (theNbElems, &theAttribs.First(), theAttribs.Size()); + } + public: Standard_Integer Stride; //!< the distance to the attributes of the next vertex diff --git a/src/Graphic3d/Graphic3d_IndexBuffer.hxx b/src/Graphic3d/Graphic3d_IndexBuffer.hxx index f6b7448f8d..6b6bc9ebbc 100644 --- a/src/Graphic3d/Graphic3d_IndexBuffer.hxx +++ b/src/Graphic3d/Graphic3d_IndexBuffer.hxx @@ -48,6 +48,12 @@ public: return true; } + //! Allocates new empty index array + bool InitInt32 (const Standard_Integer theNbElems) + { + return Init (theNbElems); + } + //! Access index at specified position Standard_Integer Index (const Standard_Integer theIndex) const { diff --git a/src/Graphic3d/Graphic3d_ShaderAttribute.cxx b/src/Graphic3d/Graphic3d_ShaderAttribute.cxx new file mode 100644 index 0000000000..c994c3cd7b --- /dev/null +++ b/src/Graphic3d/Graphic3d_ShaderAttribute.cxx @@ -0,0 +1,39 @@ +// Created on: 2016-02-19 +// Created by: Kirill Gavrilov +// Copyright (c) 2016 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 + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderAttribute,Standard_Transient) + +// ======================================================================= +// function : Graphic3d_ShaderAttribute +// purpose : +// ======================================================================= +Graphic3d_ShaderAttribute::Graphic3d_ShaderAttribute (const TCollection_AsciiString& theName, + const int theLocation) +: myName (theName), + myLocation (theLocation) +{ + // +} + +// ======================================================================= +// function : ~Graphic3d_ShaderAttribute +// purpose : +// ======================================================================= +Graphic3d_ShaderAttribute::~Graphic3d_ShaderAttribute() +{ + // +} diff --git a/src/Graphic3d/Graphic3d_ShaderAttribute.hxx b/src/Graphic3d/Graphic3d_ShaderAttribute.hxx new file mode 100644 index 0000000000..786458d360 --- /dev/null +++ b/src/Graphic3d/Graphic3d_ShaderAttribute.hxx @@ -0,0 +1,59 @@ +// Created on: 2016-02-19 +// Created by: Kirill Gavrilov +// Copyright (c) 2016 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 _Graphic3d_ShaderAttribute_HeaderFile +#define _Graphic3d_ShaderAttribute_HeaderFile + +#include +#include + +//! Describes custom vertex shader attribute. +class Graphic3d_ShaderAttribute : public Standard_Transient +{ +public: + + //! Creates new attribute. + Standard_EXPORT Graphic3d_ShaderAttribute (const TCollection_AsciiString& theName, + const int theLocation); + + //! Destructor. + Standard_EXPORT virtual ~Graphic3d_ShaderAttribute(); + + //! Returns name of shader variable. + const TCollection_AsciiString& Name() const + { + return myName; + } + + //! Returns attribute location to be bound on GLSL program linkage stage. + int Location() const + { + return myLocation; + } + +protected: + + TCollection_AsciiString myName; //!< attribute name + int myLocation; //!< attribute location + +public: + + DEFINE_STANDARD_RTTIEXT(Graphic3d_ShaderAttribute,Standard_Transient) + +}; + +DEFINE_STANDARD_HANDLE (Graphic3d_ShaderAttribute, Standard_Transient) + +#endif // _Graphic3d_ShaderAttribute_HeaderFile diff --git a/src/Graphic3d/Graphic3d_ShaderProgram.cxx b/src/Graphic3d/Graphic3d_ShaderProgram.cxx index 25862914cf..cd87a0d51b 100755 --- a/src/Graphic3d/Graphic3d_ShaderProgram.cxx +++ b/src/Graphic3d/Graphic3d_ShaderProgram.cxx @@ -217,3 +217,12 @@ void Graphic3d_ShaderProgram::ClearVariables() { myVariables.Clear(); } + +// ======================================================================= +// function : SetAttributes +// purpose : +// ======================================================================= +void Graphic3d_ShaderProgram::SetVertexAttributes (const Graphic3d_ShaderAttributeList& theAttributes) +{ + myAttributes = theAttributes; +} diff --git a/src/Graphic3d/Graphic3d_ShaderProgram.hxx b/src/Graphic3d/Graphic3d_ShaderProgram.hxx index 890b240c11..907f5ff048 100755 --- a/src/Graphic3d/Graphic3d_ShaderProgram.hxx +++ b/src/Graphic3d/Graphic3d_ShaderProgram.hxx @@ -16,6 +16,7 @@ #ifndef _Graphic3d_ShaderProgram_HeaderFile #define _Graphic3d_ShaderProgram_HeaderFile +#include #include #include #include @@ -27,6 +28,9 @@ typedef NCollection_Sequence Graphic3d_ShaderObj //! List of custom uniform shader variables. typedef NCollection_Sequence Graphic3d_ShaderVariableList; +//! List of custom vertex shader attrubures +typedef NCollection_Sequence Graphic3d_ShaderAttributeList; + //! This class is responsible for managing shader programs. class Graphic3d_ShaderProgram : public Standard_Transient { @@ -82,10 +86,20 @@ public: //! Returns list of attached shader objects. const Graphic3d_ShaderObjectList& ShaderObjects() const { return myShaderObjects; } - //! Returns list of custom uniform variables. + //! The list of currently pushed but not applied custom uniform variables. + //! This list is automatically cleared after applying to GLSL program. const Graphic3d_ShaderVariableList& Variables() const { return myVariables; } + //! Return the list of custom vertex attributes. + const Graphic3d_ShaderAttributeList& VertexAttributes() const { return myAttributes; } + + //! Assign the list of custom vertex attributes. + //! Should be done before GLSL program initialization. + Standard_EXPORT void SetVertexAttributes (const Graphic3d_ShaderAttributeList& theAttributes); + //! Pushes custom uniform variable to the program. + //! The list of pushed variables is automatically cleared after applying to GLSL program. + //! Thus after program recreation even unchanged uniforms should be pushed anew. template Standard_Boolean PushVariable (const TCollection_AsciiString& theName, const T& theValue); @@ -93,6 +107,30 @@ public: //! Removes all custom uniform variables from the program. Standard_EXPORT void ClearVariables(); + //! Pushes float uniform. + Standard_Boolean PushVariableFloat (const TCollection_AsciiString& theName, const float theValue) { return PushVariable (theName, theValue); } + + //! Pushes vec2 uniform. + Standard_Boolean PushVariableVec2 (const TCollection_AsciiString& theName, const Graphic3d_Vec2& theValue) { return PushVariable (theName, theValue); } + + //! Pushes vec3 uniform. + Standard_Boolean PushVariableVec3 (const TCollection_AsciiString& theName, const Graphic3d_Vec3& theValue) { return PushVariable (theName, theValue); } + + //! Pushes vec4 uniform. + Standard_Boolean PushVariableVec4 (const TCollection_AsciiString& theName, const Graphic3d_Vec4& theValue) { return PushVariable (theName, theValue); } + + //! Pushes int uniform. + Standard_Boolean PushVariableInt (const TCollection_AsciiString& theName, const int theValue) { return PushVariable (theName, theValue); } + + //! Pushes vec2i uniform. + Standard_Boolean PushVariableVec2i (const TCollection_AsciiString& theName, const Graphic3d_Vec2i& theValue) { return PushVariable (theName, theValue); } + + //! Pushes vec3i uniform. + Standard_Boolean PushVariableVec3i (const TCollection_AsciiString& theName, const Graphic3d_Vec3i& theValue) { return PushVariable (theName, theValue); } + + //! Pushes vec4i uniform. + Standard_Boolean PushVariableVec4i (const TCollection_AsciiString& theName, const Graphic3d_Vec4i& theValue) { return PushVariable (theName, theValue); } + public: //! The path to GLSL programs determined from CSF_ShadersDirectory or CASROOT environment variables. @@ -105,10 +143,11 @@ public: private: - TCollection_AsciiString myID; //!< The unique identifier of program object. - Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects. - Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables. - TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions + TCollection_AsciiString myID; //!< the unique identifier of program object + Graphic3d_ShaderObjectList myShaderObjects; //!< the list of attached shader objects + Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables + Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes + TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions }; diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 6908e2edc6..ecb91c4481 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -53,6 +53,9 @@ namespace case Graphic3d_TOD_VEC4UB: theNbComp = 4; return GL_UNSIGNED_BYTE; + case Graphic3d_TOD_FLOAT: + theNbComp = 1; + return GL_FLOAT; } theNbComp = 0; return GL_NONE; diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx index 4f8ad9b3ec..90ef45b78f 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/OpenGl/OpenGl_ShaderProgram.cxx @@ -297,6 +297,16 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord"); SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor"); + // bind custom Vertex Attributes + if (!myProxy.IsNull()) + { + for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes()); + anAttribIter.More(); anAttribIter.Next()) + { + SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString()); + } + } + if (!Link (theCtx)) { TCollection_AsciiString aLog;