1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 * Copyright (C) 2012 David Callu
4 * This library is open source and may be redistributed and/or modified under
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version. The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * OpenSceneGraph Public License for more details.
15#ifndef OSG_BUFFEROBJECT
16#define OSG_BUFFEROBJECT 1
19#include <osg/GLExtensions>
21#include <osg/buffered_value>
22#include <osg/FrameStamp>
23#include <osg/GLObjects>
29#ifndef GL_ARB_vertex_buffer_object
30 #define GL_ARRAY_BUFFER_ARB 0x8892
31 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
32 #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
33 #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
34 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
35 #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
36 #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
37 #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
38 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
39 #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
40 #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
41 #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
42 #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
43 #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
44 #define GL_STREAM_DRAW_ARB 0x88E0
45 #define GL_STREAM_READ_ARB 0x88E1
46 #define GL_STREAM_COPY_ARB 0x88E2
47 #define GL_STATIC_DRAW_ARB 0x88E4
48 #define GL_STATIC_READ_ARB 0x88E5
49 #define GL_STATIC_COPY_ARB 0x88E6
50 #define GL_DYNAMIC_DRAW_ARB 0x88E8
51 #define GL_DYNAMIC_READ_ARB 0x88E9
52 #define GL_DYNAMIC_COPY_ARB 0x88EA
53 #define GL_READ_ONLY_ARB 0x88B8
54 #define GL_WRITE_ONLY_ARB 0x88B9
55 #define GL_READ_WRITE_ARB 0x88BA
56 #define GL_BUFFER_SIZE_ARB 0x8764
57 #define GL_BUFFER_USAGE_ARB 0x8765
58 #define GL_BUFFER_ACCESS_ARB 0x88BB
59 #define GL_BUFFER_MAPPED_ARB 0x88BC
60 #define GL_BUFFER_MAP_POINTER_ARB 0x88BD
64 #define GL_STREAM_DRAW 0x88E0
65 #define GL_STREAM_READ 0x88E1
66 #define GL_STREAM_COPY 0x88E2
67 #define GL_STATIC_DRAW 0x88E4
68 #define GL_STATIC_READ 0x88E5
69 #define GL_STATIC_COPY 0x88E6
70 #define GL_DYNAMIC_DRAW 0x88E8
71 #define GL_DYNAMIC_READ 0x88E9
72 #define GL_DYNAMIC_COPY 0x88EA
76 #define GL_PIXEL_PACK_BUFFER 0x88EB
77 #define GL_PIXEL_UNPACK_BUFFER 0x88EC
78 #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
79 #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
83#ifndef GL_ARB_pixel_buffer_object
84 #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
85 #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
86 #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
87 #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
97class BufferObjectProfile
100 BufferObjectProfile():
105 BufferObjectProfile(GLenum target, GLenum usage, unsigned int size):
110 BufferObjectProfile(const BufferObjectProfile& bpo):
111 _target(bpo._target),
115 bool operator < (const BufferObjectProfile& rhs) const
117 if (_target < rhs._target) return true;
118 else if (_target > rhs._target) return false;
119 if (_usage < rhs._usage) return true;
120 else if (_usage > rhs._usage) return false;
121 return _size < rhs._size;
124 bool operator == (const BufferObjectProfile& rhs) const
126 return (_target == rhs._target) &&
127 (_usage == rhs._usage) &&
128 (_size == rhs._size);
131 void setProfile(GLenum target, GLenum usage, unsigned int size)
138 BufferObjectProfile& operator = (const BufferObjectProfile& rhs)
140 _target = rhs._target;
152class GLBufferObjectSet;
153class GLBufferObjectManager;
155inline unsigned int computeBufferAlignment(unsigned int pos, unsigned int bufferAlignment)
157 if (bufferAlignment<2) return pos;
158 if ((pos%bufferAlignment)==0) return pos;
159 return ((pos/bufferAlignment)+1)*bufferAlignment;
163class OSG_EXPORT GLBufferObject : public GraphicsObject
167 GLBufferObject(unsigned int contextID, BufferObject* bufferObject, unsigned int glObjectID=0);
169 void setProfile(const BufferObjectProfile& profile) { _profile = profile; }
170 const BufferObjectProfile& getProfile() const { return _profile; }
172 void setBufferObject(BufferObject* bufferObject);
173 BufferObject* getBufferObject() { return _bufferObject; }
177 BufferEntry(): numRead(0), modifiedCount(0),dataSize(0),offset(0),dataSource(0) {}
179 BufferEntry(const BufferEntry& rhs):
180 numRead(rhs.numRead),
181 modifiedCount(rhs.modifiedCount),
182 dataSize(rhs.dataSize),
184 dataSource(rhs.dataSource) {}
186 BufferEntry& operator = (const BufferEntry& rhs)
188 if (&rhs==this) return *this;
189 numRead = rhs.numRead;
190 modifiedCount = rhs.modifiedCount;
191 dataSize = rhs.dataSize;
193 dataSource = rhs.dataSource;
197 unsigned int getNumClients() const;
199 unsigned int numRead;
200 unsigned int modifiedCount;
201 unsigned int dataSize;
203 BufferData* dataSource;
206 inline unsigned int getContextID() const { return _contextID; }
208 inline GLuint& getGLObjectID() { return _glObjectID; }
209 inline GLuint getGLObjectID() const { return _glObjectID; }
210 inline GLsizeiptr getOffset(unsigned int i) const { return _bufferEntries[i].offset; }
212 inline void bindBuffer();
214 inline void unbindBuffer()
216 _extensions->glBindBuffer(_profile._target,0);
219 /** release GLBufferObject to the orphan list to be reused or deleted.*/
222 inline bool isDirty() const { return _dirty; }
224 void dirty() { _dirty = true; }
228 void compileBuffer();
230 void deleteGLObject();
232 void assign(BufferObject* bufferObject);
234 bool isPBOSupported() const { return _extensions->isPBOSupported; }
236 bool hasAllBufferDataBeenRead() const;
238 void setBufferDataHasBeenRead(const osg::BufferData* bd);
242 virtual ~GLBufferObject();
244 unsigned int computeBufferAlignment(unsigned int pos, unsigned int bufferAlignment) const
246 return osg::computeBufferAlignment(pos, bufferAlignment);
249 unsigned int _contextID;
252 BufferObjectProfile _profile;
253 unsigned int _allocatedSize;
257 typedef std::vector<BufferEntry> BufferEntries;
258 BufferEntries _bufferEntries;
260 BufferObject* _bufferObject;
264 GLBufferObjectSet* _set;
265 GLBufferObject* _previous;
266 GLBufferObject* _next;
267 unsigned int _frameLastUsed;
270 GLExtensions* _extensions;
274typedef std::list< ref_ptr<GLBufferObject> > GLBufferObjectList;
276class OSG_EXPORT GLBufferObjectSet : public Referenced
279 GLBufferObjectSet(GLBufferObjectManager* parent, const BufferObjectProfile& profile);
281 const BufferObjectProfile& getProfile() const { return _profile; }
283 void handlePendingOrphandedGLBufferObjects();
285 void deleteAllGLBufferObjects();
286 void discardAllGLBufferObjects();
287 void flushAllDeletedGLBufferObjects();
288 void discardAllDeletedGLBufferObjects();
289 void flushDeletedGLBufferObjects(double currentTime, double& availableTime);
291 osg::ref_ptr<GLBufferObject> takeFromOrphans(BufferObject* bufferObject);
292 osg::ref_ptr<GLBufferObject> takeOrGenerate(BufferObject* bufferObject);
294 void moveToBack(GLBufferObject* to);
295 void addToBack(GLBufferObject* to);
296 void orphan(GLBufferObject* to);
297 void remove(GLBufferObject* to);
298 void moveToSet(GLBufferObject* to, GLBufferObjectSet* set);
300 unsigned int size() const { return _profile._size * _numOfGLBufferObjects; }
302 bool makeSpace(unsigned int& size);
304 bool checkConsistency() const;
306 GLBufferObjectManager* getParent() { return _parent; }
308 unsigned int computeNumGLBufferObjectsInList() const;
309 unsigned int getNumOfGLBufferObjects() const { return _numOfGLBufferObjects; }
310 unsigned int getNumOrphans() const { return static_cast<unsigned int>(_orphanedGLBufferObjects.size()); }
311 unsigned int getNumPendingOrphans() const { return static_cast<unsigned int>(_pendingOrphanedGLBufferObjects.size()); }
316 virtual ~GLBufferObjectSet();
318 OpenThreads::Mutex _mutex;
320 GLBufferObjectManager* _parent;
321 unsigned int _contextID;
322 BufferObjectProfile _profile;
323 unsigned int _numOfGLBufferObjects;
324 GLBufferObjectList _orphanedGLBufferObjects;
325 GLBufferObjectList _pendingOrphanedGLBufferObjects;
327 GLBufferObject* _head;
328 GLBufferObject* _tail;
331class OSG_EXPORT GLBufferObjectManager : public GraphicsObjectManager
334 GLBufferObjectManager(unsigned int contextID);
336 void setNumberActiveGLBufferObjects(unsigned int size) { _numActiveGLBufferObjects = size; }
337 unsigned int& getNumberActiveGLBufferObjects() { return _numActiveGLBufferObjects; }
338 unsigned int getNumberActiveGLBufferObjects() const { return _numActiveGLBufferObjects; }
340 void setNumberOrphanedGLBufferObjects(unsigned int size) { _numOrphanedGLBufferObjects = size; }
341 unsigned int& getNumberOrphanedGLBufferObjects() { return _numOrphanedGLBufferObjects; }
342 unsigned int getNumberOrphanedGLBufferObjects() const { return _numOrphanedGLBufferObjects; }
344 void setCurrGLBufferObjectPoolSize(unsigned int size) { _currGLBufferObjectPoolSize = size; }
345 unsigned int& getCurrGLBufferObjectPoolSize() { return _currGLBufferObjectPoolSize; }
346 unsigned int getCurrGLBufferObjectPoolSize() const { return _currGLBufferObjectPoolSize; }
348 void setMaxGLBufferObjectPoolSize(unsigned int size);
349 unsigned int getMaxGLBufferObjectPoolSize() const { return _maxGLBufferObjectPoolSize; }
351 bool hasSpace(unsigned int size) const { return (_currGLBufferObjectPoolSize+size)<=_maxGLBufferObjectPoolSize; }
352 bool makeSpace(unsigned int size);
354 osg::ref_ptr<GLBufferObject> generateGLBufferObject(const osg::BufferObject* bufferObject);
356 void handlePendingOrphandedGLBufferObjects();
358 void deleteAllGLObjects();
359 void discardAllGLObjects();
360 void flushAllDeletedGLObjects();
361 void discardAllDeletedGLObjects();
362 void flushDeletedGLObjects(double currentTime, double& availableTime);
364 GLBufferObjectSet* getGLBufferObjectSet(const BufferObjectProfile& profile);
366 void newFrame(osg::FrameStamp* fs);
368 void reportStats(std::ostream& out);
369 void recomputeStats(std::ostream& out) const;
371 unsigned int& getFrameNumber() { return _frameNumber; }
372 unsigned int& getNumberFrames() { return _numFrames; }
374 unsigned int& getNumberDeleted() { return _numDeleted; }
375 double& getDeleteTime() { return _deleteTime; }
377 unsigned int& getNumberGenerated() { return _numGenerated; }
378 double& getGenerateTime() { return _generateTime; }
380 unsigned int& getNumberApplied() { return _numApplied; }
381 double& getApplyTime() { return _applyTime; }
385 virtual ~GLBufferObjectManager();
387 typedef std::map< BufferObjectProfile, osg::ref_ptr<GLBufferObjectSet> > GLBufferObjectSetMap;
389 unsigned int _numActiveGLBufferObjects;
390 unsigned int _numOrphanedGLBufferObjects;
391 unsigned int _currGLBufferObjectPoolSize;
392 unsigned int _maxGLBufferObjectPoolSize;
393 GLBufferObjectSetMap _glBufferObjectSetMap;
395 unsigned int _frameNumber;
397 unsigned int _numFrames;
398 unsigned int _numDeleted;
401 unsigned int _numGenerated;
402 double _generateTime;
404 unsigned int _numApplied;
410class OSG_EXPORT BufferObject : public Object
416 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
417 BufferObject(const BufferObject& bo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
419 virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferObject*>(obj)!=NULL; }
420 virtual const char* libraryName() const { return "osg"; }
421 virtual const char* className() const { return "BufferObject"; }
423 void setTarget(GLenum target) { _profile._target = target; }
424 GLenum getTarget() const { return _profile._target; }
426 /** Set what type of usage the buffer object will have. Options are:
427 * GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
428 * GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
429 * GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY.
431 void setUsage(GLenum usage) { _profile._usage = usage; }
433 /** Get the type of usage the buffer object has been set up for.*/
434 GLenum getUsage() const { return _profile._usage; }
436 BufferObjectProfile& getProfile() { return _profile; }
437 const BufferObjectProfile& getProfile() const { return _profile; }
440 /** Set whether the BufferObject should use a GLBufferObject just for copying the BufferData and release it immediately so that it may be reused.*/
441 void setCopyDataAndReleaseGLBufferObject(bool copyAndRelease) { _copyDataAndReleaseGLBufferObject = copyAndRelease; }
443 /** Get whether the BufferObject should use a GLBufferObject just for copying the BufferData and release it immediately.*/
444 bool getCopyDataAndReleaseGLBufferObject() const { return _copyDataAndReleaseGLBufferObject; }
449 /** Resize any per context GLObject buffers to specified size. */
450 virtual void resizeGLObjectBuffers(unsigned int maxSize);
452 /** If State is non-zero, this function releases OpenGL objects for
453 * the specified graphics context. Otherwise, releases OpenGL objects
454 * for all graphics contexts. */
455 void releaseGLObjects(State* state=0) const;
457 unsigned int addBufferData(BufferData* bd);
458 void removeBufferData(unsigned int index);
459 void removeBufferData(BufferData* bd);
461 void setBufferData(unsigned int index, BufferData* bd);
462 BufferData* getBufferData(unsigned int index) { return _bufferDataList[index]; }
463 const BufferData* getBufferData(unsigned int index) const { return _bufferDataList[index]; }
465 unsigned int getNumBufferData() const { return static_cast<unsigned int>(_bufferDataList.size()); }
467 void setGLBufferObject(unsigned int contextID, GLBufferObject* glbo) { _glBufferObjects[contextID] = glbo; }
469 GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _glBufferObjects[contextID].get(); }
471 GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const;
473 unsigned int computeRequiredBufferSize() const;
475 /** deprecated, provided for backwards compatibility.*/
476 static void deleteBufferObject(unsigned int contextID,GLuint globj);
482 typedef std::vector< BufferData* > BufferDataList;
483 typedef osg::buffered_object< osg::ref_ptr<GLBufferObject> > GLBufferObjects;
485 BufferObjectProfile _profile;
487 bool _copyDataAndReleaseGLBufferObject;
489 BufferDataList _bufferDataList;
491 mutable GLBufferObjects _glBufferObjects;
494class OSG_EXPORT BufferData : public Object
504 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
505 BufferData(const BufferData& bd,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
506 osg::Object(bd,copyop),
509 _modifiedCallback(bd._modifiedCallback),
512 virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferData*>(obj)!=NULL; }
513 virtual const char* libraryName() const { return "osg"; }
514 virtual const char* className() const { return "BufferData"; }
516 virtual const GLvoid* getDataPointer() const = 0;
517 virtual unsigned int getTotalDataSize() const = 0;
519 virtual osg::Array* asArray() { return 0; }
520 virtual const osg::Array* asArray() const { return 0; }
522 virtual osg::PrimitiveSet* asPrimitiveSet() { return 0; }
523 virtual const osg::PrimitiveSet* asPrimitiveSet() const { return 0; }
525 virtual osg::Image* asImage() { return 0; }
526 virtual const osg::Image* asImage() const { return 0; }
528 void setBufferObject(BufferObject* bufferObject);
529 BufferObject* getBufferObject() { return _bufferObject.get(); }
530 const BufferObject* getBufferObject() const { return _bufferObject.get(); }
532 void setBufferIndex(unsigned int index) { _bufferIndex = index; }
533 unsigned int getBufferIndex() const { return _bufferIndex; }
535 GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getGLBufferObject(contextID) : 0; }
536 GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getOrCreateGLBufferObject(contextID) : 0; }
538 struct ModifiedCallback : public virtual osg::Object
540 ModifiedCallback() {}
542 ModifiedCallback(const ModifiedCallback& org, const CopyOp& copyop) :
543 Object(org, copyop) {}
545 META_Object(osg,ModifiedCallback);
547 virtual void modified(BufferData* /*bufferData*/) const {}
550 void setModifiedCallback(ModifiedCallback* md) { _modifiedCallback = md; }
551 ModifiedCallback* getModifiedCallback() { return _modifiedCallback.get(); }
552 const ModifiedCallback* getModifiedCallback() const { return _modifiedCallback.get(); }
554 /** Dirty the primitive, which increments the modified count, to force buffer objects to update.
555 * If a ModifiedCallback is attached to this BufferData then the callback is called prior to the bufferObject's dirty is called. */
559 if (_modifiedCallback.valid()) _modifiedCallback->modified(this);
560 if (_bufferObject.valid()) _bufferObject->dirty();
563 /** Set the modified count value.*/
564 inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
566 /** Get modified count value.*/
567 inline unsigned int getModifiedCount() const { return _modifiedCount; }
569 /** Resize any per context GLObject buffers to specified size. */
570 virtual void resizeGLObjectBuffers(unsigned int maxSize);
572 /** If State is non-zero, this function releases OpenGL objects for
573 * the specified graphics context. Otherwise, releases OpenGL objects
574 * for all graphics contexts. */
575 void releaseGLObjects(State* state=0) const;
577 unsigned int getNumClients() const { return _numClients; }
579 void addClient(osg::Object * /*client*/) { ++_numClients; }
581 void removeClient(osg::Object * /*client*/) { --_numClients; }
585 virtual ~BufferData();
587 unsigned int _modifiedCount;
589 unsigned int _bufferIndex;
590 osg::ref_ptr<BufferObject> _bufferObject;
591 osg::ref_ptr<ModifiedCallback> _modifiedCallback;
593 unsigned int _numClients;
598class OSG_EXPORT VertexBufferObject : public BufferObject
602 VertexBufferObject();
604 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
605 VertexBufferObject(const VertexBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
607 META_Object(osg,VertexBufferObject);
609 unsigned int addArray(osg::Array* array);
610 void removeArray(osg::Array* array);
612 void setArray(unsigned int i, Array* array);
613 Array* getArray(unsigned int i);
614 const Array* getArray(unsigned int i) const;
617 virtual ~VertexBufferObject();
621class OSG_EXPORT ElementBufferObject : public BufferObject
625 ElementBufferObject();
627 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
628 ElementBufferObject(const ElementBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
630 META_Object(osg,ElementBufferObject);
632 unsigned int addDrawElements(osg::DrawElements* PrimitiveSet);
633 void removeDrawElements(osg::DrawElements* PrimitiveSet);
635 void setDrawElements(unsigned int i, DrawElements* PrimitiveSet);
636 DrawElements* getDrawElements(unsigned int i);
637 const DrawElements* getDrawElements(unsigned int i) const;
641 virtual ~ElementBufferObject();
644class OSG_EXPORT DrawIndirectBufferObject : public BufferObject
648 DrawIndirectBufferObject();
650 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
651 DrawIndirectBufferObject(const DrawIndirectBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
653 META_Object(osg,DrawIndirectBufferObject);
655 unsigned int addArray(osg::Array* array);
656 void removeArray(osg::Array* array);
658 void setArray(unsigned int i, Array* array);
659 Array* getArray(unsigned int i);
660 const Array* getArray(unsigned int i) const;
663 virtual ~DrawIndirectBufferObject();
667class OSG_EXPORT PixelBufferObject : public BufferObject
671 PixelBufferObject(osg::Image* image=0);
673 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
674 PixelBufferObject(const PixelBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
676 META_Object(osg,PixelBufferObject);
678 void setImage(osg::Image* image);
681 const Image* getImage() const;
683 bool isPBOSupported(unsigned int contextID) const { return _glBufferObjects[contextID]->isPBOSupported(); }
687 virtual ~PixelBufferObject();
691 * This object represent a general class of pixel buffer objects,
692 * which are capable of allocating buffer object (memory)
693 * on the GPU. The memory can then be used either for CPU-GPU
694 * pixel transfer or directly for GPU-GPU transfer, without CPU intervention.
696class OSG_EXPORT PixelDataBufferObject : public BufferObject
699 PixelDataBufferObject();
700 PixelDataBufferObject(const PixelDataBufferObject& pbo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
702 META_Object(osg, PixelDataBufferObject);
704 //! Set new size of the buffer object. This will reallocate the memory on the next compile
705 inline void setDataSize(unsigned int size) { _profile._size = size; dirty(); }
707 //! Get data size of the used buffer
708 inline unsigned int getDataSize() const { return _profile._size; }
710 //! Compile the buffer (reallocate the memory if buffer is dirty)
711 virtual void compileBuffer(State& state) const;
713 //! Bind the buffer in read mode, which means that data can be downloaded from the buffer (note: GL_PIXEL_UNPACK_BUFFER_ARB)
714 virtual void bindBufferInReadMode(State& state);
716 //! Bind the buffer in write mode, which means following OpenGL instructions will write data into the buffer (note: GL_PIXEL_PACK_BUFFER_ARB)
717 virtual void bindBufferInWriteMode(State& state);
719 //! Unbind the buffer
720 virtual void unbindBuffer(unsigned int contextID) const;
722 /** Resize any per context GLObject buffers to specified size. */
723 virtual void resizeGLObjectBuffers(unsigned int maxSize);
727 //! A normal mode of this data buffer
730 //! Buffer is in read mode (@see bindBufferInReadMode)
733 //! Buffer is in write mode (@see bindBufferInWriteMode)
737 Mode getMode(unsigned int contextID) const { return (Mode)_mode[contextID]; }
741 virtual ~PixelDataBufferObject();
743 typedef osg::buffered_value<unsigned int> ModeList;
745 mutable ModeList _mode;
750class OSG_EXPORT UniformBufferObject : public BufferObject
753 UniformBufferObject();
754 UniformBufferObject(const UniformBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
755 META_Object(osg, UniformBufferObject);
757 virtual ~UniformBufferObject();
760class OSG_EXPORT AtomicCounterBufferObject : public BufferObject
763 AtomicCounterBufferObject();
764 AtomicCounterBufferObject(const AtomicCounterBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
765 META_Object(osg, AtomicCounterBufferObject);
768 virtual ~AtomicCounterBufferObject();
771inline void GLBufferObject::bindBuffer()
773 _extensions->glBindBuffer(_profile._target,_glObjectID);
774 if (_set) _set->moveToBack(this);
778class OSG_EXPORT ShaderStorageBufferObject : public BufferObject
782 ShaderStorageBufferObject();
783 ShaderStorageBufferObject(const ShaderStorageBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
784 META_Object(osg, ShaderStorageBufferObject);
786 virtual ~ShaderStorageBufferObject();