0030640: Visualization, Graphic3d_Camera - add option creating Projection matrix...
[occt.git] / src / OpenGl / OpenGl_VertexBuffer.hxx
CommitLineData
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.
27class OpenGl_VertexBuffer : public OpenGl_Resource
28{
29
30public:
31
32 //! Helpful constants
33 static const GLuint NO_BUFFER = 0;
34
a46ab511 35 //! Format VBO target enumeration value.
36 Standard_EXPORT static TCollection_AsciiString FormatTarget (GLenum theTarget);
37
5e27df78 38public:
39
40 //! Create uninitialized VBO.
41 Standard_EXPORT OpenGl_VertexBuffer();
42
43 //! Destroy object.
44 Standard_EXPORT virtual ~OpenGl_VertexBuffer();
45
46 Standard_EXPORT virtual GLenum GetTarget() const;
47
da87ddc3 48 //! Return TRUE if this is a virtual (for backward compatibility) VBO object.
49 virtual bool IsVirtual() const { return false; }
50
5e27df78 51 //! @return true if current object was initialized
52 inline bool IsValid() const
53 {
54 return myBufferId != NO_BUFFER;
55 }
56
57 //! @return the number of components per generic vertex attribute.
58 inline GLuint GetComponentsNb() const
59 {
60 return myComponentsNb;
61 }
62
da87ddc3 63 //! @return number of vertex attributes / number of vertices specified within ::Init()
5e27df78 64 inline GLsizei GetElemsNb() const
65 {
66 return myElemsNb;
67 }
68
da87ddc3 69 //! Overrides the number of vertex attributes / number of vertexes.
70 //! It is up to user specifying this number correct (e.g. below initial value)!
71 void SetElemsNb (GLsizei theNbElems) { myElemsNb = theNbElems; }
72
5e27df78 73 //! @return data type of each component in the array.
74 inline GLenum GetDataType() const
75 {
76 return myDataType;
77 }
78
7d3e64ef 79 //! @return offset to data, NULL by default
80 inline GLubyte* GetDataOffset() const
81 {
82 return myOffset;
83 }
84
5e27df78 85 //! Creates VBO name (id) if not yet generated.
86 //! Data should be initialized by another method.
7d3e64ef 87 Standard_EXPORT virtual bool Create (const Handle(OpenGl_Context)& theGlCtx);
5e27df78 88
89 //! Destroy object - will release GPU memory if any.
79104795 90 Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx) Standard_OVERRIDE;
5e27df78 91
92 //! Bind this VBO.
7d3e64ef 93 Standard_EXPORT virtual void Bind (const Handle(OpenGl_Context)& theGlCtx) const;
5e27df78 94
95 //! Unbind this VBO.
7d3e64ef 96 Standard_EXPORT virtual void Unbind (const Handle(OpenGl_Context)& theGlCtx) const;
5e27df78 97
98 //! Notice that VBO will be unbound after this call.
99 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
100 //! @param theElemsNb - elements count;
101 //! @param theData - pointer to GLfloat data (vertices/normals etc.).
871fa103 102 bool Init (const Handle(OpenGl_Context)& theGlCtx,
103 const GLuint theComponentsNb,
104 const GLsizei theElemsNb,
105 const GLfloat* theData)
106 {
107 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_FLOAT);
108 }
5e27df78 109
110 //! Notice that VBO will be unbound after this call.
111 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
112 //! @param theElemsNb - elements count;
113 //! @param theData - pointer to GLuint data (indices etc.).
871fa103 114 bool Init (const Handle(OpenGl_Context)& theGlCtx,
115 const GLuint theComponentsNb,
116 const GLsizei theElemsNb,
117 const GLuint* theData)
118 {
119 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_INT);
120 }
121
122 //! Notice that VBO will be unbound after this call.
123 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
124 //! @param theElemsNb - elements count;
125 //! @param theData - pointer to GLushort data (indices etc.).
126 bool Init (const Handle(OpenGl_Context)& theGlCtx,
127 const GLuint theComponentsNb,
128 const GLsizei theElemsNb,
129 const GLushort* theData)
130 {
131 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_SHORT);
132 }
5e27df78 133
134 //! Notice that VBO will be unbound after this call.
135 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
136 //! @param theElemsNb - elements count;
137 //! @param theData - pointer to GLubyte data (indices/colors etc.).
871fa103 138 bool Init (const Handle(OpenGl_Context)& theGlCtx,
139 const GLuint theComponentsNb,
140 const GLsizei theElemsNb,
141 const GLubyte* theData)
142 {
143 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_BYTE);
144 }
5e27df78 145
146 //! Notice that VBO will be unbound after this call.
147 //! Function replaces portion of data within this VBO using glBufferSubData().
148 //! The VBO should be initialized before call.
149 //! @param theElemFrom - element id from which replace buffer data (>=0);
99d99a6d 150 //! @param theElemsNb - elements count (theElemFrom + theElemsNb <= GetElemsNb());
5e27df78 151 //! @param theData - pointer to GLfloat data.
871fa103 152 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
153 const GLsizei theElemFrom,
154 const GLsizei theElemsNb,
155 const GLfloat* theData)
156 {
157 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
158 }
5e27df78 159
d4cefcc0 160 //! Read back buffer sub-range.
161 //! Notice that VBO will be unbound after this call.
162 //! Function reads portion of data from this VBO using glGetBufferSubData().
163 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
164 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
165 //! @param theData [out] destination pointer to GLfloat data.
166 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
167 const GLsizei theElemFrom,
168 const GLsizei theElemsNb,
169 GLfloat* theData)
170 {
171 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
172 }
173
99d99a6d 174 //! Notice that VBO will be unbound after this call.
175 //! Function replaces portion of data within this VBO using glBufferSubData().
176 //! The VBO should be initialized before call.
177 //! @param theElemFrom element id from which replace buffer data (>=0);
178 //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb());
179 //! @param theData pointer to GLuint data.
871fa103 180 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
181 const GLsizei theElemFrom,
182 const GLsizei theElemsNb,
183 const GLuint* theData)
184 {
185 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
186 }
187
d4cefcc0 188 //! Read back buffer sub-range.
189 //! Notice that VBO will be unbound after this call.
190 //! Function reads portion of data from this VBO using glGetBufferSubData().
191 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
192 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
193 //! @param theData [out] destination pointer to GLuint data.
194 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
195 const GLsizei theElemFrom,
196 const GLsizei theElemsNb,
197 GLuint* theData)
198 {
199 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
200 }
201
871fa103 202 //! Notice that VBO will be unbound after this call.
203 //! Function replaces portion of data within this VBO using glBufferSubData().
204 //! The VBO should be initialized before call.
205 //! @param theElemFrom element id from which replace buffer data (>=0);
206 //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb());
207 //! @param theData pointer to GLushort data.
208 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
209 const GLsizei theElemFrom,
210 const GLsizei theElemsNb,
211 const GLushort* theData)
212 {
213 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
214 }
99d99a6d 215
d4cefcc0 216 //! Read back buffer sub-range.
217 //! Notice that VBO will be unbound after this call.
218 //! Function reads portion of data from this VBO using glGetBufferSubData().
219 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
220 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
221 //! @param theData [out] destination pointer to GLushort data.
222 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
223 const GLsizei theElemFrom,
224 const GLsizei theElemsNb,
225 GLushort* theData)
226 {
227 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
228 }
229
99d99a6d 230 //! Notice that VBO will be unbound after this call.
231 //! Function replaces portion of data within this VBO using glBufferSubData().
232 //! The VBO should be initialized before call.
233 //! @param theElemFrom element id from which replace buffer data (>=0);
234 //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb());
235 //! @param theData pointer to GLubyte data.
871fa103 236 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
237 const GLsizei theElemFrom,
238 const GLsizei theElemsNb,
239 const GLubyte* theData)
240 {
241 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
242 }
99d99a6d 243
d4cefcc0 244 //! Read back buffer sub-range.
245 //! Notice that VBO will be unbound after this call.
246 //! Function reads portion of data from this VBO using glGetBufferSubData().
247 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
248 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
249 //! @param theData [out] destination pointer to GLubyte data.
250 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
251 const GLsizei theElemFrom,
252 const GLsizei theElemsNb,
253 GLubyte* theData)
254 {
255 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
256 }
257
5e27df78 258 //! Bind this VBO to active GLSL program.
259 Standard_EXPORT void BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
260 const GLuint theAttribLoc) const;
261
262 //! Unbind any VBO from active GLSL program.
263 Standard_EXPORT void UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
264 const GLuint theAttribLoc) const;
265
7d3e64ef 266 //! Bind this VBO and enable specified attribute in OpenGl_Context::ActiveProgram() or FFP.
5e27df78 267 //! @param theGlCtx - handle to bound GL context;
268 //! @param theMode - array mode (GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY).
7d3e64ef 269 void BindAttribute (const Handle(OpenGl_Context)& theCtx,
270 const Graphic3d_TypeOfAttribute theMode) const
271 {
272 if (IsValid())
273 {
274 Bind (theCtx);
275 bindAttribute (theCtx, theMode, static_cast<GLint> (myComponentsNb), myDataType, 0, myOffset);
276 }
277 }
5e27df78 278
7d3e64ef 279 //! Unbind this VBO and disable specified attribute in OpenGl_Context::ActiveProgram() or FFP.
280 //! @param theCtx handle to bound GL context
281 //! @param theMode array mode
282 void UnbindAttribute (const Handle(OpenGl_Context)& theCtx,
283 const Graphic3d_TypeOfAttribute theMode) const
284 {
285 if (IsValid())
286 {
287 Unbind (theCtx);
288 unbindAttribute (theCtx, theMode);
289 }
290 }
5e27df78 291
871fa103 292public: //! @name advanced methods
293
15669413 294 //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
295 virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE
296 {
297 return IsValid()
298 ? sizeOfGlType (myDataType) * myComponentsNb * myElemsNb
299 : 0;
300 }
301
871fa103 302 //! @return size of specified GL type
303 static size_t sizeOfGlType (const GLenum theType)
304 {
305 switch (theType)
306 {
307 case GL_BYTE:
308 case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
309 case GL_SHORT:
310 case GL_UNSIGNED_SHORT: return sizeof(GLushort);
ca3c13d1 311 #ifdef GL_INT
871fa103 312 case GL_INT:
ca3c13d1 313 #endif
871fa103 314 case GL_UNSIGNED_INT: return sizeof(GLuint);
315 case GL_FLOAT: return sizeof(GLfloat);
ca3c13d1 316 #ifdef GL_DOUBLE
871fa103 317 case GL_DOUBLE: return sizeof(GLdouble);
ca3c13d1 318 #endif
871fa103 319 default: return 0;
320 }
321 }
322
323 //! Initialize buffer with new data.
7d3e64ef 324 Standard_EXPORT virtual bool init (const Handle(OpenGl_Context)& theGlCtx,
325 const GLuint theComponentsNb,
326 const GLsizei theElemsNb,
327 const void* theData,
328 const GLenum theDataType,
329 const GLsizei theStride);
871fa103 330
331 //! Initialize buffer with new data.
332 bool init (const Handle(OpenGl_Context)& theGlCtx,
333 const GLuint theComponentsNb,
334 const GLsizei theElemsNb,
335 const void* theData,
336 const GLenum theDataType)
337 {
338 return init (theGlCtx, theComponentsNb, theElemsNb, theData, theDataType, GLsizei(theComponentsNb) * GLsizei(sizeOfGlType (theDataType)));
339 }
340
341 //! Update part of the buffer with new data.
7d3e64ef 342 Standard_EXPORT virtual bool subData (const Handle(OpenGl_Context)& theGlCtx,
343 const GLsizei theElemFrom,
344 const GLsizei theElemsNb,
345 const void* theData,
346 const GLenum theDataType);
347
d4cefcc0 348 //! Read back buffer sub-range.
349 Standard_EXPORT virtual bool getSubData (const Handle(OpenGl_Context)& theGlCtx,
350 const GLsizei theElemFrom,
351 const GLsizei theElemsNb,
352 void* theData,
353 const GLenum theDataType);
354
7d3e64ef 355 //! Setup array pointer - either for active GLSL program OpenGl_Context::ActiveProgram()
356 //! or for FFP using bindFixed() when no program bound.
357 static void bindAttribute (const Handle(OpenGl_Context)& theGlCtx,
358 const Graphic3d_TypeOfAttribute theMode,
359 const GLint theNbComp,
360 const GLenum theDataType,
361 const GLsizei theStride,
362 const GLvoid* theOffset);
363
364 //! Disable GLSL array pointer - either for active GLSL program OpenGl_Context::ActiveProgram()
365 //! or for FFP using unbindFixed() when no program bound.
366 static void unbindAttribute (const Handle(OpenGl_Context)& theGlCtx,
367 const Graphic3d_TypeOfAttribute theMode);
368
369private:
ca3c13d1 370#if !defined(GL_ES_VERSION_2_0)
871fa103 371 //! Setup FFP array pointer.
372 static void bindFixed (const Handle(OpenGl_Context)& theGlCtx,
373 const Graphic3d_TypeOfAttribute theMode,
374 const GLint theNbComp,
375 const GLenum theDataType,
376 const GLsizei theStride,
7d3e64ef 377 const GLvoid* theOffset);
871fa103 378
379 //! Disable FFP array pointer.
380 static void unbindFixed (const Handle(OpenGl_Context)& theGlCtx,
7d3e64ef 381 const Graphic3d_TypeOfAttribute theMode);
8613985b 382
383 //! Disable FFP color array pointer.
f114566d 384 Standard_EXPORT static void unbindFixedColor (const Handle(OpenGl_Context)& theCtx);
8613985b 385
ca3c13d1 386#endif
871fa103 387public: //! @name methods for interleaved attributes array
388
7d3e64ef 389 //! @return true if buffer contains per-vertex color attribute
390 Standard_EXPORT virtual bool HasColorAttribute() const;
391
392 //! @return true if buffer contains per-vertex normal attribute
393 Standard_EXPORT virtual bool HasNormalAttribute() const;
871fa103 394
7d3e64ef 395 //! Bind all vertex attributes to active program OpenGl_Context::ActiveProgram() or for FFP.
396 //! Default implementation does nothing.
397 Standard_EXPORT virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const;
871fa103 398
7d3e64ef 399 //! Bind vertex position attribute only. Default implementation does nothing.
400 Standard_EXPORT virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const;
871fa103 401
7d3e64ef 402 //! Unbind all vertex attributes. Default implementation does nothing.
403 Standard_EXPORT virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const;
871fa103 404
bc73b006 405 //! Dumps the content of me into the stream
406 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
407
5e27df78 408protected:
409
7d3e64ef 410 GLubyte* myOffset; //!< offset to data
411 GLuint myBufferId; //!< VBO name (index)
412 GLuint myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4
413 GLsizei myElemsNb; //!< Number of vertex attributes / number of vertices
414 GLenum myDataType; //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.)
5e27df78 415
416public:
417
92efcf78 418 DEFINE_STANDARD_RTTIEXT(OpenGl_VertexBuffer,OpenGl_Resource) // Type definition
5e27df78 419
420};
421
422DEFINE_STANDARD_HANDLE(OpenGl_VertexBuffer, OpenGl_Resource)
423
7d3e64ef 424#include <OpenGl_VertexBuffer.lxx>
425
5e27df78 426#endif // _OpenGl_VertexBuffer_H__