root/OpenSceneGraph/trunk/include/osg/BufferObject @ 10600

Revision 10600, 20.6 kB (checked in by robert, 5 years ago)

Introduced new BufferObject? design + implementation in preperation of implementing a pool system for buffer objects

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[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]98namespace osg
99{
100
[4018]101class State;
[10600]102class BufferData;
103class BufferObject;
[4018]104
[10600]105class 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]284class 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
352class 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]404class Array;
405class 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
427class DrawElements;
[6578]428class 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]451class Image;
[4021]452class 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 **/
481class 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
Note: See TracBrowser for help on using the browser.