| [5328] | 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| [3819] | 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 | |
|---|
| [4018] | 17 | #include <osg/GL> |
|---|
| 18 | #include <osg/Object> |
|---|
| [3819] | 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 | |
|---|
| [8336] | 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 | |
|---|
| [3828] | 91 | #ifndef GL_ARB_pixel_buffer_object |
|---|
| [8336] | 92 | #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB |
|---|
| 93 | #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC |
|---|
| [3828] | 94 | #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED |
|---|
| 95 | #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF |
|---|
| 96 | #endif |
|---|
| 97 | |
|---|
| [3819] | 98 | namespace osg |
|---|
| 99 | { |
|---|
| 100 | |
|---|
| [4018] | 101 | class State; |
|---|
| [10600] | 102 | class BufferData; |
|---|
| 103 | class BufferObject; |
|---|
| [4018] | 104 | |
|---|
| [10600] | 105 | class OSG_EXPORT GLBufferObject : public Referenced |
|---|
| [3819] | 106 | { |
|---|
| 107 | public: |
|---|
| 108 | |
|---|
| [10600] | 109 | GLBufferObject(unsigned int contextID, BufferObject* bufferObject=0); |
|---|
| [3819] | 110 | |
|---|
| [10600] | 111 | void setBufferObject(BufferObject* bufferObject); |
|---|
| 112 | BufferObject* getBufferObject() { return _bufferObject; } |
|---|
| [3819] | 113 | |
|---|
| 114 | struct BufferEntry |
|---|
| 115 | { |
|---|
| [10600] | 116 | BufferEntry(): modifiedCount(0),dataSize(0),offset(0),dataSource(0) {} |
|---|
| [3819] | 117 | |
|---|
| [10600] | 118 | BufferEntry(const BufferEntry& rhs): |
|---|
| 119 | modifiedCount(rhs.modifiedCount), |
|---|
| 120 | dataSize(rhs.dataSize), |
|---|
| 121 | offset(rhs.offset), |
|---|
| 122 | dataSource(rhs.dataSource) {} |
|---|
| 123 | |
|---|
| 124 | BufferEntry& operator = (const BufferEntry& rhs) |
|---|
| 125 | { |
|---|
| 126 | if (&rhs==this) return *this; |
|---|
| 127 | modifiedCount = rhs.modifiedCount; |
|---|
| 128 | dataSize = rhs.dataSize; |
|---|
| 129 | offset = rhs.offset; |
|---|
| 130 | dataSource = rhs.dataSource; |
|---|
| 131 | return *this; |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | unsigned int modifiedCount; |
|---|
| 135 | GLsizeiptrARB dataSize; |
|---|
| 136 | GLsizeiptrARB offset; |
|---|
| 137 | BufferData* dataSource; |
|---|
| [3819] | 138 | }; |
|---|
| 139 | |
|---|
| [10600] | 140 | inline unsigned int getContextID() const { return _contextID; } |
|---|
| [3819] | 141 | |
|---|
| [10600] | 142 | inline GLuint& getGLObjectID() { return _glObjectID; } |
|---|
| 143 | inline GLuint getGLObjectID() const { return _glObjectID; } |
|---|
| 144 | inline GLsizeiptrARB getOffset(unsigned int i) const { return _bufferEntries[i].offset; } |
|---|
| 145 | |
|---|
| 146 | inline void bindBuffer() const |
|---|
| [3819] | 147 | { |
|---|
| [10600] | 148 | _extensions->glBindBuffer(_target,_glObjectID); |
|---|
| [3819] | 149 | } |
|---|
| 150 | |
|---|
| [10600] | 151 | inline void unbindBuffer() const |
|---|
| [3819] | 152 | { |
|---|
| [10600] | 153 | _extensions->glBindBuffer(_target,0); |
|---|
| [3819] | 154 | } |
|---|
| 155 | |
|---|
| [10600] | 156 | inline bool isDirty() const { return _dirty; } |
|---|
| [6574] | 157 | |
|---|
| [10600] | 158 | void dirty() { _dirty = true; } |
|---|
| [6574] | 159 | |
|---|
| [10600] | 160 | void clear(); |
|---|
| [3819] | 161 | |
|---|
| [10600] | 162 | void compileBuffer(); |
|---|
| [6574] | 163 | |
|---|
| [10600] | 164 | void deleteGLObject(); |
|---|
| [3819] | 165 | |
|---|
| [10600] | 166 | void assign(BufferObject* bufferObject); |
|---|
| 167 | |
|---|
| 168 | bool isPBOSupported() const { return _extensions->isPBOSupported(); } |
|---|
| 169 | |
|---|
| 170 | static GLBufferObject* createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject); |
|---|
| 171 | |
|---|
| 172 | |
|---|
| [3819] | 173 | /** Use deleteVertexBufferObject instead of glDeleteBuffers to allow |
|---|
| 174 | * OpenGL buffer objects to be cached until they can be deleted |
|---|
| 175 | * by the OpenGL context in which they were created, specified |
|---|
| 176 | * by contextID.*/ |
|---|
| 177 | static void deleteBufferObject(unsigned int contextID,GLuint globj); |
|---|
| 178 | |
|---|
| 179 | /** flush all the cached display list which need to be deleted |
|---|
| 180 | * in the OpenGL context related to contextID.*/ |
|---|
| [6450] | 181 | static void flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime); |
|---|
| [3819] | 182 | |
|---|
| [7773] | 183 | /** dicard all the cached display list which need to be deleted |
|---|
| 184 | * in the OpenGL context related to contextID. |
|---|
| 185 | * Note, unlike flush no OpenGL calls are made, instead the handles are all removed. |
|---|
| 186 | * this call is useful for when an OpenGL context has been destroyed. */ |
|---|
| 187 | static void discardDeletedBufferObjects(unsigned int contextID); |
|---|
| 188 | |
|---|
| [3819] | 189 | /** Extensions class which encapsulates the querying of extensions and |
|---|
| 190 | * associated function pointers, and provide convenience wrappers to |
|---|
| 191 | * check for the extensions or use the associated functions.*/ |
|---|
| [4021] | 192 | class OSG_EXPORT Extensions : public osg::Referenced |
|---|
| [3819] | 193 | { |
|---|
| 194 | public: |
|---|
| [4102] | 195 | Extensions(unsigned int contextID); |
|---|
| [3819] | 196 | |
|---|
| 197 | Extensions(const Extensions& rhs); |
|---|
| 198 | |
|---|
| 199 | void lowestCommonDenominator(const Extensions& rhs); |
|---|
| 200 | |
|---|
| [7038] | 201 | void setupGLExtensions(unsigned int contextID); |
|---|
| [3819] | 202 | |
|---|
| 203 | bool isBufferObjectSupported() const { return _glGenBuffers!=0; } |
|---|
| [5474] | 204 | bool isPBOSupported() const { return _isPBOSupported; } |
|---|
| [3819] | 205 | |
|---|
| 206 | void glGenBuffers (GLsizei n, GLuint *buffers) const; |
|---|
| 207 | void glBindBuffer (GLenum target, GLuint buffer) const; |
|---|
| 208 | void glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const; |
|---|
| 209 | void glBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const; |
|---|
| 210 | void glDeleteBuffers (GLsizei n, const GLuint *buffers) const; |
|---|
| 211 | GLboolean glIsBuffer (GLuint buffer) const; |
|---|
| 212 | void glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const; |
|---|
| 213 | GLvoid* glMapBuffer (GLenum target, GLenum access) const; |
|---|
| 214 | GLboolean glUnmapBuffer (GLenum target) const; |
|---|
| 215 | void glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const; |
|---|
| 216 | void glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const; |
|---|
| 217 | |
|---|
| 218 | protected: |
|---|
| 219 | |
|---|
| 220 | typedef void (APIENTRY * GenBuffersProc) (GLsizei n, GLuint *buffers); |
|---|
| 221 | typedef void (APIENTRY * BindBufferProc) (GLenum target, GLuint buffer); |
|---|
| 222 | typedef void (APIENTRY * BufferDataProc) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); |
|---|
| 223 | typedef void (APIENTRY * BufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); |
|---|
| 224 | typedef void (APIENTRY * DeleteBuffersProc) (GLsizei n, const GLuint *buffers); |
|---|
| 225 | typedef GLboolean (APIENTRY * IsBufferProc) (GLuint buffer); |
|---|
| 226 | typedef void (APIENTRY * GetBufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); |
|---|
| 227 | typedef GLvoid* (APIENTRY * MapBufferProc) (GLenum target, GLenum access); |
|---|
| 228 | typedef GLboolean (APIENTRY * UnmapBufferProc) (GLenum target); |
|---|
| 229 | typedef void (APIENTRY * GetBufferParameterivProc) (GLenum target, GLenum pname, GLint *params); |
|---|
| 230 | typedef void (APIENTRY * GetBufferPointervProc) (GLenum target, GLenum pname, GLvoid* *params); |
|---|
| 231 | |
|---|
| 232 | GenBuffersProc _glGenBuffers; |
|---|
| 233 | BindBufferProc _glBindBuffer; |
|---|
| 234 | BufferDataProc _glBufferData; |
|---|
| 235 | BufferSubDataProc _glBufferSubData; |
|---|
| 236 | DeleteBuffersProc _glDeleteBuffers; |
|---|
| 237 | IsBufferProc _glIsBuffer; |
|---|
| 238 | GetBufferSubDataProc _glGetBufferSubData; |
|---|
| 239 | MapBufferProc _glMapBuffer; |
|---|
| 240 | UnmapBufferProc _glUnmapBuffer; |
|---|
| 241 | GetBufferParameterivProc _glGetBufferParameteriv; |
|---|
| 242 | GetBufferPointervProc _glGetBufferPointerv; |
|---|
| 243 | |
|---|
| [5474] | 244 | bool _isPBOSupported; |
|---|
| [3819] | 245 | }; |
|---|
| 246 | |
|---|
| 247 | /** Function to call to get the extension of a specified context. |
|---|
| [7648] | 248 | * If the Extension object for that context has not yet been created |
|---|
| [3819] | 249 | * and the 'createIfNotInitalized' flag been set to false then returns NULL. |
|---|
| 250 | * If 'createIfNotInitalized' is true then the Extensions object is |
|---|
| 251 | * automatically created. However, in this case the extension object is |
|---|
| 252 | * only created with the graphics context associated with ContextID..*/ |
|---|
| 253 | static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized); |
|---|
| 254 | |
|---|
| 255 | /** setExtensions allows users to override the extensions across graphics contexts. |
|---|
| 256 | * typically used when you have different extensions supported across graphics pipes |
|---|
| 257 | * but need to ensure that they all use the same low common denominator extensions.*/ |
|---|
| 258 | static void setExtensions(unsigned int contextID,Extensions* extensions); |
|---|
| 259 | |
|---|
| 260 | protected: |
|---|
| 261 | |
|---|
| [10600] | 262 | virtual ~GLBufferObject(); |
|---|
| [3819] | 263 | |
|---|
| [10600] | 264 | unsigned int _contextID; |
|---|
| 265 | GLuint _glObjectID; |
|---|
| [3819] | 266 | |
|---|
| 267 | GLenum _target; |
|---|
| 268 | GLenum _usage; |
|---|
| [10600] | 269 | |
|---|
| 270 | bool _dirty; |
|---|
| 271 | |
|---|
| [3819] | 272 | mutable unsigned int _totalSize; |
|---|
| [10600] | 273 | |
|---|
| 274 | typedef std::vector<BufferEntry> BufferEntries; |
|---|
| 275 | BufferEntries _bufferEntries; |
|---|
| 276 | |
|---|
| 277 | BufferObject* _bufferObject; |
|---|
| 278 | |
|---|
| 279 | public: |
|---|
| 280 | Extensions* _extensions; |
|---|
| 281 | |
|---|
| [3819] | 282 | }; |
|---|
| 283 | |
|---|
| [10600] | 284 | class OSG_EXPORT BufferObject : public Object |
|---|
| 285 | { |
|---|
| 286 | public: |
|---|
| 287 | |
|---|
| 288 | BufferObject(); |
|---|
| 289 | |
|---|
| 290 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 291 | BufferObject(const BufferObject& bo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 292 | |
|---|
| 293 | virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferObject*>(obj)!=NULL; } |
|---|
| 294 | virtual const char* libraryName() const { return "osg"; } |
|---|
| 295 | virtual const char* className() const { return "BufferObject"; } |
|---|
| 296 | |
|---|
| 297 | void setTarget(GLenum target) { _target = target; } |
|---|
| 298 | GLenum getTarget() const { return _target; } |
|---|
| 299 | |
|---|
| 300 | /** Set what type of usage the buffer object will have. Options are: |
|---|
| 301 | * GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, |
|---|
| 302 | * GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, |
|---|
| 303 | * GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY. |
|---|
| 304 | */ |
|---|
| 305 | void setUsage(GLenum usage) { _usage = usage; } |
|---|
| 306 | |
|---|
| 307 | /** Get the type of usage the buffer object has been set up for.*/ |
|---|
| 308 | GLenum getUsage() const { return _usage; } |
|---|
| 309 | |
|---|
| 310 | void dirty(); |
|---|
| 311 | |
|---|
| 312 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 313 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 314 | |
|---|
| 315 | /** If State is non-zero, this function releases OpenGL objects for |
|---|
| 316 | * the specified graphics context. Otherwise, releases OpenGL objects |
|---|
| 317 | * for all graphics contexts. */ |
|---|
| 318 | void releaseGLObjects(State* state=0) const; |
|---|
| 319 | |
|---|
| 320 | unsigned int addBufferData(BufferData* bd); |
|---|
| 321 | void removeBufferData(unsigned int index); |
|---|
| 322 | void removeBufferData(BufferData* bd); |
|---|
| 323 | |
|---|
| 324 | void setBufferData(unsigned int index, BufferData* bd); |
|---|
| 325 | BufferData* getBufferData(unsigned int index) { return _bufferDataList[index]; } |
|---|
| 326 | const BufferData* getBufferData(unsigned int index) const { return _bufferDataList[index]; } |
|---|
| 327 | |
|---|
| 328 | unsigned int getNumBufferData() const { return _bufferDataList.size(); } |
|---|
| 329 | |
|---|
| 330 | GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _glBufferObjects[contextID].get(); } |
|---|
| 331 | |
|---|
| 332 | GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const |
|---|
| 333 | { |
|---|
| 334 | if (!_glBufferObjects[contextID]) _glBufferObjects[contextID] = GLBufferObject::createGLBufferObject(contextID, this); |
|---|
| 335 | return _glBufferObjects[contextID].get(); |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | protected: |
|---|
| 339 | |
|---|
| 340 | ~BufferObject(); |
|---|
| 341 | |
|---|
| 342 | typedef std::vector< BufferData* > BufferDataList; |
|---|
| 343 | typedef osg::buffered_object< osg::ref_ptr<GLBufferObject> > GLBufferObjects; |
|---|
| 344 | |
|---|
| 345 | GLenum _target; |
|---|
| 346 | GLenum _usage; |
|---|
| 347 | BufferDataList _bufferDataList; |
|---|
| 348 | |
|---|
| 349 | mutable GLBufferObjects _glBufferObjects; |
|---|
| 350 | }; |
|---|
| 351 | |
|---|
| 352 | class BufferData : public Object |
|---|
| 353 | { |
|---|
| 354 | public: |
|---|
| 355 | |
|---|
| 356 | BufferData(): |
|---|
| 357 | Object(true), |
|---|
| 358 | _modifiedCount(0), |
|---|
| 359 | _bufferIndex(0) {} |
|---|
| 360 | |
|---|
| 361 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 362 | BufferData(const BufferData& bd,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 363 | osg::Object(bd,copyop), |
|---|
| 364 | _modifiedCount(0), |
|---|
| 365 | _bufferIndex(0) {} |
|---|
| 366 | |
|---|
| 367 | virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferData*>(obj)!=NULL; } |
|---|
| 368 | virtual const char* libraryName() const { return "osg"; } |
|---|
| 369 | virtual const char* className() const { return "BufferData"; } |
|---|
| 370 | |
|---|
| 371 | virtual const GLvoid* getDataPointer() const = 0; |
|---|
| 372 | virtual unsigned int getTotalDataSize() const = 0; |
|---|
| 373 | |
|---|
| 374 | void setBufferObject(BufferObject* bufferObject); |
|---|
| 375 | BufferObject* getBufferObject() { return _bufferObject.get(); } |
|---|
| 376 | const BufferObject* getBufferObject() const { return _bufferObject.get(); } |
|---|
| 377 | |
|---|
| 378 | void setBufferIndex(unsigned int index) { _bufferIndex = index; } |
|---|
| 379 | unsigned int getBufferIndex() const { return _bufferIndex; } |
|---|
| 380 | |
|---|
| 381 | GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getGLBufferObject(contextID) : 0; } |
|---|
| 382 | GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getOrCreateGLBufferObject(contextID) : 0; } |
|---|
| 383 | |
|---|
| 384 | /** Dirty the primitive, which increments the modified count, to force buffer objects to update. */ |
|---|
| 385 | inline void dirty() { ++_modifiedCount; if (_bufferObject.valid()) _bufferObject->dirty(); } |
|---|
| 386 | |
|---|
| 387 | /** Set the modified count value.*/ |
|---|
| 388 | inline void setModifiedCount(unsigned int value) { _modifiedCount=value; } |
|---|
| 389 | |
|---|
| 390 | /** Get modified count value.*/ |
|---|
| 391 | inline unsigned int getModifiedCount() const { return _modifiedCount; } |
|---|
| 392 | |
|---|
| 393 | protected: |
|---|
| 394 | |
|---|
| 395 | virtual ~BufferData(); |
|---|
| 396 | |
|---|
| 397 | unsigned int _modifiedCount; |
|---|
| 398 | |
|---|
| 399 | unsigned int _bufferIndex; |
|---|
| 400 | osg::ref_ptr<BufferObject> _bufferObject; |
|---|
| 401 | }; |
|---|
| 402 | |
|---|
| 403 | |
|---|
| [6555] | 404 | class Array; |
|---|
| 405 | class OSG_EXPORT VertexBufferObject : public BufferObject |
|---|
| 406 | { |
|---|
| 407 | public: |
|---|
| 408 | |
|---|
| 409 | VertexBufferObject(); |
|---|
| 410 | |
|---|
| 411 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 412 | VertexBufferObject(const VertexBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 413 | |
|---|
| 414 | META_Object(osg,VertexBufferObject); |
|---|
| 415 | |
|---|
| 416 | unsigned int addArray(osg::Array* array); |
|---|
| [6582] | 417 | void removeArray(osg::Array* array); |
|---|
| [6555] | 418 | |
|---|
| 419 | void setArray(unsigned int i, Array* array); |
|---|
| [10600] | 420 | Array* getArray(unsigned int i); |
|---|
| 421 | const Array* getArray(unsigned int i) const; |
|---|
| [6565] | 422 | |
|---|
| [6555] | 423 | protected: |
|---|
| 424 | virtual ~VertexBufferObject(); |
|---|
| 425 | }; |
|---|
| 426 | |
|---|
| 427 | class DrawElements; |
|---|
| [6578] | 428 | class OSG_EXPORT ElementBufferObject : public BufferObject |
|---|
| [6555] | 429 | { |
|---|
| 430 | public: |
|---|
| 431 | |
|---|
| [6578] | 432 | ElementBufferObject(); |
|---|
| [6555] | 433 | |
|---|
| 434 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| [6578] | 435 | ElementBufferObject(const ElementBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| [6555] | 436 | |
|---|
| [6578] | 437 | META_Object(osg,ElementBufferObject); |
|---|
| [6555] | 438 | |
|---|
| 439 | unsigned int addDrawElements(osg::DrawElements* PrimitiveSet); |
|---|
| [6582] | 440 | void removeDrawElements(osg::DrawElements* PrimitiveSet); |
|---|
| [6555] | 441 | |
|---|
| 442 | void setDrawElements(unsigned int i, DrawElements* PrimitiveSet); |
|---|
| [10600] | 443 | DrawElements* getDrawElements(unsigned int i); |
|---|
| 444 | const DrawElements* getDrawElements(unsigned int i) const; |
|---|
| [6565] | 445 | |
|---|
| [6555] | 446 | protected: |
|---|
| 447 | |
|---|
| [6578] | 448 | virtual ~ElementBufferObject(); |
|---|
| [6555] | 449 | }; |
|---|
| 450 | |
|---|
| [3819] | 451 | class Image; |
|---|
| [4021] | 452 | class OSG_EXPORT PixelBufferObject : public BufferObject |
|---|
| [3819] | 453 | { |
|---|
| 454 | public: |
|---|
| 455 | |
|---|
| 456 | PixelBufferObject(osg::Image* image=0); |
|---|
| 457 | |
|---|
| 458 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 459 | PixelBufferObject(const PixelBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 460 | |
|---|
| 461 | META_Object(osg,PixelBufferObject); |
|---|
| 462 | |
|---|
| 463 | void setImage(osg::Image* image); |
|---|
| 464 | |
|---|
| [10600] | 465 | Image* getImage(); |
|---|
| 466 | const Image* getImage() const; |
|---|
| [3819] | 467 | |
|---|
| [10600] | 468 | bool isPBOSupported(unsigned int contextID) const { return _glBufferObjects[contextID]->isPBOSupported(); } |
|---|
| [3819] | 469 | |
|---|
| 470 | protected: |
|---|
| 471 | |
|---|
| 472 | virtual ~PixelBufferObject(); |
|---|
| 473 | }; |
|---|
| 474 | |
|---|
| [9302] | 475 | /** |
|---|
| 476 | * This object represent a general class of pixel buffer objects, |
|---|
| 477 | * which are capable of allocating buffer object (memory) |
|---|
| 478 | * on the GPU. The memory can then be used either for CPU-GPU |
|---|
| 479 | * pixel transfer or directly for GPU-GPU transfer, without CPU intervention. |
|---|
| 480 | **/ |
|---|
| 481 | class OSG_EXPORT PixelDataBufferObject : public BufferObject |
|---|
| 482 | { |
|---|
| 483 | public: |
|---|
| 484 | PixelDataBufferObject(); |
|---|
| 485 | PixelDataBufferObject(const PixelDataBufferObject& pbo, const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| [3819] | 486 | |
|---|
| [9302] | 487 | META_Object(osg, PixelDataBufferObject); |
|---|
| 488 | |
|---|
| 489 | //! Set new size of the buffer object. This will reallocate the memory on the next compile |
|---|
| [10600] | 490 | inline void setDataSize(unsigned int size) { _dataSize = size; dirty(); } |
|---|
| [9302] | 491 | |
|---|
| 492 | //! Get data size of the used buffer |
|---|
| [10600] | 493 | inline unsigned int getDataSize() const { return _dataSize; } |
|---|
| [9302] | 494 | |
|---|
| 495 | //! Compile the buffer (reallocate the memory if buffer is dirty) |
|---|
| 496 | virtual void compileBuffer(State& state) const; |
|---|
| 497 | |
|---|
| 498 | //! Bind the buffer in read mode, which means that data can be downloaded from the buffer (note: GL_PIXEL_UNPACK_BUFFER_ARB) |
|---|
| 499 | virtual void bindBufferInReadMode(State& state); |
|---|
| 500 | |
|---|
| 501 | //! Bind the buffer in write mode, which means following OpenGL instructions will write data into the buffer (note: GL_PIXEL_PACK_BUFFER_ARB) |
|---|
| 502 | virtual void bindBufferInWriteMode(State& state); |
|---|
| 503 | |
|---|
| 504 | //! Unbind the buffer |
|---|
| 505 | virtual void unbindBuffer(unsigned int contextID) const; |
|---|
| 506 | |
|---|
| 507 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 508 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 509 | |
|---|
| 510 | enum Mode |
|---|
| 511 | { |
|---|
| 512 | //! A normal mode of this data buffer |
|---|
| 513 | NONE = 0, |
|---|
| 514 | |
|---|
| 515 | //! Buffer is in read mode (@see bindBufferInReadMode) |
|---|
| 516 | READ = 1, |
|---|
| 517 | |
|---|
| 518 | //! Buffer is in write mode (@see bindBufferInWriteMode) |
|---|
| 519 | WRITE = 2 |
|---|
| 520 | }; |
|---|
| 521 | |
|---|
| 522 | Mode getMode(unsigned int contextID) const { return (Mode)_mode[contextID]; } |
|---|
| 523 | |
|---|
| 524 | protected: |
|---|
| 525 | |
|---|
| 526 | virtual ~PixelDataBufferObject(); |
|---|
| 527 | |
|---|
| [10600] | 528 | unsigned int _dataSize; |
|---|
| [9302] | 529 | |
|---|
| 530 | typedef osg::buffered_value<unsigned int> ModeList; |
|---|
| 531 | |
|---|
| 532 | mutable ModeList _mode; |
|---|
| 533 | |
|---|
| 534 | }; |
|---|
| 535 | |
|---|
| 536 | |
|---|
| [3819] | 537 | } |
|---|
| 538 | |
|---|
| 539 | #endif |
|---|