Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-05 08:34:43

0001 // Created by: Kirill GAVRILOV
0002 // Copyright (c) 2013-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef OpenGl_VertexBufferEditor_HeaderFile
0016 #define OpenGl_VertexBufferEditor_HeaderFile
0017 
0018 #include <OpenGl_Buffer.hxx>
0019 #include <OpenGl_Context.hxx>
0020 
0021 #include <NCollection_Array1.hxx>
0022 
0023 //! Auxiliary class to iteratively modify data of existing VBO.
0024 //! It provides iteration interface with delayed CPU->GPU memory transfer to avoid slow per-element
0025 //! data transfer. User should explicitly call Flush() method to ensure that all data is transferred
0026 //! to VBO. Temporary buffer on CPU side can be initialized with lesser capacity than  VBO to allow
0027 //! re-usage of shared buffer with fixed size between VBOs.
0028 //!
0029 //! You should use NCollection_Vec2/NCollection_Vec3/NCollection_Vec4 with appropriate length
0030 //! to instantiate this template and access elements in VBO.
0031 //!
0032 //! Notice that this technique designed for VBO streaming scenarios (when VBO is modified from time
0033 //! to time). Also this class doesn't retrieve existing data from VBO - data transferred only in one
0034 //! direction! In case of static data this is preferred to upload it within one call during VBO
0035 //! initialization.
0036 template <typename theVec_t>
0037 class OpenGl_VertexBufferEditor
0038 {
0039 
0040 public:
0041   //! Creates empty editor
0042   //! theTmpBufferLength[in]  temporary buffer length
0043   explicit OpenGl_VertexBufferEditor(const Standard_Integer theTmpBufferLength = 0)
0044       : myElemFrom(0),
0045         myElemsNb(0),
0046         myTmpBuffer(0, theTmpBufferLength > 0 ? (theTmpBufferLength - 1) : 2047)
0047   {
0048   }
0049 
0050   //! Creates empty editor
0051   //! theTmpBuffer[in]        pointer to temporary buffer
0052   //! theTmpBufferLength[in]  temporary buffer length
0053   OpenGl_VertexBufferEditor(theVec_t* theTmpBuffer, const Standard_Integer theTmpBufferLength)
0054       : myElemFrom(0),
0055         myElemsNb(0),
0056         myTmpBuffer(theTmpBuffer[0], 0, theTmpBufferLength - 1)
0057   {
0058   }
0059 
0060   //! Initialize editor for specified buffer object.
0061   //! theGlCtx[in]  bound OpenGL context to edit buffer object
0062   //! theVbo[in]    buffer to edit
0063   Standard_Boolean Init(const Handle(OpenGl_Context)& theGlCtx, const Handle(OpenGl_Buffer)& theVbo)
0064   {
0065     myGlCtx = theGlCtx;
0066     myVbo   = theVbo;
0067     if (myGlCtx.IsNull() || myVbo.IsNull() || !myVbo->IsValid()
0068         || myVbo->GetComponentsNb() != GLuint(theVec_t::Length()))
0069     {
0070       return Standard_False;
0071     }
0072 
0073     myElemFrom = myElemsNb = 0;
0074     return Standard_True;
0075   }
0076 
0077   //! Modify current element in VBO.
0078   theVec_t& Value() { return myTmpBuffer.ChangeValue(myElemsNb); }
0079 
0080   //! Move to the next position in VBO.
0081   Standard_Boolean Next()
0082   {
0083     if (++myElemsNb > myTmpBuffer.Upper())
0084     {
0085       return Flush();
0086     }
0087     return Standard_True;
0088   }
0089 
0090   //! Push current data from local buffer to VBO.
0091   Standard_Boolean Flush()
0092   {
0093     if (myElemsNb <= 0)
0094     {
0095       return Standard_True;
0096     }
0097 
0098     if (myVbo.IsNull() || !myVbo->SubData(myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value(0)[0]))
0099     {
0100       // should never happens
0101       return Standard_False;
0102     }
0103     myElemFrom += myElemsNb;
0104     myElemsNb = 0;
0105 
0106     return Standard_True;
0107   }
0108 
0109   //! @return assigned VBO
0110   const Handle(OpenGl_Buffer)& GetVBO() const { return myVbo; }
0111 
0112 private:
0113   Handle(OpenGl_Context)       myGlCtx;     //!< handle to current OpenGL context
0114   Handle(OpenGl_Buffer)        myVbo;       //!< edited VBO
0115   Standard_Integer             myElemFrom;  //!< element in VBO to upload from
0116   Standard_Integer             myElemsNb;   //!< current element in temporary buffer
0117   NCollection_Array1<theVec_t> myTmpBuffer; //!< temporary array
0118 };
0119 
0120 #endif // _OpenGl_VertexBufferEditor_H__