0025703: Visualization - Decrease number of samplers used in ray-tracing mode
[occt.git] / src / OpenGl / OpenGl_VertexBufferEditor.hxx
CommitLineData
5e27df78 1// Created by: Kirill GAVRILOV
d5f74e42 2// Copyright (c) 2013-2014 OPEN CASCADE SAS
5e27df78 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
5e27df78 5//
d5f74e42 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
973c2be1 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.
5e27df78 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
5e27df78 14
15#ifndef _OpenGl_VertexBufferEditor_H__
16#define _OpenGl_VertexBufferEditor_H__
17
18#include <OpenGl_VertexBuffer.hxx>
19#include <OpenGl_Context.hxx>
20
21#include <NCollection_Array1.hxx>
22
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.
28//!
29//! You should use NCollection_Vec2/NCollection_Vec3/NCollection_Vec4 with appropriate length
30//! to instantiate this template and access elements in VBO.
31//!
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.
35template<typename theVec_t>
36class OpenGl_VertexBufferEditor
37{
38
39public:
40
41 //! Creates empty editor
42 //! theTmpBufferLength - temporary buffer length
43 OpenGl_VertexBufferEditor (const Standard_Integer theTmpBufferLength = 0)
44 : myElemFrom (0),
45 myElemsNb (0),
46 myTmpBuffer (0, theTmpBufferLength > 0 ? (theTmpBufferLength - 1) : 2047) {}
47
48 //! Creates empty editor
49 //! theTmpBuffer - pointer to temporary buffer
50 //! theTmpBufferLength - temporary buffer length
51 OpenGl_VertexBufferEditor (theVec_t* theTmpBuffer,
52 const Standard_Integer theTmpBufferLength)
53 : myElemFrom (0),
54 myElemsNb (0),
55 myTmpBuffer (theTmpBuffer[0], 0, theTmpBufferLength - 1) {}
56
57 //! Initialize editor for specified VBO.
58 //! theGlCtx - bound OpenGL context to edit VBO
59 //! theVbo - VBO to edit
60 Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
61 const Handle(OpenGl_VertexBuffer)& theVbo)
62 {
63 myGlCtx = theGlCtx;
64 myVbo = theVbo;
65 if (myGlCtx.IsNull() || myVbo.IsNull() || !myVbo->IsValid() || myVbo->GetComponentsNb() != GLuint (theVec_t::Length()))
66 {
67 return Standard_False;
68 }
69
70 myElemFrom = myElemsNb = 0;
71 return Standard_True;
72 }
73
74 //! Modify current element in VBO.
75 theVec_t& Value()
76 {
a174a3c5 77 return myTmpBuffer.ChangeValue (myElemsNb);
5e27df78 78 }
79
80 //! Move to the next position in VBO.
81 Standard_Boolean Next()
82 {
a174a3c5 83 if (++myElemsNb > myTmpBuffer.Upper())
84 {
85 return Flush();
86 }
87 return Standard_True;
5e27df78 88 }
89
90 //! Push current data from local buffer to VBO.
91 Standard_Boolean Flush()
92 {
a174a3c5 93 if (myElemsNb <= 0)
94 {
5e27df78 95 return Standard_True;
a174a3c5 96 }
97
98 if (myVbo.IsNull()
99 || !myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
100 {
101 // should never happens
102 return Standard_False;
103 }
104 myElemFrom += myElemsNb;
105 myElemsNb = 0;
106
107 return Standard_True;
5e27df78 108 }
109
99d99a6d 110 //! @return assigned VBO
111 inline const Handle(OpenGl_VertexBuffer)& GetVBO() const
112 {
113 return myVbo;
114 }
115
5e27df78 116private:
117
118 Handle(OpenGl_Context) myGlCtx; //!< handle to current OpenGL context
119 Handle(OpenGl_VertexBuffer) myVbo; //!< edited VBO
120 Standard_Integer myElemFrom; //!< element in VBO to upload from
121 Standard_Integer myElemsNb; //!< current element in temporary buffer
122 NCollection_Array1<theVec_t> myTmpBuffer; //!< temporary array
123
124};
125
126#endif // _OpenGl_VertexBufferEditor_H__