1 // Created by: Kirill GAVRILOV 2 // Copyright (c) 2013-2014 OPEN CASCADE SAS 3 // 4 // This file is part of Open CASCADE Technology software library. 5 // 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. 11 // 12 // Alternatively, this file may be used under the terms of Open CASCADE 13 // commercial license or contractual agreement. 14 15 #ifndef _OpenGl_Buffer_H__ 16 #define _OpenGl_Buffer_H__ 17 18 #include <OpenGl_Resource.hxx> 19 #include <TCollection_AsciiString.hxx> 20 21 //! Buffer Object - is a general storage object for arbitrary data (see sub-classes). 22 class OpenGl_Buffer : public OpenGl_Resource 23 { 24 DEFINE_STANDARD_RTTIEXT(OpenGl_Buffer, OpenGl_Resource) 25 public: 26 27 //! Helpful constants 28 static const unsigned int NO_BUFFER = 0; 29 30 //! Format VBO target enumeration value. 31 Standard_EXPORT static TCollection_AsciiString FormatTarget (unsigned int theTarget); 32 33 public: 34 35 //! Create uninitialized buffer. 36 Standard_EXPORT OpenGl_Buffer(); 37 38 //! Destroy object. 39 Standard_EXPORT virtual ~OpenGl_Buffer(); 40 41 //! Return buffer target. 42 virtual unsigned int GetTarget() const = 0; 43 44 //! Return TRUE if this is a virtual (for backward compatibility) VBO object. IsVirtual() const45 virtual bool IsVirtual() const { return false; } 46 47 //! @return true if current object was initialized IsValid() const48 bool IsValid() const { return myBufferId != NO_BUFFER; } 49 50 //! @return the number of components per generic vertex attribute. GetComponentsNb() const51 unsigned int GetComponentsNb() const { return myComponentsNb; } 52 53 //! @return number of vertex attributes / number of vertices specified within ::Init() GetElemsNb() const54 Standard_Integer GetElemsNb() const { return myElemsNb; } 55 56 //! Overrides the number of vertex attributes / number of vertexes. 57 //! It is up to user specifying this number correct (e.g. below initial value)! SetElemsNb(Standard_Integer theNbElems)58 void SetElemsNb (Standard_Integer theNbElems) { myElemsNb = theNbElems; } 59 60 //! @return data type of each component in the array. GetDataType() const61 unsigned int GetDataType() const { return myDataType; } 62 63 //! @return offset to data, NULL by default GetDataOffset() const64 Standard_Byte* GetDataOffset() const { return myOffset; } 65 66 //! Creates buffer object name (id) if not yet generated. 67 //! Data should be initialized by another method. 68 Standard_EXPORT virtual bool Create (const Handle(OpenGl_Context)& theGlCtx); 69 70 //! Destroy object - will release GPU memory if any. 71 Standard_EXPORT virtual void Release (OpenGl_Context* theGlCtx) Standard_OVERRIDE; 72 73 //! Bind this buffer object. 74 Standard_EXPORT virtual void Bind (const Handle(OpenGl_Context)& theGlCtx) const; 75 76 //! Unbind this buffer object. 77 Standard_EXPORT virtual void Unbind (const Handle(OpenGl_Context)& theGlCtx) const; 78 79 //! Notice that buffer object will be unbound after this call. 80 //! @param theComponentsNb [in] specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; 81 //! @param theElemsNb [in] elements count; 82 //! @param theData [in] pointer to float data (vertices/normals etc.). 83 Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx, 84 const unsigned int theComponentsNb, 85 const Standard_Integer theElemsNb, 86 const float* theData); 87 88 //! Notice that buffer object will be unbound after this call. 89 //! @param theComponentsNb [in] specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; 90 //! @param theElemsNb [in] elements count; 91 //! @param theData [in] pointer to unsigned int data (indices etc.). 92 Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx, 93 const unsigned int theComponentsNb, 94 const Standard_Integer theElemsNb, 95 const unsigned int* theData); 96 97 //! Notice that buffer object will be unbound after this call. 98 //! @param theComponentsNb [in] specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; 99 //! @param theElemsNb [in] elements count; 100 //! @param theData [in] pointer to unsigned short data (indices etc.). 101 Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx, 102 const unsigned int theComponentsNb, 103 const Standard_Integer theElemsNb, 104 const unsigned short* theData); 105 106 //! Notice that buffer object will be unbound after this call. 107 //! @param theComponentsNb [in] specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4; 108 //! @param theElemsNb [in] elements count; 109 //! @param theData [in] pointer to Standard_Byte data (indices/colors etc.). 110 Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx, 111 const unsigned int theComponentsNb, 112 const Standard_Integer theElemsNb, 113 const Standard_Byte* theData); 114 115 //! Notice that buffer object will be unbound after this call. 116 //! Function replaces portion of data within this buffer object using glBufferSubData(). 117 //! The buffer object should be initialized before call. 118 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 119 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 120 //! @param theData [in] pointer to float data. 121 Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx, 122 const Standard_Integer theElemFrom, 123 const Standard_Integer theElemsNb, 124 const float* theData); 125 126 //! Read back buffer sub-range. 127 //! Notice that buffer object will be unbound after this call. 128 //! Function reads portion of data from this buffer object using glGetBufferSubData(). 129 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 130 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 131 //! @param theData [out] destination pointer to float data. 132 Standard_EXPORT bool GetSubData (const Handle(OpenGl_Context)& theGlCtx, 133 const Standard_Integer theElemFrom, 134 const Standard_Integer theElemsNb, 135 float* theData); 136 137 //! Notice that buffer object will be unbound after this call. 138 //! Function replaces portion of data within this buffer object using glBufferSubData(). 139 //! The buffer object should be initialized before call. 140 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 141 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 142 //! @param theData [in] pointer to unsigned int data. 143 Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx, 144 const Standard_Integer theElemFrom, 145 const Standard_Integer theElemsNb, 146 const unsigned int* theData); 147 148 //! Read back buffer sub-range. 149 //! Notice that buffer object will be unbound after this call. 150 //! Function reads portion of data from this buffer object using glGetBufferSubData(). 151 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 152 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 153 //! @param theData [out] destination pointer to unsigned int data. 154 Standard_EXPORT bool GetSubData (const Handle(OpenGl_Context)& theGlCtx, 155 const Standard_Integer theElemFrom, 156 const Standard_Integer theElemsNb, 157 unsigned int* theData); 158 159 //! Notice that buffer object will be unbound after this call. 160 //! Function replaces portion of data within this buffer object using glBufferSubData(). 161 //! The buffer object should be initialized before call. 162 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 163 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 164 //! @param theData [in] pointer to unsigned short data. 165 Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx, 166 const Standard_Integer theElemFrom, 167 const Standard_Integer theElemsNb, 168 const unsigned short* theData); 169 170 //! Read back buffer sub-range. 171 //! Notice that buffer object will be unbound after this call. 172 //! Function reads portion of data from this buffer object using glGetBufferSubData(). 173 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 174 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 175 //! @param theData [out] destination pointer to unsigned short data. 176 Standard_EXPORT bool GetSubData (const Handle(OpenGl_Context)& theGlCtx, 177 const Standard_Integer theElemFrom, 178 const Standard_Integer theElemsNb, 179 unsigned short* theData); 180 181 //! Notice that buffer object will be unbound after this call. 182 //! Function replaces portion of data within this buffer object using glBufferSubData(). 183 //! The buffer object should be initialized before call. 184 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 185 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 186 //! @param theData [in] pointer to Standard_Byte data. 187 Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx, 188 const Standard_Integer theElemFrom, 189 const Standard_Integer theElemsNb, 190 const Standard_Byte* theData); 191 192 //! Read back buffer sub-range. 193 //! Notice that buffer object will be unbound after this call. 194 //! Function reads portion of data from this buffer object using glGetBufferSubData(). 195 //! @param theElemFrom [in] element id from which replace buffer data (>=0); 196 //! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb()); 197 //! @param theData [out] destination pointer to Standard_Byte data. 198 Standard_EXPORT bool GetSubData (const Handle(OpenGl_Context)& theGlCtx, 199 const Standard_Integer theElemFrom, 200 const Standard_Integer theElemsNb, 201 Standard_Byte* theData); 202 203 public: //! @name advanced methods 204 205 //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules. EstimatedDataSize() const206 virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE 207 { 208 return IsValid() 209 ? sizeOfGlType (myDataType) * myComponentsNb * myElemsNb 210 : 0; 211 } 212 213 //! @return size of specified GL type 214 Standard_EXPORT static size_t sizeOfGlType (unsigned int theType); 215 216 //! Initialize buffer with new data. 217 Standard_EXPORT virtual bool init (const Handle(OpenGl_Context)& theGlCtx, 218 const unsigned int theComponentsNb, 219 const Standard_Integer theElemsNb, 220 const void* theData, 221 const unsigned int theDataType, 222 const Standard_Integer theStride); 223 224 //! Initialize buffer with new data. init(const Handle (OpenGl_Context)& theGlCtx,const unsigned int theComponentsNb,const Standard_Integer theElemsNb,const void * theData,const unsigned int theDataType)225 bool init (const Handle(OpenGl_Context)& theGlCtx, 226 const unsigned int theComponentsNb, 227 const Standard_Integer theElemsNb, 228 const void* theData, 229 const unsigned int theDataType) 230 { 231 return init (theGlCtx, theComponentsNb, theElemsNb, theData, theDataType, 232 Standard_Integer(theComponentsNb) * Standard_Integer(sizeOfGlType (theDataType))); 233 } 234 235 //! Update part of the buffer with new data. 236 Standard_EXPORT virtual bool subData (const Handle(OpenGl_Context)& theGlCtx, 237 const Standard_Integer theElemFrom, 238 const Standard_Integer theElemsNb, 239 const void* theData, 240 const unsigned int theDataType); 241 242 //! Read back buffer sub-range. 243 Standard_EXPORT virtual bool getSubData (const Handle(OpenGl_Context)& theGlCtx, 244 const Standard_Integer theElemFrom, 245 const Standard_Integer theElemsNb, 246 void* theData, 247 const unsigned int theDataType); 248 249 public: 250 251 //! Dumps the content of me into the stream 252 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE; 253 254 protected: 255 256 //! Binds a buffer object to an indexed buffer target. 257 //! Wrapper for glBindBufferBase(). 258 //! @param theGlCtx [in] active OpenGL context 259 //! @param theIndex [in] index to bind 260 Standard_EXPORT void BindBufferBase (const Handle(OpenGl_Context)& theGlCtx, 261 unsigned int theIndex); 262 263 //! Unbinds a buffer object from an indexed buffer target. 264 //! Wrapper for glBindBufferBase(). 265 //! @param theGlCtx [in] active OpenGL context 266 //! @param theIndex [in] index to bind 267 Standard_EXPORT void UnbindBufferBase (const Handle(OpenGl_Context)& theGlCtx, 268 unsigned int theIndex); 269 270 //! Binds a buffer object to an indexed buffer target with specified offset and size. 271 //! Wrapper for glBindBufferRange(). 272 //! @param theGlCtx [in] active OpenGL context 273 //! @param theIndex [in] index to bind (@sa GL_MAX_UNIFORM_BUFFER_BINDINGS in case of uniform buffer) 274 //! @param theOffset [in] offset within the buffer (@sa GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT in case of uniform buffer) 275 //! @param theSize [in] sub-section length starting from offset 276 Standard_EXPORT void BindBufferRange (const Handle(OpenGl_Context)& theGlCtx, 277 unsigned int theIndex, 278 const intptr_t theOffset, 279 const size_t theSize); 280 281 protected: 282 283 Standard_Byte* myOffset; //!< offset to data 284 unsigned int myBufferId; //!< VBO name (index) 285 unsigned int myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4 286 Standard_Integer myElemsNb; //!< Number of vertex attributes / number of vertices 287 unsigned int myDataType; //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.) 288 289 }; 290 291 DEFINE_STANDARD_HANDLE(OpenGl_Buffer, OpenGl_Resource) 292 293 #endif // _OpenGl_Buffer_H__ 294