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

Revision 13041, 32.1 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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#include <osg/FrameStamp>
21
22#include <iosfwd>
23#include <list>
24#include <map>
25
26// identify GLES 1.1
27#if (defined(GL_VERSION_ES_CM_1_0) && GL_VERSION_ES_CM_1_0 > 0) || \
28    (defined(GL_VERSION_ES_CM_1_1) && GL_VERSION_ES_CM_1_1 > 0)
29
30    #define OPENGLES_1_1_FOUND 1
31
32#endif
33
34// for compatibility with gl.h headers that don't support VBO,
35//GL_VERSION_1_5 and GL_ARB_vertex_buffer_object provide these types for OpenGL
36//all ES versions except GL_OES_VERSION_1_0 provide these types for OpenGL ES
37#if !defined(GL_VERSION_1_5) && !defined(GL_ARB_vertex_buffer_object) \
38  && !defined(GL_ES_VERSION_2_0) && !defined(OPENGLES_1_1_FOUND)
39    #if defined(_WIN64)
40        typedef __int64 GLintptr;
41        typedef __int64 GLsizeiptr;
42    #elif defined(__ia64__) || defined(__x86_64__) || defined(ANDROID)
43        typedef long int GLintptr;
44        typedef long int GLsizeiptr;
45    #else
46        typedef int GLintptr;
47        typedef int GLsizeiptr;
48    #endif
49#endif
50
51#ifndef GL_ARB_vertex_buffer_object
52    #define GL_ARB_vertex_buffer_object
53
54    typedef GLintptr GLintptrARB;
55    typedef GLsizeiptr GLsizeiptrARB;
56
57    #define GL_ARRAY_BUFFER_ARB               0x8892
58    #define GL_ELEMENT_ARRAY_BUFFER_ARB       0x8893
59    #define GL_ARRAY_BUFFER_BINDING_ARB       0x8894
60    #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
61    #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
62    #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
63    #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
64    #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
65    #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
66    #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
67    #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
68    #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
69    #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
70    #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
71    #define GL_STREAM_DRAW_ARB                0x88E0
72    #define GL_STREAM_READ_ARB                0x88E1
73    #define GL_STREAM_COPY_ARB                0x88E2
74    #define GL_STATIC_DRAW_ARB                0x88E4
75    #define GL_STATIC_READ_ARB                0x88E5
76    #define GL_STATIC_COPY_ARB                0x88E6
77    #define GL_DYNAMIC_DRAW_ARB               0x88E8
78    #define GL_DYNAMIC_READ_ARB               0x88E9
79    #define GL_DYNAMIC_COPY_ARB               0x88EA
80    #define GL_READ_ONLY_ARB                  0x88B8
81    #define GL_WRITE_ONLY_ARB                 0x88B9
82    #define GL_READ_WRITE_ARB                 0x88BA
83    #define GL_BUFFER_SIZE_ARB                0x8764
84    #define GL_BUFFER_USAGE_ARB               0x8765
85    #define GL_BUFFER_ACCESS_ARB              0x88BB
86    #define GL_BUFFER_MAPPED_ARB              0x88BC
87    #define GL_BUFFER_MAP_POINTER_ARB         0x88BD
88#endif
89
90#ifndef GL_VERSION_1_5
91    #define GL_STREAM_DRAW                    0x88E0
92    #define GL_STREAM_READ                    0x88E1
93    #define GL_STREAM_COPY                    0x88E2
94    #define GL_STATIC_DRAW                    0x88E4
95    #define GL_STATIC_READ                    0x88E5
96    #define GL_STATIC_COPY                    0x88E6
97    #define GL_DYNAMIC_DRAW                   0x88E8
98    #define GL_DYNAMIC_READ                   0x88E9
99    #define GL_DYNAMIC_COPY                   0x88EA
100#endif
101
102#ifndef GL_VERSION_2_1
103    #define GL_PIXEL_PACK_BUFFER              0x88EB
104    #define GL_PIXEL_UNPACK_BUFFER            0x88EC
105    #define GL_PIXEL_PACK_BUFFER_BINDING      0x88ED
106    #define GL_PIXEL_UNPACK_BUFFER_BINDING    0x88EF
107#endif
108
109
110#ifndef GL_ARB_pixel_buffer_object
111    #define GL_PIXEL_PACK_BUFFER_ARB            0x88EB
112    #define GL_PIXEL_UNPACK_BUFFER_ARB          0x88EC
113    #define GL_PIXEL_PACK_BUFFER_BINDING_ARB    0x88ED
114    #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB  0x88EF
115#endif
116
117namespace osg
118{
119
120class State;
121class BufferData;
122class BufferObject;
123
124class BufferObjectProfile
125{
126    public:
127        BufferObjectProfile():
128            _target(0),
129            _usage(0),
130            _size(0) {}
131
132        BufferObjectProfile(GLenum target, GLenum usage, unsigned int size):
133            _target(target),
134            _usage(usage),
135            _size(size) {}
136
137        BufferObjectProfile(const BufferObjectProfile& bpo):
138            _target(bpo._target),
139            _usage(bpo._usage),
140            _size(bpo._size) {}
141
142        bool operator < (const BufferObjectProfile& rhs) const
143        {
144            if (_target < rhs._target) return true;
145            else if (_target > rhs._target) return false;
146            if (_usage < rhs._usage) return true;
147            else if (_usage > rhs._usage) return false;
148            return _size < rhs._size;
149        }
150
151        bool operator == (const BufferObjectProfile& rhs) const
152        {
153            return (_target == rhs._target) &&
154                   (_usage == rhs._usage) &&
155                   (_size == rhs._size);
156        }
157
158        void setProfile(GLenum target, GLenum usage, unsigned int size)
159        {
160            _target = target;
161            _usage = usage;
162            _size = size;
163        }
164
165        BufferObjectProfile& operator = (const BufferObjectProfile& rhs)
166        {
167            _target = rhs._target;
168            _usage = rhs._usage;
169            _size = rhs._size;
170            return *this;
171        }
172
173        GLenum _target;
174        GLenum _usage;
175        GLenum _size;
176};
177
178// forward declare
179class GLBufferObjectSet;
180class GLBufferObjectManager;
181
182class OSG_EXPORT GLBufferObject : public Referenced
183{
184    public:
185
186        GLBufferObject(unsigned int contextID, BufferObject* bufferObject, unsigned int glObjectID=0);
187
188        void setProfile(const BufferObjectProfile& profile) { _profile = profile; }
189        const BufferObjectProfile& getProfile() const { return _profile; }
190
191        void setBufferObject(BufferObject* bufferObject);
192        BufferObject* getBufferObject() { return _bufferObject; }
193
194        struct BufferEntry
195        {
196            BufferEntry(): modifiedCount(0),dataSize(0),offset(0),dataSource(0) {}
197
198            BufferEntry(const BufferEntry& rhs):
199                modifiedCount(rhs.modifiedCount),
200                dataSize(rhs.dataSize),
201                offset(rhs.offset),
202                dataSource(rhs.dataSource) {}
203
204            BufferEntry& operator = (const BufferEntry& rhs)
205            {
206                if (&rhs==this) return *this;
207                modifiedCount = rhs.modifiedCount;
208                dataSize = rhs.dataSize;
209                offset = rhs.offset;
210                dataSource = rhs.dataSource;
211                return *this;
212            }
213
214            unsigned int        modifiedCount;
215            unsigned int        dataSize;
216            unsigned int        offset;
217            BufferData*         dataSource;
218        };
219
220        inline unsigned int getContextID() const { return _contextID; }
221
222        inline GLuint& getGLObjectID() { return _glObjectID; }
223        inline GLuint getGLObjectID() const { return _glObjectID; }
224        inline GLsizeiptrARB getOffset(unsigned int i) const { return _bufferEntries[i].offset; }
225
226        inline void bindBuffer();
227
228        inline void unbindBuffer()
229        {
230            _extensions->glBindBuffer(_profile._target,0);
231        }
232
233        inline bool isDirty() const { return _dirty; }
234
235        void dirty() { _dirty = true; }
236
237        void clear();
238
239        void compileBuffer();
240
241        void deleteGLObject();
242
243        void assign(BufferObject* bufferObject);
244
245        bool isPBOSupported() const { return _extensions->isPBOSupported(); }
246
247        static GLBufferObject* createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject);
248
249        static void deleteAllBufferObjects(unsigned int contextID);
250        static void discardAllBufferObjects(unsigned int contextID);
251        static void flushAllDeletedBufferObjects(unsigned int contextID);
252        static void discardAllDeletedBufferObjects(unsigned int contextID);
253        static void flushDeletedBufferObjects(unsigned int contextID,double currentTime, double& availbleTime);
254        static void releaseGLBufferObject(unsigned int contextID, GLBufferObject* to);
255
256        /** Extensions class which encapsulates the querying of extensions and
257        * associated function pointers, and provide convenience wrappers to
258        * check for the extensions or use the associated functions.*/
259        class OSG_EXPORT Extensions : public osg::Referenced
260        {
261        public:
262            Extensions(unsigned int contextID);
263
264            Extensions(const Extensions& rhs);
265
266            void lowestCommonDenominator(const Extensions& rhs);
267
268            void setupGLExtensions(unsigned int contextID);
269
270            bool isBufferObjectSupported() const { return _glGenBuffers!=0; }
271            bool isPBOSupported() const { return _isPBOSupported; }
272            bool isUniformBufferObjectSupported() const { return _isUniformBufferObjectSupported; }
273
274            void glGenBuffers (GLsizei n, GLuint *buffers) const;
275            void glBindBuffer (GLenum target, GLuint buffer) const;
276            void glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const;
277            void glBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const;
278            void glDeleteBuffers (GLsizei n, const GLuint *buffers) const;
279            GLboolean glIsBuffer (GLuint buffer) const;
280            void glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const;
281            GLvoid* glMapBuffer (GLenum target, GLenum access) const;
282            GLboolean glUnmapBuffer (GLenum target) const;
283            void glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const;
284            void glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const;
285            void glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
286            void glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
287
288        protected:
289
290            typedef void (GL_APIENTRY * GenBuffersProc) (GLsizei n, GLuint *buffers);
291            typedef void (GL_APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
292            typedef void (GL_APIENTRY * BufferDataProc) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
293            typedef void (GL_APIENTRY * BufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
294            typedef void (GL_APIENTRY * DeleteBuffersProc) (GLsizei n, const GLuint *buffers);
295            typedef GLboolean (GL_APIENTRY * IsBufferProc) (GLuint buffer);
296            typedef void (GL_APIENTRY * GetBufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
297            typedef GLvoid* (GL_APIENTRY * MapBufferProc) (GLenum target, GLenum access);
298            typedef GLboolean (GL_APIENTRY * UnmapBufferProc) (GLenum target);
299            typedef void (GL_APIENTRY * GetBufferParameterivProc) (GLenum target, GLenum pname, GLint *params);
300            typedef void (GL_APIENTRY * GetBufferPointervProc) (GLenum target, GLenum pname, GLvoid* *params);
301            typedef void (GL_APIENTRY * BindBufferRangeProc) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
302            typedef void (GL_APIENTRY * BindBufferBaseProc) (GLenum target, GLuint index, GLuint buffer);
303
304
305            GenBuffersProc          _glGenBuffers;
306            BindBufferProc          _glBindBuffer;
307            BufferDataProc          _glBufferData;
308            BufferSubDataProc       _glBufferSubData;
309            DeleteBuffersProc       _glDeleteBuffers;
310            IsBufferProc            _glIsBuffer;
311            GetBufferSubDataProc    _glGetBufferSubData;
312            MapBufferProc           _glMapBuffer;
313            UnmapBufferProc         _glUnmapBuffer;
314            GetBufferParameterivProc _glGetBufferParameteriv;
315            GetBufferPointervProc   _glGetBufferPointerv;
316            BindBufferRangeProc     _glBindBufferRange;
317            BindBufferBaseProc      _glBindBufferBase;
318
319            bool _isPBOSupported;
320            bool _isUniformBufferObjectSupported;
321        };
322
323        /** Function to call to get the extension of a specified context.
324        * If the Extension object for that context has not yet been created
325        * and the 'createIfNotInitalized' flag been set to false then returns NULL.
326        * If 'createIfNotInitalized' is true then the Extensions object is
327        * automatically created.  However, in this case the extension object is
328        * only created with the graphics context associated with ContextID..*/
329        static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized);
330
331        /** setExtensions allows users to override the extensions across graphics contexts.
332        * typically used when you have different extensions supported across graphics pipes
333        * but need to ensure that they all use the same low common denominator extensions.*/
334        static void setExtensions(unsigned int contextID,Extensions* extensions);
335
336    protected:
337
338        virtual ~GLBufferObject();
339
340        unsigned int computeBufferAlignment(unsigned int pos, unsigned int bufferAlignment) const
341        {
342            if (bufferAlignment<2) return pos;
343            if ((pos%bufferAlignment)==0) return pos;
344            return ((pos/bufferAlignment)+1)*bufferAlignment;
345        }
346
347        unsigned int            _contextID;
348        GLuint                  _glObjectID;
349
350        BufferObjectProfile     _profile;
351        unsigned int            _allocatedSize;
352
353        bool                    _dirty;
354
355        typedef std::vector<BufferEntry> BufferEntries;
356        BufferEntries           _bufferEntries;
357
358        BufferObject*           _bufferObject;
359
360    public:
361
362        GLBufferObjectSet*      _set;
363        GLBufferObject*         _previous;
364        GLBufferObject*         _next;
365        unsigned int            _frameLastUsed;
366
367    public:
368        Extensions*             _extensions;
369
370};
371
372typedef std::list< ref_ptr<GLBufferObject> > GLBufferObjectList;
373
374class OSG_EXPORT GLBufferObjectSet : public Referenced
375{
376    public:
377        GLBufferObjectSet(GLBufferObjectManager* parent, const BufferObjectProfile& profile);
378
379        const BufferObjectProfile& getProfile() const { return _profile; }
380
381        void handlePendingOrphandedGLBufferObjects();
382
383        void deleteAllGLBufferObjects();
384        void discardAllGLBufferObjects();
385        void flushAllDeletedGLBufferObjects();
386        void discardAllDeletedGLBufferObjects();
387        void flushDeletedGLBufferObjects(double currentTime, double& availableTime);
388
389        GLBufferObject* takeFromOrphans(BufferObject* bufferObject);
390        GLBufferObject* takeOrGenerate(BufferObject* bufferObject);
391
392        void moveToBack(GLBufferObject* to);
393        void addToBack(GLBufferObject* to);
394        void orphan(GLBufferObject* to);
395        void remove(GLBufferObject* to);
396        void moveToSet(GLBufferObject* to, GLBufferObjectSet* set);
397
398        unsigned int size() const { return _profile._size * _numOfGLBufferObjects; }
399
400        bool makeSpace(unsigned int& size);
401
402        bool checkConsistency() const;
403
404        GLBufferObjectManager* getParent() { return _parent; }
405
406        unsigned int computeNumGLBufferObjectsInList() const;
407        unsigned int getNumOfGLBufferObjects() const { return _numOfGLBufferObjects; }
408        unsigned int getNumOrphans() const { return _orphanedGLBufferObjects.size(); }
409        unsigned int getNumPendingOrphans() const { return _pendingOrphanedGLBufferObjects.size(); }
410
411
412    protected:
413
414        virtual ~GLBufferObjectSet();
415
416        OpenThreads::Mutex  _mutex;
417
418        GLBufferObjectManager*  _parent;
419        unsigned int            _contextID;
420        BufferObjectProfile     _profile;
421        unsigned int            _numOfGLBufferObjects;
422        GLBufferObjectList      _orphanedGLBufferObjects;
423        GLBufferObjectList      _pendingOrphanedGLBufferObjects;
424
425        GLBufferObject*         _head;
426        GLBufferObject*         _tail;
427};
428
429class OSG_EXPORT GLBufferObjectManager : public osg::Referenced
430{
431    public:
432        GLBufferObjectManager(unsigned int contextID);
433
434        unsigned int getContextID() const { return _contextID; }
435
436
437        void setNumberActiveGLBufferObjects(unsigned int size) { _numActiveGLBufferObjects = size; }
438        unsigned int& getNumberActiveGLBufferObjects() { return _numActiveGLBufferObjects; }
439        unsigned int getNumberActiveGLBufferObjects() const { return _numActiveGLBufferObjects; }
440
441        void setNumberOrphanedGLBufferObjects(unsigned int size) { _numOrphanedGLBufferObjects = size; }
442        unsigned int& getNumberOrphanedGLBufferObjects() { return _numOrphanedGLBufferObjects; }
443        unsigned int getNumberOrphanedGLBufferObjects() const { return _numOrphanedGLBufferObjects; }
444
445        void setCurrGLBufferObjectPoolSize(unsigned int size) { _currGLBufferObjectPoolSize = size; }
446        unsigned int& getCurrGLBufferObjectPoolSize() { return _currGLBufferObjectPoolSize; }
447        unsigned int getCurrGLBufferObjectPoolSize() const { return _currGLBufferObjectPoolSize; }
448
449        void setMaxGLBufferObjectPoolSize(unsigned int size);
450        unsigned int getMaxGLBufferObjectPoolSize() const { return _maxGLBufferObjectPoolSize; }
451
452        bool hasSpace(unsigned int size) const { return (_currGLBufferObjectPoolSize+size)<=_maxGLBufferObjectPoolSize; }
453        bool makeSpace(unsigned int size);
454
455        GLBufferObject* generateGLBufferObject(const osg::BufferObject* bufferObject);
456
457        void handlePendingOrphandedGLBufferObjects();
458
459        void deleteAllGLBufferObjects();
460        void discardAllGLBufferObjects();
461        void flushAllDeletedGLBufferObjects();
462        void discardAllDeletedGLBufferObjects();
463        void flushDeletedGLBufferObjects(double currentTime, double& availableTime);
464        void releaseGLBufferObject(GLBufferObject* to);
465
466        GLBufferObjectSet* getGLBufferObjectSet(const BufferObjectProfile& profile);
467
468        void newFrame(osg::FrameStamp* fs);
469        void resetStats();
470        void reportStats(std::ostream& out);
471        void recomputeStats(std::ostream& out);
472
473        unsigned int& getFrameNumber() { return _frameNumber; }
474        unsigned int& getNumberFrames() { return _numFrames; }
475
476        unsigned int& getNumberDeleted() { return _numDeleted; }
477        double& getDeleteTime() { return _deleteTime; }
478
479        unsigned int& getNumberGenerated() { return _numGenerated; }
480        double& getGenerateTime() { return _generateTime; }
481
482        unsigned int& getNumberApplied() { return _numApplied; }
483        double& getApplyTime() { return _applyTime; }
484
485        static osg::ref_ptr<GLBufferObjectManager>& getGLBufferObjectManager(unsigned int contextID);
486
487    protected:
488
489        typedef std::map< BufferObjectProfile, osg::ref_ptr<GLBufferObjectSet> > GLBufferObjectSetMap;
490        unsigned int            _contextID;
491        unsigned int            _numActiveGLBufferObjects;
492        unsigned int            _numOrphanedGLBufferObjects;
493        unsigned int            _currGLBufferObjectPoolSize;
494        unsigned int            _maxGLBufferObjectPoolSize;
495        GLBufferObjectSetMap    _glBufferObjectSetMap;
496
497        unsigned int            _frameNumber;
498
499        unsigned int            _numFrames;
500        unsigned int            _numDeleted;
501        double                  _deleteTime;
502
503        unsigned int            _numGenerated;
504        double                  _generateTime;
505
506        unsigned int            _numApplied;
507        double                  _applyTime;
508
509};
510
511
512class OSG_EXPORT BufferObject : public Object
513{
514    public:
515
516        BufferObject();
517
518        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
519        BufferObject(const BufferObject& bo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
520
521        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferObject*>(obj)!=NULL; }
522        virtual const char* libraryName() const { return "osg"; }
523        virtual const char* className() const { return "BufferObject"; }
524
525        void setTarget(GLenum target) { _profile._target = target; }
526        GLenum getTarget() const { return _profile._target; }
527
528        /** Set what type of usage the buffer object will have. Options are:
529          *          GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
530          *          GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
531          *          GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY.
532          */
533        void setUsage(GLenum usage) { _profile._usage = usage; }
534
535        /** Get the type of usage the buffer object has been set up for.*/
536        GLenum getUsage() const { return _profile._usage; }
537
538        BufferObjectProfile& getProfile() { return _profile; }
539        const BufferObjectProfile& getProfile() const { return _profile; }
540
541
542        /** Set whether the BufferObject should use a GLBufferObject just for copying the BufferData and release it immmediately so that it may be reused.*/
543        void setCopyDataAndReleaseGLBufferObject(bool copyAndRelease) { _copyDataAndReleaseGLBufferObject = copyAndRelease; }
544
545        /** Get whether the BufferObject should use a GLBufferObject just for copying the BufferData and release it immmediately.*/
546        bool getCopyDataAndReleaseGLBufferObject() const { return _copyDataAndReleaseGLBufferObject; }
547
548
549        void dirty();
550
551        /** Resize any per context GLObject buffers to specified size. */
552        virtual void resizeGLObjectBuffers(unsigned int maxSize);
553
554        /** If State is non-zero, this function releases OpenGL objects for
555          * the specified graphics context. Otherwise, releases OpenGL objects
556          * for all graphics contexts. */
557        void releaseGLObjects(State* state=0) const;
558
559        unsigned int addBufferData(BufferData* bd);
560        void removeBufferData(unsigned int index);
561        void removeBufferData(BufferData* bd);
562
563        void setBufferData(unsigned int index, BufferData* bd);
564        BufferData* getBufferData(unsigned int index) { return _bufferDataList[index]; }
565        const BufferData* getBufferData(unsigned int index) const { return _bufferDataList[index]; }
566
567        unsigned int getNumBufferData() const { return _bufferDataList.size(); }
568
569        void setGLBufferObject(unsigned int contextID, GLBufferObject* glbo) { _glBufferObjects[contextID] = glbo; }
570
571        GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _glBufferObjects[contextID].get(); }
572
573        GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const
574        {
575            if (!_glBufferObjects[contextID]) _glBufferObjects[contextID] = GLBufferObject::createGLBufferObject(contextID, this);
576            return _glBufferObjects[contextID].get();
577        }
578
579        unsigned int computeRequiredBufferSize() const;
580
581        /** deprecated, provided for backwards compatibility.*/
582        static void deleteBufferObject(unsigned int contextID,GLuint globj);
583
584    protected:
585
586        ~BufferObject();
587
588        typedef std::vector< BufferData* > BufferDataList;
589        typedef osg::buffered_object< osg::ref_ptr<GLBufferObject> > GLBufferObjects;
590
591        BufferObjectProfile     _profile;
592
593        bool                    _copyDataAndReleaseGLBufferObject;
594
595        BufferDataList          _bufferDataList;
596
597        mutable GLBufferObjects _glBufferObjects;
598};
599
600class OSG_EXPORT BufferData : public Object
601{
602    public:
603
604        BufferData():
605            Object(true),
606            _modifiedCount(0),
607            _bufferIndex(0) {}
608
609        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
610        BufferData(const BufferData& bd,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
611            osg::Object(bd,copyop),
612            _modifiedCount(0),
613            _bufferIndex(0),
614            _modifiedCallback(bd._modifiedCallback) {}
615
616        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferData*>(obj)!=NULL; }
617        virtual const char* libraryName() const { return "osg"; }
618        virtual const char* className() const { return "BufferData"; }
619
620        virtual const GLvoid*   getDataPointer() const = 0;
621        virtual unsigned int    getTotalDataSize() const = 0;
622
623        virtual osg::Array* asArray() { return 0; }
624        virtual const osg::Array* asArray() const { return 0; }
625
626        virtual osg::PrimitiveSet* asPrimitiveSet() { return 0; }
627        virtual const osg::PrimitiveSet* asPrimitiveSet() const { return 0; }
628
629        virtual osg::Image* asImage() { return 0; }
630        virtual const osg::Image* asImage() const { return 0; }
631
632        void setBufferObject(BufferObject* bufferObject);
633        BufferObject* getBufferObject() { return _bufferObject.get(); }
634        const BufferObject* getBufferObject() const { return _bufferObject.get(); }
635
636        void setBufferIndex(unsigned int index) { _bufferIndex = index; }
637        unsigned int getBufferIndex() const { return _bufferIndex; }
638
639        GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getGLBufferObject(contextID) : 0; }
640        GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getOrCreateGLBufferObject(contextID) : 0; }
641
642        struct ModifiedCallback : public virtual osg::Object
643        {
644            ModifiedCallback() {}
645
646            ModifiedCallback(const ModifiedCallback&,const CopyOp&) {}
647
648            META_Object(osg,ModifiedCallback);
649
650            virtual void modified(BufferData* /*bufferData*/) const {}
651        };
652
653        void setModifiedCallback(ModifiedCallback* md) { _modifiedCallback = md; }
654        ModifiedCallback* getModifiedCallback() { return _modifiedCallback.get(); }
655        const ModifiedCallback* getModifiedCallback() const { return _modifiedCallback.get(); }
656
657        /** Dirty the primitive, which increments the modified count, to force buffer objects to update.
658          * If a ModifiedCallback is attached to this BufferData then the callback is called prior to the bufferObject's dirty is called. */
659        inline void dirty()
660        {
661            ++_modifiedCount;
662            if (_modifiedCallback.valid()) _modifiedCallback->modified(this);
663            if (_bufferObject.valid()) _bufferObject->dirty();
664        }
665
666        /** Set the modified count value.*/
667        inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
668
669        /** Get modified count value.*/
670        inline unsigned int getModifiedCount() const { return _modifiedCount; }
671
672        /** Resize any per context GLObject buffers to specified size. */
673        virtual void resizeGLObjectBuffers(unsigned int maxSize);
674
675        /** If State is non-zero, this function releases OpenGL objects for
676          * the specified graphics context. Otherwise, releases OpenGL objects
677          * for all graphics contexts. */
678        void releaseGLObjects(State* state=0) const;
679
680protected:
681
682        virtual ~BufferData();
683
684        unsigned int                    _modifiedCount;
685
686        unsigned int                    _bufferIndex;
687        osg::ref_ptr<BufferObject>      _bufferObject;
688        osg::ref_ptr<ModifiedCallback>  _modifiedCallback;
689};
690
691
692class Array;
693class OSG_EXPORT VertexBufferObject : public BufferObject
694{
695    public:
696
697        VertexBufferObject();
698
699        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
700        VertexBufferObject(const VertexBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
701
702        META_Object(osg,VertexBufferObject);
703
704        unsigned int addArray(osg::Array* array);
705        void removeArray(osg::Array* array);
706
707        void setArray(unsigned int i, Array* array);
708        Array* getArray(unsigned int i);
709        const Array* getArray(unsigned int i) const;
710
711    protected:
712        virtual ~VertexBufferObject();
713};
714
715class DrawElements;
716class OSG_EXPORT ElementBufferObject : public BufferObject
717{
718    public:
719
720        ElementBufferObject();
721
722        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
723        ElementBufferObject(const ElementBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
724
725        META_Object(osg,ElementBufferObject);
726
727        unsigned int addDrawElements(osg::DrawElements* PrimitiveSet);
728        void removeDrawElements(osg::DrawElements* PrimitiveSet);
729
730        void setDrawElements(unsigned int i, DrawElements* PrimitiveSet);
731        DrawElements* getDrawElements(unsigned int i);
732        const DrawElements* getDrawElements(unsigned int i) const;
733
734    protected:
735
736        virtual ~ElementBufferObject();
737};
738
739class Image;
740class OSG_EXPORT PixelBufferObject : public BufferObject
741{
742    public:
743
744        PixelBufferObject(osg::Image* image=0);
745
746        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
747        PixelBufferObject(const PixelBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
748
749        META_Object(osg,PixelBufferObject);
750
751        void setImage(osg::Image* image);
752
753        Image* getImage();
754        const Image* getImage() const;
755
756        bool isPBOSupported(unsigned int contextID) const { return _glBufferObjects[contextID]->isPBOSupported(); }
757
758    protected:
759
760        virtual ~PixelBufferObject();
761};
762
763/**
764 * This object represent a general class of pixel buffer objects,
765 * which are capable of allocating buffer object (memory)
766 * on the GPU. The memory can then be used either for CPU-GPU
767 * pixel transfer or directly for GPU-GPU transfer, without CPU intervention.
768 **/
769class OSG_EXPORT PixelDataBufferObject : public BufferObject
770{
771    public:
772        PixelDataBufferObject();
773        PixelDataBufferObject(const PixelDataBufferObject& pbo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
774
775        META_Object(osg, PixelDataBufferObject);
776
777        //! Set new size of the buffer object. This will reallocate the memory on the next compile
778        inline void setDataSize(unsigned int size) { _profile._size = size; dirty(); }
779
780        //! Get data size of the used buffer
781        inline unsigned int getDataSize() const { return _profile._size; }
782
783        //! Compile the buffer (reallocate the memory if buffer is dirty)
784        virtual void compileBuffer(State& state) const;
785
786        //! Bind the buffer in read mode, which means that data can be downloaded from the buffer (note: GL_PIXEL_UNPACK_BUFFER_ARB)
787        virtual void bindBufferInReadMode(State& state);
788
789        //! Bind the buffer in write mode, which means following OpenGL instructions will write data into the buffer (note: GL_PIXEL_PACK_BUFFER_ARB)
790        virtual void bindBufferInWriteMode(State& state);
791
792        //! Unbind the buffer
793        virtual void unbindBuffer(unsigned int contextID) const;
794
795        /** Resize any per context GLObject buffers to specified size. */
796        virtual void resizeGLObjectBuffers(unsigned int maxSize);
797
798        enum Mode
799        {
800            //! A normal mode of this data buffer
801            NONE = 0,
802
803            //! Buffer is in read mode (@see bindBufferInReadMode)
804            READ = 1,
805
806            //! Buffer is in write mode (@see bindBufferInWriteMode)
807            WRITE = 2
808        };
809
810        Mode getMode(unsigned int contextID) const { return (Mode)_mode[contextID]; }
811
812    protected:
813
814        virtual ~PixelDataBufferObject();
815
816        typedef osg::buffered_value<unsigned int> ModeList;
817
818        mutable ModeList _mode;
819
820};
821
822class OSG_EXPORT UniformBufferObject : public BufferObject
823{
824 public:
825    UniformBufferObject();
826    UniformBufferObject(const UniformBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
827    META_Object(osg, UniformBufferObject);
828 protected:
829    virtual ~UniformBufferObject();
830};
831
832inline void GLBufferObject::bindBuffer()
833{
834    _extensions->glBindBuffer(_profile._target,_glObjectID);
835    if (_set) _set->moveToBack(this);
836}
837
838}
839
840#endif
Note: See TracBrowser for help on using the browser.