// 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 _Graphic3d_Buffer_HeaderFile #define _Graphic3d_Buffer_HeaderFile #include #include #include //! Type of attribute in Vertex Buffer enum Graphic3d_TypeOfAttribute { Graphic3d_TOA_POS = 0, //!< vertex position Graphic3d_TOA_NORM, //!< normal Graphic3d_TOA_UV, //!< texture coordinates Graphic3d_TOA_COLOR, //!< per-vertex color Graphic3d_TOA_CUSTOM, //!< custom attributes }; //! Type of the element in Vertex or Index Buffer enum Graphic3d_TypeOfData { Graphic3d_TOD_USHORT, //!< unsigned 16-bit integer Graphic3d_TOD_UINT, //!< unsigned 32-bit integer Graphic3d_TOD_VEC2, //!< 2-components float vector 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. struct Graphic3d_Attribute { Graphic3d_TypeOfAttribute Id; //!< attribute identifier in vertex shader, 0 is reserved for vertex position Graphic3d_TypeOfData DataType; //!< vec2,vec3,vec4,vec4ub Standard_Integer Stride() const { return Stride (DataType); } //! @return size of attribute of specified data type static Standard_Integer Stride (const Graphic3d_TypeOfData theType) { switch (theType) { case Graphic3d_TOD_USHORT: return sizeof(unsigned short); case Graphic3d_TOD_UINT: return sizeof(unsigned int); case Graphic3d_TOD_VEC2: return sizeof(Graphic3d_Vec2); 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 { public: //! Empty constructor. Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc) : NCollection_Buffer (theAlloc), Stride (0), NbElements (0), NbAttributes (0) { // } //! @return array of attributes definitions const Graphic3d_Attribute* AttributesArray() const { return (Graphic3d_Attribute* )(myData + mySize); } //! @return attribute definition const Graphic3d_Attribute& Attribute (const Standard_Integer theAttribIndex) const { return AttributesArray()[theAttribIndex]; } //! @return attribute definition Graphic3d_Attribute& ChangeAttribute (const Standard_Integer theAttribIndex) { return *((Graphic3d_Attribute* )(myData + mySize) + theAttribIndex); } //! @return data offset to specified attribute Standard_Integer AttributeOffset (const Standard_Integer theAttribIndex) const { Standard_Integer anOffset = 0; for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribIndex; ++anAttribIter) { anOffset += Graphic3d_Attribute::Stride (Attribute (anAttribIter).DataType); } return anOffset; } using NCollection_Buffer::Data; using NCollection_Buffer::ChangeData; //! @return data for specified attribute const Standard_Byte* Data (const Standard_Integer theAttribIndex) const { return myData + AttributeOffset (theAttribIndex); } //! @return data for specified attribute Standard_Byte* ChangeData (const Standard_Integer theAttribIndex) { return myData + AttributeOffset (theAttribIndex); } //! Access specified element. inline const Standard_Byte* value (const Standard_Integer theElem) const { return myData + Stride * size_t(theElem); } //! Access specified element. inline Standard_Byte* changeValue (const Standard_Integer theElem) { return myData + Stride * size_t(theElem); } //! Access element with specified position and type. template inline const Type_t& Value (const Standard_Integer theElem) const { return *reinterpret_cast(value (theElem)); } //! Access element with specified position and type. template inline Type_t& ChangeValue (const Standard_Integer theElem) { return *reinterpret_cast(changeValue (theElem)); } //! Release buffer. void release() { Free(); Stride = 0; NbElements = 0; NbAttributes = 0; } //! Allocates new empty array bool Init (const Standard_Integer theNbElems, const Graphic3d_Attribute* theAttribs, const Standard_Integer theNbAttribs) { release(); Standard_Integer aStride = 0; for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter) { const Graphic3d_Attribute& anAttrib = theAttribs[anAttribIter]; aStride += anAttrib.Stride(); } if (aStride == 0) { return false; } Stride = aStride; NbElements = theNbElems; NbAttributes = theNbAttribs; if (NbElements != 0) { const size_t aDataSize = size_t(Stride) * size_t(NbElements); if (!Allocate (aDataSize + sizeof(Graphic3d_Attribute) * NbAttributes)) { release(); return false; } mySize = aDataSize; for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter) { ChangeAttribute (anAttribIter) = theAttribs[anAttribIter]; } } 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 Standard_Integer NbElements; //!< number of the elements Standard_Integer NbAttributes; //!< number of vertex attributes public: DEFINE_STANDARD_RTTI_INLINE(Graphic3d_Buffer,NCollection_Buffer) // Type definition }; DEFINE_STANDARD_HANDLE(Graphic3d_Buffer, NCollection_Buffer) #endif // _Graphic3d_Buffer_HeaderFile