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

Revision 12912, 32.1 kB (checked in by robert, 2 years ago)

Added support for using GL_UNPACK_ROW_LENGTH in conjunction with texture's + osg::Image via new RowLength?
parameter in osg::Image. To support this Image::setData(..) now has a new optional rowLength parameter which
defaults to 0, which provides the original behaviour, Image::setRowLength(int) and int Image::getRowLength() are also provided.

With the introduction of RowLength? support in osg::Image it is now possible to create a sub image where
the t size of the image are smaller than the row length, useful for when you have a large image on the CPU
and which to use a small portion of it on the GPU. However, when these sub images are created the data
within the image is no longer contiguous so data access can no longer assume that all the data is in
one block. The new method Image::isDataContiguous() enables the user to check whether the data is contiguous,
and if not one can either access the data row by row using Image::data(column,row,image) accessor, or use the
new Image::DataIterator? for stepping through each block on memory assocatied with the image.

To support the possibility of non contiguous osg::Image usage of image objects has had to be updated to
check DataContiguous? and handle the case or use access via the DataIerator? or by row by row. To achieve
this a relatively large number of files has had to be modified, in particular the texture classes and
image plugins that doing writing.

  • 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.