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_VertexBufferEditor_HeaderFile
16 #define OpenGl_VertexBufferEditor_HeaderFile
18 #include <OpenGl_Buffer.hxx>
19 #include <OpenGl_Context.hxx>
21 #include <NCollection_Array1.hxx>
23 //! Auxiliary class to iteratively modify data of existing VBO.
24 //! It provides iteration interface with delayed CPU->GPU memory transfer to avoid slow per-element data transfer.
25 //! User should explicitly call Flush() method to ensure that all data is transferred to VBO.
26 //! Temporary buffer on CPU side can be initialized with lesser capacity than VBO
27 //! to allow re-usage of shared buffer with fixed size between VBOs.
29 //! You should use NCollection_Vec2/NCollection_Vec3/NCollection_Vec4 with appropriate length
30 //! to instantiate this template and access elements in VBO.
32 //! Notice that this technique designed for VBO streaming scenarios (when VBO is modified from time to time).
33 //! Also this class doesn't retrieve existing data from VBO - data transferred only in one direction!
34 //! In case of static data this is preferred to upload it within one call during VBO initialization.
35 template<typename theVec_t>
36 class OpenGl_VertexBufferEditor
41 //! Creates empty editor
42 //! theTmpBufferLength [in] temporary buffer length
43 explicit OpenGl_VertexBufferEditor (const Standard_Integer theTmpBufferLength = 0)
46 myTmpBuffer (0, theTmpBufferLength > 0 ? (theTmpBufferLength - 1) : 2047) {}
48 //! Creates empty editor
49 //! theTmpBuffer [in] pointer to temporary buffer
50 //! theTmpBufferLength [in] temporary buffer length
51 OpenGl_VertexBufferEditor (theVec_t* theTmpBuffer,
52 const Standard_Integer theTmpBufferLength)
55 myTmpBuffer (theTmpBuffer[0], 0, theTmpBufferLength - 1) {}
57 //! Initialize editor for specified buffer object.
58 //! theGlCtx [in] bound OpenGL context to edit buffer object
59 //! theVbo [in] buffer to edit
60 Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
61 const Handle(OpenGl_Buffer)& theVbo)
65 if (myGlCtx.IsNull() || myVbo.IsNull() || !myVbo->IsValid() || myVbo->GetComponentsNb() != GLuint (theVec_t::Length()))
67 return Standard_False;
70 myElemFrom = myElemsNb = 0;
74 //! Modify current element in VBO.
77 return myTmpBuffer.ChangeValue (myElemsNb);
80 //! Move to the next position in VBO.
81 Standard_Boolean Next()
83 if (++myElemsNb > myTmpBuffer.Upper())
90 //! Push current data from local buffer to VBO.
91 Standard_Boolean Flush()
99 || !myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
101 // should never happens
102 return Standard_False;
104 myElemFrom += myElemsNb;
107 return Standard_True;
110 //! @return assigned VBO
111 const Handle(OpenGl_Buffer)& GetVBO() const { return myVbo; }
115 Handle(OpenGl_Context) myGlCtx; //!< handle to current OpenGL context
116 Handle(OpenGl_Buffer) myVbo; //!< edited VBO
117 Standard_Integer myElemFrom; //!< element in VBO to upload from
118 Standard_Integer myElemsNb; //!< current element in temporary buffer
119 NCollection_Array1<theVec_t> myTmpBuffer; //!< temporary array
123 #endif // _OpenGl_VertexBufferEditor_H__