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