| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | */ |
|---|
| 13 | |
|---|
| 14 | #ifndef OSG_BUFFEROBJECT |
|---|
| 15 | #define OSG_BUFFEROBJECT 1 |
|---|
| 16 | |
|---|
| 17 | #include <osg/GL> |
|---|
| 18 | #include <osg/Object> |
|---|
| 19 | #include <osg/buffered_value> |
|---|
| 20 | |
|---|
| 21 | #ifndef GL_ARB_vertex_buffer_object |
|---|
| 22 | |
|---|
| 23 | #define GL_ARB_vertex_buffer_object |
|---|
| 24 | |
|---|
| 25 | // for compatibility with gl.h headers that don't support VBO, |
|---|
| 26 | #if defined(_WIN64) |
|---|
| 27 | typedef __int64 GLintptrARB; |
|---|
| 28 | typedef __int64 GLsizeiptrARB; |
|---|
| 29 | #elif defined(__ia64__) || defined(__x86_64__) |
|---|
| 30 | typedef long int GLintptrARB; |
|---|
| 31 | typedef long int GLsizeiptrARB; |
|---|
| 32 | #else |
|---|
| 33 | typedef int GLintptrARB; |
|---|
| 34 | typedef int GLsizeiptrARB; |
|---|
| 35 | #endif |
|---|
| 36 | |
|---|
| 37 | #define GL_ARRAY_BUFFER_ARB 0x8892 |
|---|
| 38 | #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 |
|---|
| 39 | #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 |
|---|
| 40 | #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 |
|---|
| 41 | #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 |
|---|
| 42 | #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 |
|---|
| 43 | #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 |
|---|
| 44 | #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 |
|---|
| 45 | #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A |
|---|
| 46 | #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B |
|---|
| 47 | #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C |
|---|
| 48 | #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D |
|---|
| 49 | #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E |
|---|
| 50 | #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F |
|---|
| 51 | #define GL_STREAM_DRAW_ARB 0x88E0 |
|---|
| 52 | #define GL_STREAM_READ_ARB 0x88E1 |
|---|
| 53 | #define GL_STREAM_COPY_ARB 0x88E2 |
|---|
| 54 | #define GL_STATIC_DRAW_ARB 0x88E4 |
|---|
| 55 | #define GL_STATIC_READ_ARB 0x88E5 |
|---|
| 56 | #define GL_STATIC_COPY_ARB 0x88E6 |
|---|
| 57 | #define GL_DYNAMIC_DRAW_ARB 0x88E8 |
|---|
| 58 | #define GL_DYNAMIC_READ_ARB 0x88E9 |
|---|
| 59 | #define GL_DYNAMIC_COPY_ARB 0x88EA |
|---|
| 60 | #define GL_READ_ONLY_ARB 0x88B8 |
|---|
| 61 | #define GL_WRITE_ONLY_ARB 0x88B9 |
|---|
| 62 | #define GL_READ_WRITE_ARB 0x88BA |
|---|
| 63 | #define GL_BUFFER_SIZE_ARB 0x8764 |
|---|
| 64 | #define GL_BUFFER_USAGE_ARB 0x8765 |
|---|
| 65 | #define GL_BUFFER_ACCESS_ARB 0x88BB |
|---|
| 66 | #define GL_BUFFER_MAPPED_ARB 0x88BC |
|---|
| 67 | #define GL_BUFFER_MAP_POINTER_ARB 0x88BD |
|---|
| 68 | |
|---|
| 69 | #endif |
|---|
| 70 | |
|---|
| 71 | #ifndef GL_VERSION_1_5 |
|---|
| 72 | #define GL_STREAM_DRAW 0x88E0 |
|---|
| 73 | #define GL_STREAM_READ 0x88E1 |
|---|
| 74 | #define GL_STREAM_COPY 0x88E2 |
|---|
| 75 | #define GL_STATIC_DRAW 0x88E4 |
|---|
| 76 | #define GL_STATIC_READ 0x88E5 |
|---|
| 77 | #define GL_STATIC_COPY 0x88E6 |
|---|
| 78 | #define GL_DYNAMIC_DRAW 0x88E8 |
|---|
| 79 | #define GL_DYNAMIC_READ 0x88E9 |
|---|
| 80 | #define GL_DYNAMIC_COPY 0x88EA |
|---|
| 81 | #endif |
|---|
| 82 | |
|---|
| 83 | #ifndef GL_VERSION_2_1 |
|---|
| 84 | #define GL_PIXEL_PACK_BUFFER 0x88EB |
|---|
| 85 | #define GL_PIXEL_UNPACK_BUFFER 0x88EC |
|---|
| 86 | #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED |
|---|
| 87 | #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF |
|---|
| 88 | #endif |
|---|
| 89 | |
|---|
| 90 | |
|---|
| 91 | #ifndef GL_ARB_pixel_buffer_object |
|---|
| 92 | #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB |
|---|
| 93 | #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC |
|---|
| 94 | #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED |
|---|
| 95 | #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF |
|---|
| 96 | #endif |
|---|
| 97 | |
|---|
| 98 | namespace osg |
|---|
| 99 | { |
|---|
| 100 | |
|---|
| 101 | class State; |
|---|
| 102 | |
|---|
| 103 | class OSG_EXPORT BufferObject : public Object |
|---|
| 104 | { |
|---|
| 105 | public: |
|---|
| 106 | |
|---|
| 107 | BufferObject(); |
|---|
| 108 | |
|---|
| 109 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 110 | BufferObject(const BufferObject& bo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 111 | |
|---|
| 112 | virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferObject*>(obj)!=NULL; } |
|---|
| 113 | virtual const char* libraryName() const { return "osg"; } |
|---|
| 114 | virtual const char* className() const { return "BufferObject"; } |
|---|
| 115 | |
|---|
| 116 | /** Set what type of usage the buffer object will have. Options are: |
|---|
| 117 | * GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, |
|---|
| 118 | * GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, |
|---|
| 119 | * GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY. |
|---|
| 120 | */ |
|---|
| 121 | void setUsage(GLenum usage) { _usage = usage; } |
|---|
| 122 | |
|---|
| 123 | /** Get the type of usage the buffer object has been set up for.*/ |
|---|
| 124 | GLenum getUsage() const { return _usage; } |
|---|
| 125 | |
|---|
| 126 | struct BufferEntry |
|---|
| 127 | { |
|---|
| 128 | BufferEntry(): dataSize(0),offset(0) {} |
|---|
| 129 | BufferEntry(const BufferEntry& be): modifiedCount(be.modifiedCount),dataSize(be.dataSize),offset(be.offset) {} |
|---|
| 130 | |
|---|
| 131 | BufferEntry& operator = (const BufferEntry& be) { modifiedCount=be.modifiedCount; dataSize=be.dataSize; offset=be.offset; return *this; } |
|---|
| 132 | |
|---|
| 133 | mutable buffered_value<unsigned int> modifiedCount; |
|---|
| 134 | mutable unsigned int dataSize; |
|---|
| 135 | mutable unsigned int offset; |
|---|
| 136 | }; |
|---|
| 137 | |
|---|
| 138 | inline bool isBufferObjectSupported(unsigned int contextID) const { return getExtensions(contextID,true)->isBufferObjectSupported(); } |
|---|
| 139 | inline bool isPBOSupported(unsigned int contextID) const { return getExtensions(contextID,true)->isPBOSupported(); } |
|---|
| 140 | |
|---|
| 141 | inline GLuint& buffer(unsigned int contextID) const { return _bufferObjectList[contextID]; } |
|---|
| 142 | |
|---|
| 143 | inline void bindBuffer(unsigned int contextID) const |
|---|
| 144 | { |
|---|
| 145 | Extensions* extensions = getExtensions(contextID,true); |
|---|
| 146 | extensions->glBindBuffer(_target,_bufferObjectList[contextID]); |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | virtual void unbindBuffer(unsigned int contextID) const |
|---|
| 150 | { |
|---|
| 151 | Extensions* extensions = getExtensions(contextID,true); |
|---|
| 152 | extensions->glBindBuffer(_target,0); |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | inline void dirty() { _compiledList.setAllElementsTo(0); } |
|---|
| 156 | |
|---|
| 157 | bool isDirty(unsigned int contextID) const { return _compiledList[contextID]==0; } |
|---|
| 158 | |
|---|
| 159 | virtual void compileBuffer(State& state) const = 0; |
|---|
| 160 | |
|---|
| 161 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 162 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 163 | |
|---|
| 164 | /** If State is non-zero, this function releases OpenGL objects for |
|---|
| 165 | * the specified graphics context. Otherwise, releases OpenGL objects |
|---|
| 166 | * for all graphics contexts. */ |
|---|
| 167 | void releaseGLObjects(State* state=0) const; |
|---|
| 168 | |
|---|
| 169 | |
|---|
| 170 | /** Use deleteVertexBufferObject instead of glDeleteBuffers to allow |
|---|
| 171 | * OpenGL buffer objects to be cached until they can be deleted |
|---|
| 172 | * by the OpenGL context in which they were created, specified |
|---|
| 173 | * by contextID.*/ |
|---|
| 174 | static void deleteBufferObject(unsigned int contextID,GLuint globj); |
|---|
| 175 | |
|---|
| 176 | /** flush all the cached display list which need to be deleted |
|---|
| 177 | * in the OpenGL context related to contextID.*/ |
|---|
| 178 | static void flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime); |
|---|
| 179 | |
|---|
| 180 | /** dicard all the cached display list which need to be deleted |
|---|
| 181 | * in the OpenGL context related to contextID. |
|---|
| 182 | * Note, unlike flush no OpenGL calls are made, instead the handles are all removed. |
|---|
| 183 | * this call is useful for when an OpenGL context has been destroyed. */ |
|---|
| 184 | static void discardDeletedBufferObjects(unsigned int contextID); |
|---|
| 185 | |
|---|
| 186 | /** Extensions class which encapsulates the querying of extensions and |
|---|
| 187 | * associated function pointers, and provide convenience wrappers to |
|---|
| 188 | * check for the extensions or use the associated functions.*/ |
|---|
| 189 | class OSG_EXPORT Extensions : public osg::Referenced |
|---|
| 190 | { |
|---|
| 191 | public: |
|---|
| 192 | Extensions(unsigned int contextID); |
|---|
| 193 | |
|---|
| 194 | Extensions(const Extensions& rhs); |
|---|
| 195 | |
|---|
| 196 | void lowestCommonDenominator(const Extensions& rhs); |
|---|
| 197 | |
|---|
| 198 | void setupGLExtensions(unsigned int contextID); |
|---|
| 199 | |
|---|
| 200 | bool isBufferObjectSupported() const { return _glGenBuffers!=0; } |
|---|
| 201 | bool isPBOSupported() const { return _isPBOSupported; } |
|---|
| 202 | |
|---|
| 203 | void glGenBuffers (GLsizei n, GLuint *buffers) const; |
|---|
| 204 | void glBindBuffer (GLenum target, GLuint buffer) const; |
|---|
| 205 | void glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const; |
|---|
| 206 | void glBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const; |
|---|
| 207 | void glDeleteBuffers (GLsizei n, const GLuint *buffers) const; |
|---|
| 208 | GLboolean glIsBuffer (GLuint buffer) const; |
|---|
| 209 | void glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const; |
|---|
| 210 | GLvoid* glMapBuffer (GLenum target, GLenum access) const; |
|---|
| 211 | GLboolean glUnmapBuffer (GLenum target) const; |
|---|
| 212 | void glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const; |
|---|
| 213 | void glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const; |
|---|
| 214 | |
|---|
| 215 | protected: |
|---|
| 216 | |
|---|
| 217 | typedef void (APIENTRY * GenBuffersProc) (GLsizei n, GLuint *buffers); |
|---|
| 218 | typedef void (APIENTRY * BindBufferProc) (GLenum target, GLuint buffer); |
|---|
| 219 | typedef void (APIENTRY * BufferDataProc) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); |
|---|
| 220 | typedef void (APIENTRY * BufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); |
|---|
| 221 | typedef void (APIENTRY * DeleteBuffersProc) (GLsizei n, const GLuint *buffers); |
|---|
| 222 | typedef GLboolean (APIENTRY * IsBufferProc) (GLuint buffer); |
|---|
| 223 | typedef void (APIENTRY * GetBufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); |
|---|
| 224 | typedef GLvoid* (APIENTRY * MapBufferProc) (GLenum target, GLenum access); |
|---|
| 225 | typedef GLboolean (APIENTRY * UnmapBufferProc) (GLenum target); |
|---|
| 226 | typedef void (APIENTRY * GetBufferParameterivProc) (GLenum target, GLenum pname, GLint *params); |
|---|
| 227 | typedef void (APIENTRY * GetBufferPointervProc) (GLenum target, GLenum pname, GLvoid* *params); |
|---|
| 228 | |
|---|
| 229 | GenBuffersProc _glGenBuffers; |
|---|
| 230 | BindBufferProc _glBindBuffer; |
|---|
| 231 | BufferDataProc _glBufferData; |
|---|
| 232 | BufferSubDataProc _glBufferSubData; |
|---|
| 233 | DeleteBuffersProc _glDeleteBuffers; |
|---|
| 234 | IsBufferProc _glIsBuffer; |
|---|
| 235 | GetBufferSubDataProc _glGetBufferSubData; |
|---|
| 236 | MapBufferProc _glMapBuffer; |
|---|
| 237 | UnmapBufferProc _glUnmapBuffer; |
|---|
| 238 | GetBufferParameterivProc _glGetBufferParameteriv; |
|---|
| 239 | GetBufferPointervProc _glGetBufferPointerv; |
|---|
| 240 | |
|---|
| 241 | bool _isPBOSupported; |
|---|
| 242 | }; |
|---|
| 243 | |
|---|
| 244 | /** Function to call to get the extension of a specified context. |
|---|
| 245 | * If the Extension object for that context has not yet been created |
|---|
| 246 | * and the 'createIfNotInitalized' flag been set to false then returns NULL. |
|---|
| 247 | * If 'createIfNotInitalized' is true then the Extensions object is |
|---|
| 248 | * automatically created. However, in this case the extension object is |
|---|
| 249 | * only created with the graphics context associated with ContextID..*/ |
|---|
| 250 | static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized); |
|---|
| 251 | |
|---|
| 252 | /** setExtensions allows users to override the extensions across graphics contexts. |
|---|
| 253 | * typically used when you have different extensions supported across graphics pipes |
|---|
| 254 | * but need to ensure that they all use the same low common denominator extensions.*/ |
|---|
| 255 | static void setExtensions(unsigned int contextID,Extensions* extensions); |
|---|
| 256 | |
|---|
| 257 | protected: |
|---|
| 258 | |
|---|
| 259 | virtual ~BufferObject(); |
|---|
| 260 | |
|---|
| 261 | typedef osg::buffered_value<GLuint> GLObjectList; |
|---|
| 262 | typedef osg::buffered_value<unsigned int> CompiledList; |
|---|
| 263 | |
|---|
| 264 | mutable GLObjectList _bufferObjectList; |
|---|
| 265 | mutable CompiledList _compiledList; |
|---|
| 266 | |
|---|
| 267 | GLenum _target; |
|---|
| 268 | GLenum _usage; |
|---|
| 269 | mutable unsigned int _totalSize; |
|---|
| 270 | }; |
|---|
| 271 | |
|---|
| 272 | class Array; |
|---|
| 273 | class OSG_EXPORT VertexBufferObject : public BufferObject |
|---|
| 274 | { |
|---|
| 275 | public: |
|---|
| 276 | |
|---|
| 277 | VertexBufferObject(); |
|---|
| 278 | |
|---|
| 279 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 280 | VertexBufferObject(const VertexBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 281 | |
|---|
| 282 | META_Object(osg,VertexBufferObject); |
|---|
| 283 | |
|---|
| 284 | typedef std::pair< BufferEntry, Array* > BufferEntryArrayPair; |
|---|
| 285 | typedef std::vector< BufferEntryArrayPair > BufferEntryArrayPairs; |
|---|
| 286 | |
|---|
| 287 | unsigned int addArray(osg::Array* array); |
|---|
| 288 | void removeArray(osg::Array* array); |
|---|
| 289 | |
|---|
| 290 | void setArray(unsigned int i, Array* array); |
|---|
| 291 | Array* getArray(unsigned int i) { return _bufferEntryArrayPairs[i].second; } |
|---|
| 292 | const Array* getArray(unsigned int i) const { return _bufferEntryArrayPairs[i].second; } |
|---|
| 293 | |
|---|
| 294 | const GLvoid* getOffset(unsigned int i) const { return (const GLvoid*)(((char *)0)+(_bufferEntryArrayPairs[i].first.offset)); } |
|---|
| 295 | |
|---|
| 296 | virtual void compileBuffer(State& state) const; |
|---|
| 297 | |
|---|
| 298 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 299 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 300 | |
|---|
| 301 | protected: |
|---|
| 302 | |
|---|
| 303 | virtual ~VertexBufferObject(); |
|---|
| 304 | |
|---|
| 305 | BufferEntryArrayPairs _bufferEntryArrayPairs; |
|---|
| 306 | }; |
|---|
| 307 | |
|---|
| 308 | class DrawElements; |
|---|
| 309 | class OSG_EXPORT ElementBufferObject : public BufferObject |
|---|
| 310 | { |
|---|
| 311 | public: |
|---|
| 312 | |
|---|
| 313 | ElementBufferObject(); |
|---|
| 314 | |
|---|
| 315 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 316 | ElementBufferObject(const ElementBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 317 | |
|---|
| 318 | META_Object(osg,ElementBufferObject); |
|---|
| 319 | |
|---|
| 320 | typedef std::pair< BufferEntry, DrawElements* > BufferEntryDrawElementsPair; |
|---|
| 321 | typedef std::vector< BufferEntryDrawElementsPair > BufferEntryDrawElementsPairs; |
|---|
| 322 | |
|---|
| 323 | unsigned int addDrawElements(osg::DrawElements* PrimitiveSet); |
|---|
| 324 | void removeDrawElements(osg::DrawElements* PrimitiveSet); |
|---|
| 325 | |
|---|
| 326 | void setDrawElements(unsigned int i, DrawElements* PrimitiveSet); |
|---|
| 327 | DrawElements* getDrawElements(unsigned int i) { return _bufferEntryDrawElementsPairs[i].second; } |
|---|
| 328 | const DrawElements* getDrawElements(unsigned int i) const { return _bufferEntryDrawElementsPairs[i].second; } |
|---|
| 329 | |
|---|
| 330 | const GLvoid* getOffset(unsigned int i) const { return (const GLvoid*)(((char *)0)+(_bufferEntryDrawElementsPairs[i].first.offset)); } |
|---|
| 331 | |
|---|
| 332 | virtual void compileBuffer(State& state) const; |
|---|
| 333 | |
|---|
| 334 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 335 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 336 | |
|---|
| 337 | protected: |
|---|
| 338 | |
|---|
| 339 | virtual ~ElementBufferObject(); |
|---|
| 340 | |
|---|
| 341 | BufferEntryDrawElementsPairs _bufferEntryDrawElementsPairs; |
|---|
| 342 | }; |
|---|
| 343 | |
|---|
| 344 | class Image; |
|---|
| 345 | class OSG_EXPORT PixelBufferObject : public BufferObject |
|---|
| 346 | { |
|---|
| 347 | public: |
|---|
| 348 | |
|---|
| 349 | PixelBufferObject(osg::Image* image=0); |
|---|
| 350 | |
|---|
| 351 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 352 | PixelBufferObject(const PixelBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 353 | |
|---|
| 354 | META_Object(osg,PixelBufferObject); |
|---|
| 355 | |
|---|
| 356 | typedef std::pair< BufferEntry, Image* > BufferEntryImagePair; |
|---|
| 357 | |
|---|
| 358 | void setImage(osg::Image* image); |
|---|
| 359 | |
|---|
| 360 | Image* getImage() { return _bufferEntryImagePair.second; } |
|---|
| 361 | const Image* getImage() const { return _bufferEntryImagePair.second; } |
|---|
| 362 | |
|---|
| 363 | unsigned int offset() const { return _bufferEntryImagePair.first.offset; } |
|---|
| 364 | |
|---|
| 365 | virtual void compileBuffer(State& state) const; |
|---|
| 366 | |
|---|
| 367 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 368 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 369 | |
|---|
| 370 | protected: |
|---|
| 371 | |
|---|
| 372 | virtual ~PixelBufferObject(); |
|---|
| 373 | |
|---|
| 374 | BufferEntryImagePair _bufferEntryImagePair; |
|---|
| 375 | }; |
|---|
| 376 | |
|---|
| 377 | /** |
|---|
| 378 | * This object represent a general class of pixel buffer objects, |
|---|
| 379 | * which are capable of allocating buffer object (memory) |
|---|
| 380 | * on the GPU. The memory can then be used either for CPU-GPU |
|---|
| 381 | * pixel transfer or directly for GPU-GPU transfer, without CPU intervention. |
|---|
| 382 | **/ |
|---|
| 383 | class OSG_EXPORT PixelDataBufferObject : public BufferObject |
|---|
| 384 | { |
|---|
| 385 | public: |
|---|
| 386 | PixelDataBufferObject(); |
|---|
| 387 | PixelDataBufferObject(const PixelDataBufferObject& pbo, const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 388 | |
|---|
| 389 | META_Object(osg, PixelDataBufferObject); |
|---|
| 390 | |
|---|
| 391 | //! Set new size of the buffer object. This will reallocate the memory on the next compile |
|---|
| 392 | inline void setDataSize(unsigned int size) { _bufferData.dataSize = size; dirty(); } |
|---|
| 393 | |
|---|
| 394 | //! Get data size of the used buffer |
|---|
| 395 | inline unsigned int getDataSize() { return _bufferData.dataSize; } |
|---|
| 396 | |
|---|
| 397 | //! Compile the buffer (reallocate the memory if buffer is dirty) |
|---|
| 398 | virtual void compileBuffer(State& state) const; |
|---|
| 399 | |
|---|
| 400 | //! Bind the buffer in read mode, which means that data can be downloaded from the buffer (note: GL_PIXEL_UNPACK_BUFFER_ARB) |
|---|
| 401 | virtual void bindBufferInReadMode(State& state); |
|---|
| 402 | |
|---|
| 403 | //! Bind the buffer in write mode, which means following OpenGL instructions will write data into the buffer (note: GL_PIXEL_PACK_BUFFER_ARB) |
|---|
| 404 | virtual void bindBufferInWriteMode(State& state); |
|---|
| 405 | |
|---|
| 406 | //! Unbind the buffer |
|---|
| 407 | virtual void unbindBuffer(unsigned int contextID) const; |
|---|
| 408 | |
|---|
| 409 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 410 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 411 | |
|---|
| 412 | enum Mode |
|---|
| 413 | { |
|---|
| 414 | //! A normal mode of this data buffer |
|---|
| 415 | NONE = 0, |
|---|
| 416 | |
|---|
| 417 | //! Buffer is in read mode (@see bindBufferInReadMode) |
|---|
| 418 | READ = 1, |
|---|
| 419 | |
|---|
| 420 | //! Buffer is in write mode (@see bindBufferInWriteMode) |
|---|
| 421 | WRITE = 2 |
|---|
| 422 | }; |
|---|
| 423 | |
|---|
| 424 | Mode getMode(unsigned int contextID) const { return (Mode)_mode[contextID]; } |
|---|
| 425 | |
|---|
| 426 | protected: |
|---|
| 427 | |
|---|
| 428 | virtual ~PixelDataBufferObject(); |
|---|
| 429 | |
|---|
| 430 | BufferEntry _bufferData; |
|---|
| 431 | |
|---|
| 432 | typedef osg::buffered_value<unsigned int> ModeList; |
|---|
| 433 | |
|---|
| 434 | mutable ModeList _mode; |
|---|
| 435 | |
|---|
| 436 | }; |
|---|
| 437 | |
|---|
| 438 | |
|---|
| 439 | } |
|---|
| 440 | |
|---|
| 441 | #endif |
|---|