Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:36

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 data transfer.
0025 //! User should explicitly call Flush() method to ensure that all data is transferred to VBO.
0026 //! Temporary buffer on CPU side can be initialized with lesser capacity than  VBO
0027 //! to allow 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 to time).
0033 //! Also this class doesn't retrieve existing data from VBO - data transferred only in one direction!
0034 //! In case of static data this is preferred to upload it within one call during VBO initialization.
0035 template<typename theVec_t>
0036 class OpenGl_VertexBufferEditor
0037 {
0038 
0039 public:
0040 
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   //! Creates empty editor
0049   //! theTmpBuffer       [in] pointer to temporary buffer
0050   //! theTmpBufferLength [in] temporary buffer length
0051   OpenGl_VertexBufferEditor (theVec_t*              theTmpBuffer,
0052                              const Standard_Integer theTmpBufferLength)
0053   : myElemFrom (0),
0054     myElemsNb (0),
0055     myTmpBuffer (theTmpBuffer[0], 0, theTmpBufferLength - 1) {}
0056 
0057   //! Initialize editor for specified buffer object.
0058   //! theGlCtx [in] bound OpenGL context to edit buffer object
0059   //! theVbo   [in] buffer to edit
0060   Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
0061                          const Handle(OpenGl_Buffer)&  theVbo)
0062   {
0063     myGlCtx = theGlCtx;
0064     myVbo   = theVbo;
0065     if (myGlCtx.IsNull() || myVbo.IsNull() || !myVbo->IsValid() || myVbo->GetComponentsNb() != GLuint (theVec_t::Length()))
0066     {
0067       return Standard_False;
0068     }
0069 
0070     myElemFrom = myElemsNb = 0;
0071     return Standard_True;
0072   }
0073 
0074   //! Modify current element in VBO.
0075   theVec_t& Value()
0076   {
0077     return myTmpBuffer.ChangeValue (myElemsNb);
0078   }
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()
0099      || !myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
0100     {
0101       // should never happens
0102       return Standard_False;
0103     }
0104     myElemFrom += myElemsNb;
0105     myElemsNb = 0;
0106 
0107     return Standard_True;
0108   }
0109 
0110   //! @return assigned VBO
0111   const Handle(OpenGl_Buffer)& GetVBO() const { return myVbo; }
0112 
0113 private:
0114 
0115   Handle(OpenGl_Context)       myGlCtx;     //!< handle to current OpenGL context
0116   Handle(OpenGl_Buffer)        myVbo;       //!< edited VBO
0117   Standard_Integer             myElemFrom;  //!< element in VBO to upload from
0118   Standard_Integer             myElemsNb;   //!< current element in temporary buffer
0119   NCollection_Array1<theVec_t> myTmpBuffer; //!< temporary array
0120 
0121 };
0122 
0123 #endif // _OpenGl_VertexBufferEditor_H__