1 // Copyright (c) 2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #ifndef _Graphic3d_Buffer_HeaderFile
15 #define _Graphic3d_Buffer_HeaderFile
17 #include <Graphic3d_BufferRange.hxx>
18 #include <Graphic3d_Vec.hxx>
19 #include <NCollection_Array1.hxx>
20 #include <NCollection_Buffer.hxx>
21 #include <Standard_NotImplemented.hxx>
23 //! Type of attribute in Vertex Buffer
24 enum Graphic3d_TypeOfAttribute
26 Graphic3d_TOA_POS = 0, //!< vertex position
27 Graphic3d_TOA_NORM, //!< normal
28 Graphic3d_TOA_UV, //!< texture coordinates
29 Graphic3d_TOA_COLOR, //!< per-vertex color
30 Graphic3d_TOA_CUSTOM, //!< custom attributes
33 //! Type of the element in Vertex or Index Buffer
34 enum Graphic3d_TypeOfData
36 Graphic3d_TOD_USHORT, //!< unsigned 16-bit integer
37 Graphic3d_TOD_UINT, //!< unsigned 32-bit integer
38 Graphic3d_TOD_VEC2, //!< 2-components float vector
39 Graphic3d_TOD_VEC3, //!< 3-components float vector
40 Graphic3d_TOD_VEC4, //!< 4-components float vector
41 Graphic3d_TOD_VEC4UB, //!< 4-components unsigned byte vector
42 Graphic3d_TOD_FLOAT, //!< float value
45 //! Vertex attribute definition.
46 struct Graphic3d_Attribute
48 Graphic3d_TypeOfAttribute Id; //!< attribute identifier in vertex shader, 0 is reserved for vertex position
49 Graphic3d_TypeOfData DataType; //!< vec2,vec3,vec4,vec4ub
51 Standard_Integer Stride() const { return Stride (DataType); }
53 //! @return size of attribute of specified data type
54 static Standard_Integer Stride (const Graphic3d_TypeOfData theType)
58 case Graphic3d_TOD_USHORT: return sizeof(unsigned short);
59 case Graphic3d_TOD_UINT: return sizeof(unsigned int);
60 case Graphic3d_TOD_VEC2: return sizeof(Graphic3d_Vec2);
61 case Graphic3d_TOD_VEC3: return sizeof(Graphic3d_Vec3);
62 case Graphic3d_TOD_VEC4: return sizeof(Graphic3d_Vec4);
63 case Graphic3d_TOD_VEC4UB: return sizeof(Graphic3d_Vec4ub);
64 case Graphic3d_TOD_FLOAT: return sizeof(float);
71 typedef NCollection_Array1<Graphic3d_Attribute> Graphic3d_Array1OfAttribute;
73 //! Buffer of vertex attributes.
74 class Graphic3d_Buffer : public NCollection_Buffer
76 DEFINE_STANDARD_RTTIEXT(Graphic3d_Buffer, NCollection_Buffer)
79 //! Empty constructor.
80 Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc)
81 : NCollection_Buffer (theAlloc),
89 //! Return number of initially allocated elements which can fit into this buffer,
90 //! while NbElements can be overwritten to smaller value.
91 Standard_Integer NbMaxElements() const { return Stride != 0 ? Standard_Integer(mySize / size_t(Stride)) : 0; }
93 //! @return array of attributes definitions
94 const Graphic3d_Attribute* AttributesArray() const
96 return (Graphic3d_Attribute* )(myData + mySize);
99 //! @return attribute definition
100 const Graphic3d_Attribute& Attribute (const Standard_Integer theAttribIndex) const
102 return AttributesArray()[theAttribIndex];
105 //! @return attribute definition
106 Graphic3d_Attribute& ChangeAttribute (const Standard_Integer theAttribIndex)
108 return *((Graphic3d_Attribute* )(myData + mySize) + theAttribIndex);
111 //! Find attribute index.
112 //! @param theAttrib attribute to find
113 //! @return attribute index or -1 if not found
114 Standard_Integer FindAttribute (Graphic3d_TypeOfAttribute theAttrib) const
116 for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
118 const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
119 if (anAttrib.Id == theAttrib)
127 //! @name data accessors for interleaved array
130 //! @return data offset to specified attribute
131 Standard_Integer AttributeOffset (const Standard_Integer theAttribIndex) const
133 Standard_Integer anOffset = 0;
134 for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribIndex; ++anAttribIter)
136 anOffset += Graphic3d_Attribute::Stride (Attribute (anAttribIter).DataType);
141 //! @return data for specified attribute
142 const Standard_Byte* Data (const Standard_Integer theAttribIndex) const
144 return myData + AttributeOffset (theAttribIndex);
147 //! @return data for specified attribute
148 Standard_Byte* ChangeData (const Standard_Integer theAttribIndex)
150 return myData + AttributeOffset (theAttribIndex);
153 //! Access specified element.
154 inline const Standard_Byte* value (const Standard_Integer theElem) const
156 return myData + Stride * size_t(theElem);
159 //! Access specified element.
160 inline Standard_Byte* changeValue (const Standard_Integer theElem)
162 return myData + Stride * size_t(theElem);
165 //! Access element with specified position and type.
166 template <typename Type_t>
167 inline const Type_t& Value (const Standard_Integer theElem) const
169 return *reinterpret_cast<const Type_t*>(value (theElem));
172 //! Access element with specified position and type.
173 template <typename Type_t>
174 inline Type_t& ChangeValue (const Standard_Integer theElem)
176 return *reinterpret_cast<Type_t* >(changeValue (theElem));
179 //! @name general accessors
182 using NCollection_Buffer::Data;
183 using NCollection_Buffer::ChangeData;
185 //! Return the attribute data with stride size specific to this attribute.
186 //! @param theAttrib attribute to find
187 //! @param theAttribIndex index of found attribute
188 //! @param theAttribStride stride in bytes between values of this attribute within returned data pointer
189 Standard_Byte* ChangeAttributeData (Graphic3d_TypeOfAttribute theAttrib,
190 Standard_Integer& theAttribIndex,
191 Standard_Size& theAttribStride)
193 return (Standard_Byte* )AttributeData (theAttrib, theAttribIndex, theAttribStride);
196 //! Return the attribute data with stride size specific to this attribute.
197 //! @param theAttrib attribute to find
198 //! @param theAttribIndex index of found attribute
199 //! @param theAttribStride stride in bytes between values of this attribute within returned data pointer
200 const Standard_Byte* AttributeData (Graphic3d_TypeOfAttribute theAttrib,
201 Standard_Integer& theAttribIndex,
202 Standard_Size& theAttribStride) const
204 const Standard_Byte* aDataPtr = Data();
207 for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
209 const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
210 const Standard_Size anAttribStride = Graphic3d_Attribute::Stride (anAttrib.DataType);
211 if (anAttrib.Id == theAttrib)
213 theAttribIndex = anAttribIter;
214 theAttribStride = Stride;
218 aDataPtr += anAttribStride;
223 const Standard_Integer aNbMaxVerts = NbMaxElements();
224 for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
226 const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
227 const Standard_Size anAttribStride = Graphic3d_Attribute::Stride (anAttrib.DataType);
228 if (anAttrib.Id == theAttrib)
230 theAttribIndex = anAttribIter;
231 theAttribStride = anAttribStride;
235 aDataPtr += anAttribStride * aNbMaxVerts;
252 //! Allocates new empty array
253 bool Init (const Standard_Integer theNbElems,
254 const Graphic3d_Attribute* theAttribs,
255 const Standard_Integer theNbAttribs)
258 Standard_Integer aStride = 0;
259 for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
261 const Graphic3d_Attribute& anAttrib = theAttribs[anAttribIter];
262 aStride += anAttrib.Stride();
270 NbElements = theNbElems;
271 NbAttributes = theNbAttribs;
274 const size_t aDataSize = size_t(Stride) * size_t(NbElements);
275 if (!Allocate (aDataSize + sizeof(Graphic3d_Attribute) * NbAttributes))
282 for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
284 ChangeAttribute (anAttribIter) = theAttribs[anAttribIter];
290 //! Allocates new empty array
291 bool Init (const Standard_Integer theNbElems,
292 const Graphic3d_Array1OfAttribute& theAttribs)
294 return Init (theNbElems, &theAttribs.First(), theAttribs.Size());
299 //! Flag indicating that attributes in the buffer are interleaved; TRUE by default.
300 //! Requires sub-classing for creating a non-interleaved buffer (advanced usage).
301 virtual Standard_Boolean IsInterleaved() const { return Standard_True; }
303 //! Return TRUE if data can be invalidated; FALSE by default.
304 //! Requires sub-classing for creating a mutable buffer (advanced usage).
305 virtual Standard_Boolean IsMutable() const { return Standard_False; }
307 //! Return invalidated range; EMPTY by default.
308 //! Requires sub-classing for creating a mutable buffer (advanced usage).
309 virtual Graphic3d_BufferRange InvalidatedRange() const { return Graphic3d_BufferRange(); }
311 //! Reset invalidated range.
312 //! Requires sub-classing for creating a mutable buffer (advanced usage).
313 virtual void Validate() {}
315 //! Invalidate entire buffer.
316 virtual void Invalidate() {}
320 Standard_Integer Stride; //!< the distance to the attributes of the next vertex within interleaved array
321 Standard_Integer NbElements; //!< number of the elements (@sa NbMaxElements() specifying the number of initially allocated number of elements)
322 Standard_Integer NbAttributes; //!< number of vertex attributes
326 DEFINE_STANDARD_HANDLE(Graphic3d_Buffer, NCollection_Buffer)
328 #endif // _Graphic3d_Buffer_HeaderFile