0030239: Visualization, Graphic3d_ArrayOfPrimitives - pass Graphic3d_ArrayFlags bitma...
[occt.git] / src / Graphic3d / Graphic3d_Buffer.hxx
1 // Copyright (c) 2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _Graphic3d_Buffer_HeaderFile
15 #define _Graphic3d_Buffer_HeaderFile
16
17 #include <Graphic3d_Vec.hxx>
18 #include <NCollection_Array1.hxx>
19 #include <NCollection_Buffer.hxx>
20
21 //! Type of attribute in Vertex Buffer
22 enum Graphic3d_TypeOfAttribute
23 {
24   Graphic3d_TOA_POS   =  0,   //!< vertex position
25   Graphic3d_TOA_NORM,         //!< normal
26   Graphic3d_TOA_UV,           //!< texture coordinates
27   Graphic3d_TOA_COLOR,        //!< per-vertex color
28   Graphic3d_TOA_CUSTOM,       //!< custom attributes
29 };
30
31 //! Type of the element in Vertex or Index Buffer
32 enum Graphic3d_TypeOfData
33 {
34   Graphic3d_TOD_USHORT,  //!< unsigned 16-bit integer
35   Graphic3d_TOD_UINT,    //!< unsigned 32-bit integer
36   Graphic3d_TOD_VEC2,    //!< 2-components float vector
37   Graphic3d_TOD_VEC3,    //!< 3-components float vector
38   Graphic3d_TOD_VEC4,    //!< 4-components float vector
39   Graphic3d_TOD_VEC4UB,  //!< 4-components unsigned byte vector
40   Graphic3d_TOD_FLOAT,   //!< float value
41 };
42
43 //! Vertex attribute definition.
44 struct Graphic3d_Attribute
45 {
46   Graphic3d_TypeOfAttribute Id;       //!< attribute identifier in vertex shader, 0 is reserved for vertex position
47   Graphic3d_TypeOfData      DataType; //!< vec2,vec3,vec4,vec4ub
48
49   Standard_Integer Stride() const { return Stride (DataType); }
50
51   //! @return size of attribute of specified data type
52   static Standard_Integer Stride (const Graphic3d_TypeOfData theType)
53   {
54     switch (theType)
55     {
56       case Graphic3d_TOD_USHORT: return sizeof(unsigned short);
57       case Graphic3d_TOD_UINT:   return sizeof(unsigned int);
58       case Graphic3d_TOD_VEC2:   return sizeof(Graphic3d_Vec2);
59       case Graphic3d_TOD_VEC3:   return sizeof(Graphic3d_Vec3);
60       case Graphic3d_TOD_VEC4:   return sizeof(Graphic3d_Vec4);
61       case Graphic3d_TOD_VEC4UB: return sizeof(Graphic3d_Vec4ub);
62       case Graphic3d_TOD_FLOAT:  return sizeof(float);
63     }
64     return 0;
65   }
66
67 };
68
69 typedef NCollection_Array1<Graphic3d_Attribute> Graphic3d_Array1OfAttribute;
70
71 //! Buffer of vertex attributes.
72 class Graphic3d_Buffer : public NCollection_Buffer
73 {
74   DEFINE_STANDARD_RTTIEXT(Graphic3d_Buffer, NCollection_Buffer)
75 public:
76
77   //! Empty constructor.
78   Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc)
79   : NCollection_Buffer (theAlloc),
80     Stride       (0),
81     NbElements   (0),
82     NbAttributes (0)
83   {
84     //
85   }
86
87   //! Return number of initially allocated elements which can fit into this buffer,
88   //! while NbElements can be overwritten to smaller value.
89   Standard_Integer NbMaxElements() const { return Standard_Integer(mySize / size_t(Stride)); }
90
91   //! @return array of attributes definitions
92   const Graphic3d_Attribute* AttributesArray() const
93   {
94     return (Graphic3d_Attribute* )(myData + mySize);
95   }
96
97   //! @return attribute definition
98   const Graphic3d_Attribute& Attribute (const Standard_Integer theAttribIndex) const
99   {
100     return AttributesArray()[theAttribIndex];
101   }
102
103   //! @return attribute definition
104   Graphic3d_Attribute& ChangeAttribute (const Standard_Integer theAttribIndex)
105   {
106     return *((Graphic3d_Attribute* )(myData + mySize) + theAttribIndex);
107   }
108
109   //! @return data offset to specified attribute
110   Standard_Integer AttributeOffset (const Standard_Integer theAttribIndex) const
111   {
112     Standard_Integer anOffset = 0;
113     for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribIndex; ++anAttribIter)
114     {
115       anOffset += Graphic3d_Attribute::Stride (Attribute (anAttribIter).DataType);
116     }
117     return anOffset;
118   }
119
120   using NCollection_Buffer::Data;
121   using NCollection_Buffer::ChangeData;
122
123   //! @return data for specified attribute
124   const Standard_Byte* Data (const Standard_Integer theAttribIndex) const
125   {
126     return myData + AttributeOffset (theAttribIndex);
127   }
128
129   //! @return data for specified attribute
130   Standard_Byte* ChangeData (const Standard_Integer theAttribIndex)
131   {
132     return myData + AttributeOffset (theAttribIndex);
133   }
134
135   //! Access specified element.
136   inline const Standard_Byte* value (const Standard_Integer theElem) const
137   {
138     return myData + Stride * size_t(theElem);
139   }
140
141   //! Access specified element.
142   inline Standard_Byte* changeValue (const Standard_Integer theElem)
143   {
144     return myData + Stride * size_t(theElem);
145   }
146
147   //! Access element with specified position and type.
148   template <typename Type_t>
149   inline const Type_t& Value (const Standard_Integer theElem) const
150   {
151     return *reinterpret_cast<const Type_t*>(value (theElem));
152   }
153
154   //! Access element with specified position and type.
155   template <typename Type_t>
156   inline Type_t& ChangeValue (const Standard_Integer theElem)
157   {
158     return *reinterpret_cast<Type_t* >(changeValue (theElem));
159   }
160
161   //! Release buffer.
162   void release()
163   {
164     Free();
165     Stride       = 0;
166     NbElements   = 0;
167     NbAttributes = 0;
168   }
169
170   //! Allocates new empty array
171   bool Init (const Standard_Integer     theNbElems,
172              const Graphic3d_Attribute* theAttribs,
173              const Standard_Integer     theNbAttribs)
174   {
175     release();
176     Standard_Integer aStride = 0;
177     for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
178     {
179       const Graphic3d_Attribute& anAttrib = theAttribs[anAttribIter];
180       aStride += anAttrib.Stride();
181     }
182     if (aStride == 0)
183     {
184       return false;
185     }
186
187     Stride       = aStride;
188     NbElements   = theNbElems;
189     NbAttributes = theNbAttribs;
190     if (NbElements != 0)
191     {
192       const size_t aDataSize = size_t(Stride) * size_t(NbElements);
193       if (!Allocate (aDataSize + sizeof(Graphic3d_Attribute) * NbAttributes))
194       {
195         release();
196         return false;
197       }
198
199       mySize = aDataSize;
200       for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
201       {
202         ChangeAttribute (anAttribIter) = theAttribs[anAttribIter];
203       }
204     }
205     return true;
206   }
207
208   //! Allocates new empty array
209   bool Init (const Standard_Integer             theNbElems,
210              const Graphic3d_Array1OfAttribute& theAttribs)
211   {
212     return Init (theNbElems, &theAttribs.First(), theAttribs.Size());
213   }
214
215 public:
216
217   Standard_Integer Stride;       //!< the distance to the attributes of the next vertex within interleaved array
218   Standard_Integer NbElements;   //!< number of the elements (@sa NbMaxElements() specifying the number of initially allocated number of elements)
219   Standard_Integer NbAttributes; //!< number of vertex attributes
220
221 };
222
223 DEFINE_STANDARD_HANDLE(Graphic3d_Buffer, NCollection_Buffer)
224
225 #endif // _Graphic3d_Buffer_HeaderFile