5e27df78 |
1 | // Created by: Kirill GAVRILOV |
d5f74e42 |
2 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
5e27df78 |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
5e27df78 |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
5e27df78 |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
5e27df78 |
14 | |
15 | #ifndef _OpenGl_VertexBuffer_H__ |
16 | #define _OpenGl_VertexBuffer_H__ |
17 | |
18 | #include <OpenGl_GlCore20.hxx> |
19 | #include <OpenGl_Resource.hxx> |
871fa103 |
20 | #include <OpenGl_Context.hxx> |
7d3e64ef |
21 | #include <OpenGl_ShaderProgram.hxx> |
5e27df78 |
22 | |
871fa103 |
23 | #include <Graphic3d_IndexBuffer.hxx> |
5e27df78 |
24 | |
25 | //! Vertex Buffer Object - is a general storage object for vertex attributes (position, normal, color). |
26 | //! Notice that you should use OpenGl_IndexBuffer specialization for array of indices. |
27 | class OpenGl_VertexBuffer : public OpenGl_Resource |
28 | { |
29 | |
30 | public: |
31 | |
32 | //! Helpful constants |
33 | static const GLuint NO_BUFFER = 0; |
34 | |
35 | public: |
36 | |
37 | //! Create uninitialized VBO. |
38 | Standard_EXPORT OpenGl_VertexBuffer(); |
39 | |
40 | //! Destroy object. |
41 | Standard_EXPORT virtual ~OpenGl_VertexBuffer(); |
42 | |
43 | Standard_EXPORT virtual GLenum GetTarget() const; |
44 | |
45 | //! @return true if current object was initialized |
46 | inline bool IsValid() const |
47 | { |
48 | return myBufferId != NO_BUFFER; |
49 | } |
50 | |
51 | //! @return the number of components per generic vertex attribute. |
52 | inline GLuint GetComponentsNb() const |
53 | { |
54 | return myComponentsNb; |
55 | } |
56 | |
57 | //! @return number of vertex attributes / number of vertices. |
58 | inline GLsizei GetElemsNb() const |
59 | { |
60 | return myElemsNb; |
61 | } |
62 | |
63 | //! @return data type of each component in the array. |
64 | inline GLenum GetDataType() const |
65 | { |
66 | return myDataType; |
67 | } |
68 | |
7d3e64ef |
69 | //! @return offset to data, NULL by default |
70 | inline GLubyte* GetDataOffset() const |
71 | { |
72 | return myOffset; |
73 | } |
74 | |
5e27df78 |
75 | //! Creates VBO name (id) if not yet generated. |
76 | //! Data should be initialized by another method. |
7d3e64ef |
77 | Standard_EXPORT virtual bool Create (const Handle(OpenGl_Context)& theGlCtx); |
5e27df78 |
78 | |
79 | //! Destroy object - will release GPU memory if any. |
79104795 |
80 | Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx) Standard_OVERRIDE; |
5e27df78 |
81 | |
82 | //! Bind this VBO. |
7d3e64ef |
83 | Standard_EXPORT virtual void Bind (const Handle(OpenGl_Context)& theGlCtx) const; |
5e27df78 |
84 | |
85 | //! Unbind this VBO. |
7d3e64ef |
86 | Standard_EXPORT virtual void Unbind (const Handle(OpenGl_Context)& theGlCtx) const; |
5e27df78 |
87 | |
88 | //! Notice that VBO will be unbound after this call. |
89 | //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; |
90 | //! @param theElemsNb - elements count; |
91 | //! @param theData - pointer to GLfloat data (vertices/normals etc.). |
871fa103 |
92 | bool Init (const Handle(OpenGl_Context)& theGlCtx, |
93 | const GLuint theComponentsNb, |
94 | const GLsizei theElemsNb, |
95 | const GLfloat* theData) |
96 | { |
97 | return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_FLOAT); |
98 | } |
5e27df78 |
99 | |
100 | //! Notice that VBO will be unbound after this call. |
101 | //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; |
102 | //! @param theElemsNb - elements count; |
103 | //! @param theData - pointer to GLuint data (indices etc.). |
871fa103 |
104 | bool Init (const Handle(OpenGl_Context)& theGlCtx, |
105 | const GLuint theComponentsNb, |
106 | const GLsizei theElemsNb, |
107 | const GLuint* theData) |
108 | { |
109 | return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_INT); |
110 | } |
111 | |
112 | //! Notice that VBO will be unbound after this call. |
113 | //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; |
114 | //! @param theElemsNb - elements count; |
115 | //! @param theData - pointer to GLushort data (indices etc.). |
116 | bool Init (const Handle(OpenGl_Context)& theGlCtx, |
117 | const GLuint theComponentsNb, |
118 | const GLsizei theElemsNb, |
119 | const GLushort* theData) |
120 | { |
121 | return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_SHORT); |
122 | } |
5e27df78 |
123 | |
124 | //! Notice that VBO will be unbound after this call. |
125 | //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; |
126 | //! @param theElemsNb - elements count; |
127 | //! @param theData - pointer to GLubyte data (indices/colors etc.). |
871fa103 |
128 | bool Init (const Handle(OpenGl_Context)& theGlCtx, |
129 | const GLuint theComponentsNb, |
130 | const GLsizei theElemsNb, |
131 | const GLubyte* theData) |
132 | { |
133 | return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_BYTE); |
134 | } |
5e27df78 |
135 | |
136 | //! Notice that VBO will be unbound after this call. |
137 | //! Function replaces portion of data within this VBO using glBufferSubData(). |
138 | //! The VBO should be initialized before call. |
139 | //! @param theElemFrom - element id from which replace buffer data (>=0); |
99d99a6d |
140 | //! @param theElemsNb - elements count (theElemFrom + theElemsNb <= GetElemsNb()); |
5e27df78 |
141 | //! @param theData - pointer to GLfloat data. |
871fa103 |
142 | bool SubData (const Handle(OpenGl_Context)& theGlCtx, |
143 | const GLsizei theElemFrom, |
144 | const GLsizei theElemsNb, |
145 | const GLfloat* theData) |
146 | { |
147 | return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT); |
148 | } |
5e27df78 |
149 | |
99d99a6d |
150 | //! Notice that VBO will be unbound after this call. |
151 | //! Function replaces portion of data within this VBO using glBufferSubData(). |
152 | //! The VBO should be initialized before call. |
153 | //! @param theElemFrom element id from which replace buffer data (>=0); |
154 | //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb()); |
155 | //! @param theData pointer to GLuint data. |
871fa103 |
156 | bool SubData (const Handle(OpenGl_Context)& theGlCtx, |
157 | const GLsizei theElemFrom, |
158 | const GLsizei theElemsNb, |
159 | const GLuint* theData) |
160 | { |
161 | return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT); |
162 | } |
163 | |
164 | //! Notice that VBO will be unbound after this call. |
165 | //! Function replaces portion of data within this VBO using glBufferSubData(). |
166 | //! The VBO should be initialized before call. |
167 | //! @param theElemFrom element id from which replace buffer data (>=0); |
168 | //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb()); |
169 | //! @param theData pointer to GLushort data. |
170 | bool SubData (const Handle(OpenGl_Context)& theGlCtx, |
171 | const GLsizei theElemFrom, |
172 | const GLsizei theElemsNb, |
173 | const GLushort* theData) |
174 | { |
175 | return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT); |
176 | } |
99d99a6d |
177 | |
178 | //! Notice that VBO will be unbound after this call. |
179 | //! Function replaces portion of data within this VBO using glBufferSubData(). |
180 | //! The VBO should be initialized before call. |
181 | //! @param theElemFrom element id from which replace buffer data (>=0); |
182 | //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb()); |
183 | //! @param theData pointer to GLubyte data. |
871fa103 |
184 | bool SubData (const Handle(OpenGl_Context)& theGlCtx, |
185 | const GLsizei theElemFrom, |
186 | const GLsizei theElemsNb, |
187 | const GLubyte* theData) |
188 | { |
189 | return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE); |
190 | } |
99d99a6d |
191 | |
5e27df78 |
192 | //! Bind this VBO to active GLSL program. |
193 | Standard_EXPORT void BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx, |
194 | const GLuint theAttribLoc) const; |
195 | |
196 | //! Unbind any VBO from active GLSL program. |
197 | Standard_EXPORT void UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx, |
198 | const GLuint theAttribLoc) const; |
199 | |
7d3e64ef |
200 | //! Bind this VBO and enable specified attribute in OpenGl_Context::ActiveProgram() or FFP. |
5e27df78 |
201 | //! @param theGlCtx - handle to bound GL context; |
202 | //! @param theMode - array mode (GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY). |
7d3e64ef |
203 | void BindAttribute (const Handle(OpenGl_Context)& theCtx, |
204 | const Graphic3d_TypeOfAttribute theMode) const |
205 | { |
206 | if (IsValid()) |
207 | { |
208 | Bind (theCtx); |
209 | bindAttribute (theCtx, theMode, static_cast<GLint> (myComponentsNb), myDataType, 0, myOffset); |
210 | } |
211 | } |
5e27df78 |
212 | |
7d3e64ef |
213 | //! Unbind this VBO and disable specified attribute in OpenGl_Context::ActiveProgram() or FFP. |
214 | //! @param theCtx handle to bound GL context |
215 | //! @param theMode array mode |
216 | void UnbindAttribute (const Handle(OpenGl_Context)& theCtx, |
217 | const Graphic3d_TypeOfAttribute theMode) const |
218 | { |
219 | if (IsValid()) |
220 | { |
221 | Unbind (theCtx); |
222 | unbindAttribute (theCtx, theMode); |
223 | } |
224 | } |
5e27df78 |
225 | |
871fa103 |
226 | public: //! @name advanced methods |
227 | |
228 | //! @return size of specified GL type |
229 | static size_t sizeOfGlType (const GLenum theType) |
230 | { |
231 | switch (theType) |
232 | { |
233 | case GL_BYTE: |
234 | case GL_UNSIGNED_BYTE: return sizeof(GLubyte); |
235 | case GL_SHORT: |
236 | case GL_UNSIGNED_SHORT: return sizeof(GLushort); |
ca3c13d1 |
237 | #ifdef GL_INT |
871fa103 |
238 | case GL_INT: |
ca3c13d1 |
239 | #endif |
871fa103 |
240 | case GL_UNSIGNED_INT: return sizeof(GLuint); |
241 | case GL_FLOAT: return sizeof(GLfloat); |
ca3c13d1 |
242 | #ifdef GL_DOUBLE |
871fa103 |
243 | case GL_DOUBLE: return sizeof(GLdouble); |
ca3c13d1 |
244 | #endif |
871fa103 |
245 | default: return 0; |
246 | } |
247 | } |
248 | |
249 | //! Initialize buffer with new data. |
7d3e64ef |
250 | Standard_EXPORT virtual bool init (const Handle(OpenGl_Context)& theGlCtx, |
251 | const GLuint theComponentsNb, |
252 | const GLsizei theElemsNb, |
253 | const void* theData, |
254 | const GLenum theDataType, |
255 | const GLsizei theStride); |
871fa103 |
256 | |
257 | //! Initialize buffer with new data. |
258 | bool init (const Handle(OpenGl_Context)& theGlCtx, |
259 | const GLuint theComponentsNb, |
260 | const GLsizei theElemsNb, |
261 | const void* theData, |
262 | const GLenum theDataType) |
263 | { |
264 | return init (theGlCtx, theComponentsNb, theElemsNb, theData, theDataType, GLsizei(theComponentsNb) * GLsizei(sizeOfGlType (theDataType))); |
265 | } |
266 | |
267 | //! Update part of the buffer with new data. |
7d3e64ef |
268 | Standard_EXPORT virtual bool subData (const Handle(OpenGl_Context)& theGlCtx, |
269 | const GLsizei theElemFrom, |
270 | const GLsizei theElemsNb, |
271 | const void* theData, |
272 | const GLenum theDataType); |
273 | |
274 | //! Setup array pointer - either for active GLSL program OpenGl_Context::ActiveProgram() |
275 | //! or for FFP using bindFixed() when no program bound. |
276 | static void bindAttribute (const Handle(OpenGl_Context)& theGlCtx, |
277 | const Graphic3d_TypeOfAttribute theMode, |
278 | const GLint theNbComp, |
279 | const GLenum theDataType, |
280 | const GLsizei theStride, |
281 | const GLvoid* theOffset); |
282 | |
283 | //! Disable GLSL array pointer - either for active GLSL program OpenGl_Context::ActiveProgram() |
284 | //! or for FFP using unbindFixed() when no program bound. |
285 | static void unbindAttribute (const Handle(OpenGl_Context)& theGlCtx, |
286 | const Graphic3d_TypeOfAttribute theMode); |
287 | |
288 | private: |
ca3c13d1 |
289 | #if !defined(GL_ES_VERSION_2_0) |
871fa103 |
290 | //! Setup FFP array pointer. |
291 | static void bindFixed (const Handle(OpenGl_Context)& theGlCtx, |
292 | const Graphic3d_TypeOfAttribute theMode, |
293 | const GLint theNbComp, |
294 | const GLenum theDataType, |
295 | const GLsizei theStride, |
7d3e64ef |
296 | const GLvoid* theOffset); |
871fa103 |
297 | |
298 | //! Disable FFP array pointer. |
299 | static void unbindFixed (const Handle(OpenGl_Context)& theGlCtx, |
7d3e64ef |
300 | const Graphic3d_TypeOfAttribute theMode); |
ca3c13d1 |
301 | #endif |
871fa103 |
302 | public: //! @name methods for interleaved attributes array |
303 | |
7d3e64ef |
304 | //! @return true if buffer contains per-vertex color attribute |
305 | Standard_EXPORT virtual bool HasColorAttribute() const; |
306 | |
307 | //! @return true if buffer contains per-vertex normal attribute |
308 | Standard_EXPORT virtual bool HasNormalAttribute() const; |
871fa103 |
309 | |
7d3e64ef |
310 | //! Bind all vertex attributes to active program OpenGl_Context::ActiveProgram() or for FFP. |
311 | //! Default implementation does nothing. |
312 | Standard_EXPORT virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const; |
871fa103 |
313 | |
7d3e64ef |
314 | //! Bind vertex position attribute only. Default implementation does nothing. |
315 | Standard_EXPORT virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const; |
871fa103 |
316 | |
7d3e64ef |
317 | //! Unbind all vertex attributes. Default implementation does nothing. |
318 | Standard_EXPORT virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const; |
871fa103 |
319 | |
5e27df78 |
320 | protected: |
321 | |
7d3e64ef |
322 | GLubyte* myOffset; //!< offset to data |
323 | GLuint myBufferId; //!< VBO name (index) |
324 | GLuint myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4 |
325 | GLsizei myElemsNb; //!< Number of vertex attributes / number of vertices |
326 | GLenum myDataType; //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.) |
5e27df78 |
327 | |
328 | public: |
329 | |
92efcf78 |
330 | DEFINE_STANDARD_RTTIEXT(OpenGl_VertexBuffer,OpenGl_Resource) // Type definition |
5e27df78 |
331 | |
332 | }; |
333 | |
334 | DEFINE_STANDARD_HANDLE(OpenGl_VertexBuffer, OpenGl_Resource) |
335 | |
7d3e64ef |
336 | #include <OpenGl_VertexBuffer.lxx> |
337 | |
5e27df78 |
338 | #endif // _OpenGl_VertexBuffer_H__ |