1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #ifndef _OpenGl_VertexBuffer_H__
16 #define _OpenGl_VertexBuffer_H__
18 #include <OpenGl_GlCore20.hxx>
19 #include <OpenGl_Resource.hxx>
20 #include <OpenGl_Context.hxx>
21 #include <OpenGl_ShaderProgram.hxx>
23 #include <Graphic3d_IndexBuffer.hxx>
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
33 static const GLuint NO_BUFFER = 0;
37 //! Create uninitialized VBO.
38 Standard_EXPORT OpenGl_VertexBuffer();
41 Standard_EXPORT virtual ~OpenGl_VertexBuffer();
43 Standard_EXPORT virtual GLenum GetTarget() const;
45 //! Return TRUE if this is a virtual (for backward compatibility) VBO object.
46 virtual bool IsVirtual() const { return false; }
48 //! @return true if current object was initialized
49 inline bool IsValid() const
51 return myBufferId != NO_BUFFER;
54 //! @return the number of components per generic vertex attribute.
55 inline GLuint GetComponentsNb() const
57 return myComponentsNb;
60 //! @return number of vertex attributes / number of vertices specified within ::Init()
61 inline GLsizei GetElemsNb() const
66 //! Overrides the number of vertex attributes / number of vertexes.
67 //! It is up to user specifying this number correct (e.g. below initial value)!
68 void SetElemsNb (GLsizei theNbElems) { myElemsNb = theNbElems; }
70 //! @return data type of each component in the array.
71 inline GLenum GetDataType() const
76 //! @return offset to data, NULL by default
77 inline GLubyte* GetDataOffset() const
82 //! Creates VBO name (id) if not yet generated.
83 //! Data should be initialized by another method.
84 Standard_EXPORT virtual bool Create (const Handle(OpenGl_Context)& theGlCtx);
86 //! Destroy object - will release GPU memory if any.
87 Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx) Standard_OVERRIDE;
90 Standard_EXPORT virtual void Bind (const Handle(OpenGl_Context)& theGlCtx) const;
93 Standard_EXPORT virtual void Unbind (const Handle(OpenGl_Context)& theGlCtx) const;
95 //! Notice that VBO will be unbound after this call.
96 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
97 //! @param theElemsNb - elements count;
98 //! @param theData - pointer to GLfloat data (vertices/normals etc.).
99 bool Init (const Handle(OpenGl_Context)& theGlCtx,
100 const GLuint theComponentsNb,
101 const GLsizei theElemsNb,
102 const GLfloat* theData)
104 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_FLOAT);
107 //! Notice that VBO will be unbound after this call.
108 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
109 //! @param theElemsNb - elements count;
110 //! @param theData - pointer to GLuint data (indices etc.).
111 bool Init (const Handle(OpenGl_Context)& theGlCtx,
112 const GLuint theComponentsNb,
113 const GLsizei theElemsNb,
114 const GLuint* theData)
116 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_INT);
119 //! Notice that VBO will be unbound after this call.
120 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
121 //! @param theElemsNb - elements count;
122 //! @param theData - pointer to GLushort data (indices etc.).
123 bool Init (const Handle(OpenGl_Context)& theGlCtx,
124 const GLuint theComponentsNb,
125 const GLsizei theElemsNb,
126 const GLushort* theData)
128 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_SHORT);
131 //! Notice that VBO will be unbound after this call.
132 //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
133 //! @param theElemsNb - elements count;
134 //! @param theData - pointer to GLubyte data (indices/colors etc.).
135 bool Init (const Handle(OpenGl_Context)& theGlCtx,
136 const GLuint theComponentsNb,
137 const GLsizei theElemsNb,
138 const GLubyte* theData)
140 return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_BYTE);
143 //! Notice that VBO will be unbound after this call.
144 //! Function replaces portion of data within this VBO using glBufferSubData().
145 //! The VBO should be initialized before call.
146 //! @param theElemFrom - element id from which replace buffer data (>=0);
147 //! @param theElemsNb - elements count (theElemFrom + theElemsNb <= GetElemsNb());
148 //! @param theData - pointer to GLfloat data.
149 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
150 const GLsizei theElemFrom,
151 const GLsizei theElemsNb,
152 const GLfloat* theData)
154 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
157 //! Read back buffer sub-range.
158 //! Notice that VBO will be unbound after this call.
159 //! Function reads portion of data from this VBO using glGetBufferSubData().
160 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
161 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
162 //! @param theData [out] destination pointer to GLfloat data.
163 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
164 const GLsizei theElemFrom,
165 const GLsizei theElemsNb,
168 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
171 //! Notice that VBO will be unbound after this call.
172 //! Function replaces portion of data within this VBO using glBufferSubData().
173 //! The VBO should be initialized before call.
174 //! @param theElemFrom element id from which replace buffer data (>=0);
175 //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb());
176 //! @param theData pointer to GLuint data.
177 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
178 const GLsizei theElemFrom,
179 const GLsizei theElemsNb,
180 const GLuint* theData)
182 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
185 //! Read back buffer sub-range.
186 //! Notice that VBO will be unbound after this call.
187 //! Function reads portion of data from this VBO using glGetBufferSubData().
188 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
189 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
190 //! @param theData [out] destination pointer to GLuint data.
191 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
192 const GLsizei theElemFrom,
193 const GLsizei theElemsNb,
196 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
199 //! Notice that VBO will be unbound after this call.
200 //! Function replaces portion of data within this VBO using glBufferSubData().
201 //! The VBO should be initialized before call.
202 //! @param theElemFrom element id from which replace buffer data (>=0);
203 //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb());
204 //! @param theData pointer to GLushort data.
205 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
206 const GLsizei theElemFrom,
207 const GLsizei theElemsNb,
208 const GLushort* theData)
210 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
213 //! Read back buffer sub-range.
214 //! Notice that VBO will be unbound after this call.
215 //! Function reads portion of data from this VBO using glGetBufferSubData().
216 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
217 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
218 //! @param theData [out] destination pointer to GLushort data.
219 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
220 const GLsizei theElemFrom,
221 const GLsizei theElemsNb,
224 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
227 //! Notice that VBO will be unbound after this call.
228 //! Function replaces portion of data within this VBO using glBufferSubData().
229 //! The VBO should be initialized before call.
230 //! @param theElemFrom element id from which replace buffer data (>=0);
231 //! @param theElemsNb elements count (theElemFrom + theElemsNb <= GetElemsNb());
232 //! @param theData pointer to GLubyte data.
233 bool SubData (const Handle(OpenGl_Context)& theGlCtx,
234 const GLsizei theElemFrom,
235 const GLsizei theElemsNb,
236 const GLubyte* theData)
238 return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
241 //! Read back buffer sub-range.
242 //! Notice that VBO will be unbound after this call.
243 //! Function reads portion of data from this VBO using glGetBufferSubData().
244 //! @param theElemFrom [in] element id from which replace buffer data (>=0);
245 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
246 //! @param theData [out] destination pointer to GLubyte data.
247 bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
248 const GLsizei theElemFrom,
249 const GLsizei theElemsNb,
252 return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
255 //! Bind this VBO to active GLSL program.
256 Standard_EXPORT void BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
257 const GLuint theAttribLoc) const;
259 //! Unbind any VBO from active GLSL program.
260 Standard_EXPORT void UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
261 const GLuint theAttribLoc) const;
263 //! Bind this VBO and enable specified attribute in OpenGl_Context::ActiveProgram() or FFP.
264 //! @param theGlCtx - handle to bound GL context;
265 //! @param theMode - array mode (GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY).
266 void BindAttribute (const Handle(OpenGl_Context)& theCtx,
267 const Graphic3d_TypeOfAttribute theMode) const
272 bindAttribute (theCtx, theMode, static_cast<GLint> (myComponentsNb), myDataType, 0, myOffset);
276 //! Unbind this VBO and disable specified attribute in OpenGl_Context::ActiveProgram() or FFP.
277 //! @param theCtx handle to bound GL context
278 //! @param theMode array mode
279 void UnbindAttribute (const Handle(OpenGl_Context)& theCtx,
280 const Graphic3d_TypeOfAttribute theMode) const
285 unbindAttribute (theCtx, theMode);
289 public: //! @name advanced methods
291 //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
292 virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE
295 ? sizeOfGlType (myDataType) * myComponentsNb * myElemsNb
299 //! @return size of specified GL type
300 static size_t sizeOfGlType (const GLenum theType)
305 case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
307 case GL_UNSIGNED_SHORT: return sizeof(GLushort);
311 case GL_UNSIGNED_INT: return sizeof(GLuint);
312 case GL_FLOAT: return sizeof(GLfloat);
314 case GL_DOUBLE: return sizeof(GLdouble);
320 //! Initialize buffer with new data.
321 Standard_EXPORT virtual bool init (const Handle(OpenGl_Context)& theGlCtx,
322 const GLuint theComponentsNb,
323 const GLsizei theElemsNb,
325 const GLenum theDataType,
326 const GLsizei theStride);
328 //! Initialize buffer with new data.
329 bool init (const Handle(OpenGl_Context)& theGlCtx,
330 const GLuint theComponentsNb,
331 const GLsizei theElemsNb,
333 const GLenum theDataType)
335 return init (theGlCtx, theComponentsNb, theElemsNb, theData, theDataType, GLsizei(theComponentsNb) * GLsizei(sizeOfGlType (theDataType)));
338 //! Update part of the buffer with new data.
339 Standard_EXPORT virtual bool subData (const Handle(OpenGl_Context)& theGlCtx,
340 const GLsizei theElemFrom,
341 const GLsizei theElemsNb,
343 const GLenum theDataType);
345 //! Read back buffer sub-range.
346 Standard_EXPORT virtual bool getSubData (const Handle(OpenGl_Context)& theGlCtx,
347 const GLsizei theElemFrom,
348 const GLsizei theElemsNb,
350 const GLenum theDataType);
352 //! Setup array pointer - either for active GLSL program OpenGl_Context::ActiveProgram()
353 //! or for FFP using bindFixed() when no program bound.
354 static void bindAttribute (const Handle(OpenGl_Context)& theGlCtx,
355 const Graphic3d_TypeOfAttribute theMode,
356 const GLint theNbComp,
357 const GLenum theDataType,
358 const GLsizei theStride,
359 const GLvoid* theOffset);
361 //! Disable GLSL array pointer - either for active GLSL program OpenGl_Context::ActiveProgram()
362 //! or for FFP using unbindFixed() when no program bound.
363 static void unbindAttribute (const Handle(OpenGl_Context)& theGlCtx,
364 const Graphic3d_TypeOfAttribute theMode);
367 #if !defined(GL_ES_VERSION_2_0)
368 //! Setup FFP array pointer.
369 static void bindFixed (const Handle(OpenGl_Context)& theGlCtx,
370 const Graphic3d_TypeOfAttribute theMode,
371 const GLint theNbComp,
372 const GLenum theDataType,
373 const GLsizei theStride,
374 const GLvoid* theOffset);
376 //! Disable FFP array pointer.
377 static void unbindFixed (const Handle(OpenGl_Context)& theGlCtx,
378 const Graphic3d_TypeOfAttribute theMode);
380 //! Disable FFP color array pointer.
381 Standard_EXPORT static void unbindFixedColor (const Handle(OpenGl_Context)& theCtx);
384 public: //! @name methods for interleaved attributes array
386 //! @return true if buffer contains per-vertex color attribute
387 Standard_EXPORT virtual bool HasColorAttribute() const;
389 //! @return true if buffer contains per-vertex normal attribute
390 Standard_EXPORT virtual bool HasNormalAttribute() const;
392 //! Bind all vertex attributes to active program OpenGl_Context::ActiveProgram() or for FFP.
393 //! Default implementation does nothing.
394 Standard_EXPORT virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const;
396 //! Bind vertex position attribute only. Default implementation does nothing.
397 Standard_EXPORT virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const;
399 //! Unbind all vertex attributes. Default implementation does nothing.
400 Standard_EXPORT virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const;
402 //! Dumps the content of me into the stream
403 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
407 GLubyte* myOffset; //!< offset to data
408 GLuint myBufferId; //!< VBO name (index)
409 GLuint myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4
410 GLsizei myElemsNb; //!< Number of vertex attributes / number of vertices
411 GLenum myDataType; //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.)
415 DEFINE_STANDARD_RTTIEXT(OpenGl_VertexBuffer,OpenGl_Resource) // Type definition
419 DEFINE_STANDARD_HANDLE(OpenGl_VertexBuffer, OpenGl_Resource)
421 #include <OpenGl_VertexBuffer.lxx>
423 #endif // _OpenGl_VertexBuffer_H__