0024391: Erased AIS object can not be displayed in AIS_InteractiveContext after AIS_I...
[occt.git] / src / OpenGl / OpenGl_VertexBufferEditor.hxx
CommitLineData
5e27df78 1// Created by: Kirill GAVRILOV
2// Copyright (c) 2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19#ifndef _OpenGl_VertexBufferEditor_H__
20#define _OpenGl_VertexBufferEditor_H__
21
22#include <OpenGl_VertexBuffer.hxx>
23#include <OpenGl_Context.hxx>
24
25#include <NCollection_Array1.hxx>
26
27//! Auxiliary class to iteratively modify data of existing VBO.
28//! It provides iteration interface with delayed CPU->GPU memory transfer to avoid slow per-element data transfer.
29//! User should explicitly call Flush() method to ensure that all data is transferred to VBO.
30//! Temporary buffer on CPU side can be initialized with lesser capacity than VBO
31//! to allow re-usage of shared buffer with fixed size between VBOs.
32//!
33//! You should use NCollection_Vec2/NCollection_Vec3/NCollection_Vec4 with appropriate length
34//! to instantiate this template and access elements in VBO.
35//!
36//! Notice that this technique designed for VBO streaming scenarios (when VBO is modified from time to time).
37//! Also this class doesn't retrieve existing data from VBO - data transferred only in one direction!
38//! In case of static data this is preferred to upload it within one call during VBO initialization.
39template<typename theVec_t>
40class OpenGl_VertexBufferEditor
41{
42
43public:
44
45 //! Creates empty editor
46 //! theTmpBufferLength - temporary buffer length
47 OpenGl_VertexBufferEditor (const Standard_Integer theTmpBufferLength = 0)
48 : myElemFrom (0),
49 myElemsNb (0),
50 myTmpBuffer (0, theTmpBufferLength > 0 ? (theTmpBufferLength - 1) : 2047) {}
51
52 //! Creates empty editor
53 //! theTmpBuffer - pointer to temporary buffer
54 //! theTmpBufferLength - temporary buffer length
55 OpenGl_VertexBufferEditor (theVec_t* theTmpBuffer,
56 const Standard_Integer theTmpBufferLength)
57 : myElemFrom (0),
58 myElemsNb (0),
59 myTmpBuffer (theTmpBuffer[0], 0, theTmpBufferLength - 1) {}
60
61 //! Initialize editor for specified VBO.
62 //! theGlCtx - bound OpenGL context to edit VBO
63 //! theVbo - VBO to edit
64 Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
65 const Handle(OpenGl_VertexBuffer)& theVbo)
66 {
67 myGlCtx = theGlCtx;
68 myVbo = theVbo;
69 if (myGlCtx.IsNull() || myVbo.IsNull() || !myVbo->IsValid() || myVbo->GetComponentsNb() != GLuint (theVec_t::Length()))
70 {
71 return Standard_False;
72 }
73
74 myElemFrom = myElemsNb = 0;
75 return Standard_True;
76 }
77
78 //! Modify current element in VBO.
79 theVec_t& Value()
80 {
a174a3c5 81 return myTmpBuffer.ChangeValue (myElemsNb);
5e27df78 82 }
83
84 //! Move to the next position in VBO.
85 Standard_Boolean Next()
86 {
a174a3c5 87 if (++myElemsNb > myTmpBuffer.Upper())
88 {
89 return Flush();
90 }
91 return Standard_True;
5e27df78 92 }
93
94 //! Push current data from local buffer to VBO.
95 Standard_Boolean Flush()
96 {
a174a3c5 97 if (myElemsNb <= 0)
98 {
5e27df78 99 return Standard_True;
a174a3c5 100 }
101
102 if (myVbo.IsNull()
103 || !myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
104 {
105 // should never happens
106 return Standard_False;
107 }
108 myElemFrom += myElemsNb;
109 myElemsNb = 0;
110
111 return Standard_True;
5e27df78 112 }
113
99d99a6d 114 //! @return assigned VBO
115 inline const Handle(OpenGl_VertexBuffer)& GetVBO() const
116 {
117 return myVbo;
118 }
119
5e27df78 120private:
121
122 Handle(OpenGl_Context) myGlCtx; //!< handle to current OpenGL context
123 Handle(OpenGl_VertexBuffer) myVbo; //!< edited VBO
124 Standard_Integer myElemFrom; //!< element in VBO to upload from
125 Standard_Integer myElemsNb; //!< current element in temporary buffer
126 NCollection_Array1<theVec_t> myTmpBuffer; //!< temporary array
127
128};
129
130#endif // _OpenGl_VertexBufferEditor_H__