BufferObject 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. * Copyright (C) 2012 David Callu
  3. *
  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.
  8. *
  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.
  13. */
  14. #ifndef OSG_BUFFEROBJECT
  15. #define OSG_BUFFEROBJECT 1
  16. #include <osg/GL>
  17. #include <osg/GLExtensions>
  18. #include <osg/Object>
  19. #include <osg/buffered_value>
  20. #include <osg/FrameStamp>
  21. #include <osg/GLObjects>
  22. #include <iosfwd>
  23. #include <list>
  24. #include <map>
  25. #ifndef GL_ARB_vertex_buffer_object
  26. #define GL_ARRAY_BUFFER_ARB 0x8892
  27. #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
  28. #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
  29. #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
  30. #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
  31. #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
  32. #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
  33. #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
  34. #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
  35. #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
  36. #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
  37. #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
  38. #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
  39. #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
  40. #define GL_STREAM_DRAW_ARB 0x88E0
  41. #define GL_STREAM_READ_ARB 0x88E1
  42. #define GL_STREAM_COPY_ARB 0x88E2
  43. #define GL_STATIC_DRAW_ARB 0x88E4
  44. #define GL_STATIC_READ_ARB 0x88E5
  45. #define GL_STATIC_COPY_ARB 0x88E6
  46. #define GL_DYNAMIC_DRAW_ARB 0x88E8
  47. #define GL_DYNAMIC_READ_ARB 0x88E9
  48. #define GL_DYNAMIC_COPY_ARB 0x88EA
  49. #define GL_READ_ONLY_ARB 0x88B8
  50. #define GL_WRITE_ONLY_ARB 0x88B9
  51. #define GL_READ_WRITE_ARB 0x88BA
  52. #define GL_BUFFER_SIZE_ARB 0x8764
  53. #define GL_BUFFER_USAGE_ARB 0x8765
  54. #define GL_BUFFER_ACCESS_ARB 0x88BB
  55. #define GL_BUFFER_MAPPED_ARB 0x88BC
  56. #define GL_BUFFER_MAP_POINTER_ARB 0x88BD
  57. #endif
  58. #ifndef GL_VERSION_1_5
  59. #define GL_STREAM_DRAW 0x88E0
  60. #define GL_STREAM_READ 0x88E1
  61. #define GL_STREAM_COPY 0x88E2
  62. #define GL_STATIC_DRAW 0x88E4
  63. #define GL_STATIC_READ 0x88E5
  64. #define GL_STATIC_COPY 0x88E6
  65. #define GL_DYNAMIC_DRAW 0x88E8
  66. #define GL_DYNAMIC_READ 0x88E9
  67. #define GL_DYNAMIC_COPY 0x88EA
  68. #endif
  69. #ifndef GL_VERSION_2_1
  70. #define GL_PIXEL_PACK_BUFFER 0x88EB
  71. #define GL_PIXEL_UNPACK_BUFFER 0x88EC
  72. #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
  73. #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
  74. #endif
  75. #ifndef GL_ARB_pixel_buffer_object
  76. #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
  77. #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
  78. #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
  79. #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
  80. #endif
  81. namespace osg
  82. {
  83. class State;
  84. class BufferData;
  85. class BufferObject;
  86. class BufferObjectProfile
  87. {
  88. public:
  89. BufferObjectProfile():
  90. _target(0),
  91. _usage(0),
  92. _size(0) {}
  93. BufferObjectProfile(GLenum target, GLenum usage, unsigned int size):
  94. _target(target),
  95. _usage(usage),
  96. _size(size) {}
  97. BufferObjectProfile(const BufferObjectProfile& bpo):
  98. _target(bpo._target),
  99. _usage(bpo._usage),
  100. _size(bpo._size) {}
  101. bool operator < (const BufferObjectProfile& rhs) const
  102. {
  103. if (_target < rhs._target) return true;
  104. else if (_target > rhs._target) return false;
  105. if (_usage < rhs._usage) return true;
  106. else if (_usage > rhs._usage) return false;
  107. return _size < rhs._size;
  108. }
  109. bool operator == (const BufferObjectProfile& rhs) const
  110. {
  111. return (_target == rhs._target) &&
  112. (_usage == rhs._usage) &&
  113. (_size == rhs._size);
  114. }
  115. void setProfile(GLenum target, GLenum usage, unsigned int size)
  116. {
  117. _target = target;
  118. _usage = usage;
  119. _size = size;
  120. }
  121. BufferObjectProfile& operator = (const BufferObjectProfile& rhs)
  122. {
  123. _target = rhs._target;
  124. _usage = rhs._usage;
  125. _size = rhs._size;
  126. return *this;
  127. }
  128. GLenum _target;
  129. GLenum _usage;
  130. GLenum _size;
  131. };
  132. // forward declare
  133. class GLBufferObjectSet;
  134. class GLBufferObjectManager;
  135. inline unsigned int computeBufferAlignment(unsigned int pos, unsigned int bufferAlignment)
  136. {
  137. if (bufferAlignment<2) return pos;
  138. if ((pos%bufferAlignment)==0) return pos;
  139. return ((pos/bufferAlignment)+1)*bufferAlignment;
  140. }
  141. class OSG_EXPORT GLBufferObject : public GraphicsObject
  142. {
  143. public:
  144. GLBufferObject(unsigned int contextID, BufferObject* bufferObject, unsigned int glObjectID=0);
  145. void setProfile(const BufferObjectProfile& profile) { _profile = profile; }
  146. const BufferObjectProfile& getProfile() const { return _profile; }
  147. void setBufferObject(BufferObject* bufferObject);
  148. BufferObject* getBufferObject() { return _bufferObject; }
  149. struct BufferEntry
  150. {
  151. BufferEntry(): numRead(0), modifiedCount(0),dataSize(0),offset(0),dataSource(0) {}
  152. BufferEntry(const BufferEntry& rhs):
  153. numRead(rhs.numRead),
  154. modifiedCount(rhs.modifiedCount),
  155. dataSize(rhs.dataSize),
  156. offset(rhs.offset),
  157. dataSource(rhs.dataSource) {}
  158. BufferEntry& operator = (const BufferEntry& rhs)
  159. {
  160. if (&rhs==this) return *this;
  161. numRead = rhs.numRead;
  162. modifiedCount = rhs.modifiedCount;
  163. dataSize = rhs.dataSize;
  164. offset = rhs.offset;
  165. dataSource = rhs.dataSource;
  166. return *this;
  167. }
  168. unsigned int getNumClients() const;
  169. unsigned int numRead;
  170. unsigned int modifiedCount;
  171. unsigned int dataSize;
  172. unsigned int offset;
  173. BufferData* dataSource;
  174. };
  175. inline unsigned int getContextID() const { return _contextID; }
  176. inline GLuint& getGLObjectID() { return _glObjectID; }
  177. inline GLuint getGLObjectID() const { return _glObjectID; }
  178. inline GLsizeiptr getOffset(unsigned int i) const { return _bufferEntries[i].offset; }
  179. inline void bindBuffer();
  180. inline void unbindBuffer()
  181. {
  182. _extensions->glBindBuffer(_profile._target,0);
  183. }
  184. /** release GLBufferObject to the orphan list to be reused or deleted.*/
  185. void release();
  186. inline bool isDirty() const { return _dirty; }
  187. void dirty() { _dirty = true; }
  188. void clear();
  189. void compileBuffer();
  190. void deleteGLObject();
  191. void assign(BufferObject* bufferObject);
  192. bool isPBOSupported() const { return _extensions->isPBOSupported; }
  193. bool hasAllBufferDataBeenRead() const;
  194. void setBufferDataHasBeenRead(const osg::BufferData* bd);
  195. protected:
  196. virtual ~GLBufferObject();
  197. unsigned int computeBufferAlignment(unsigned int pos, unsigned int bufferAlignment) const
  198. {
  199. return osg::computeBufferAlignment(pos, bufferAlignment);
  200. }
  201. unsigned int _contextID;
  202. GLuint _glObjectID;
  203. BufferObjectProfile _profile;
  204. unsigned int _allocatedSize;
  205. bool _dirty;
  206. typedef std::vector<BufferEntry> BufferEntries;
  207. BufferEntries _bufferEntries;
  208. BufferObject* _bufferObject;
  209. public:
  210. GLBufferObjectSet* _set;
  211. GLBufferObject* _previous;
  212. GLBufferObject* _next;
  213. unsigned int _frameLastUsed;
  214. public:
  215. GLExtensions* _extensions;
  216. };
  217. typedef std::list< ref_ptr<GLBufferObject> > GLBufferObjectList;
  218. class OSG_EXPORT GLBufferObjectSet : public Referenced
  219. {
  220. public:
  221. GLBufferObjectSet(GLBufferObjectManager* parent, const BufferObjectProfile& profile);
  222. const BufferObjectProfile& getProfile() const { return _profile; }
  223. void handlePendingOrphandedGLBufferObjects();
  224. void deleteAllGLBufferObjects();
  225. void discardAllGLBufferObjects();
  226. void flushAllDeletedGLBufferObjects();
  227. void discardAllDeletedGLBufferObjects();
  228. void flushDeletedGLBufferObjects(double currentTime, double& availableTime);
  229. osg::ref_ptr<GLBufferObject> takeFromOrphans(BufferObject* bufferObject);
  230. osg::ref_ptr<GLBufferObject> takeOrGenerate(BufferObject* bufferObject);
  231. void moveToBack(GLBufferObject* to);
  232. void addToBack(GLBufferObject* to);
  233. void orphan(GLBufferObject* to);
  234. void remove(GLBufferObject* to);
  235. void moveToSet(GLBufferObject* to, GLBufferObjectSet* set);
  236. unsigned int size() const { return _profile._size * _numOfGLBufferObjects; }
  237. bool makeSpace(unsigned int& size);
  238. bool checkConsistency() const;
  239. GLBufferObjectManager* getParent() { return _parent; }
  240. unsigned int computeNumGLBufferObjectsInList() const;
  241. unsigned int getNumOfGLBufferObjects() const { return _numOfGLBufferObjects; }
  242. unsigned int getNumOrphans() const { return static_cast<unsigned int>(_orphanedGLBufferObjects.size()); }
  243. unsigned int getNumPendingOrphans() const { return static_cast<unsigned int>(_pendingOrphanedGLBufferObjects.size()); }
  244. protected:
  245. virtual ~GLBufferObjectSet();
  246. OpenThreads::Mutex _mutex;
  247. GLBufferObjectManager* _parent;
  248. unsigned int _contextID;
  249. BufferObjectProfile _profile;
  250. unsigned int _numOfGLBufferObjects;
  251. GLBufferObjectList _orphanedGLBufferObjects;
  252. GLBufferObjectList _pendingOrphanedGLBufferObjects;
  253. GLBufferObject* _head;
  254. GLBufferObject* _tail;
  255. };
  256. class OSG_EXPORT GLBufferObjectManager : public GraphicsObjectManager
  257. {
  258. public:
  259. GLBufferObjectManager(unsigned int contextID);
  260. void setNumberActiveGLBufferObjects(unsigned int size) { _numActiveGLBufferObjects = size; }
  261. unsigned int& getNumberActiveGLBufferObjects() { return _numActiveGLBufferObjects; }
  262. unsigned int getNumberActiveGLBufferObjects() const { return _numActiveGLBufferObjects; }
  263. void setNumberOrphanedGLBufferObjects(unsigned int size) { _numOrphanedGLBufferObjects = size; }
  264. unsigned int& getNumberOrphanedGLBufferObjects() { return _numOrphanedGLBufferObjects; }
  265. unsigned int getNumberOrphanedGLBufferObjects() const { return _numOrphanedGLBufferObjects; }
  266. void setCurrGLBufferObjectPoolSize(unsigned int size) { _currGLBufferObjectPoolSize = size; }
  267. unsigned int& getCurrGLBufferObjectPoolSize() { return _currGLBufferObjectPoolSize; }
  268. unsigned int getCurrGLBufferObjectPoolSize() const { return _currGLBufferObjectPoolSize; }
  269. void setMaxGLBufferObjectPoolSize(unsigned int size);
  270. unsigned int getMaxGLBufferObjectPoolSize() const { return _maxGLBufferObjectPoolSize; }
  271. bool hasSpace(unsigned int size) const { return (_currGLBufferObjectPoolSize+size)<=_maxGLBufferObjectPoolSize; }
  272. bool makeSpace(unsigned int size);
  273. osg::ref_ptr<GLBufferObject> generateGLBufferObject(const osg::BufferObject* bufferObject);
  274. void handlePendingOrphandedGLBufferObjects();
  275. void deleteAllGLObjects();
  276. void discardAllGLObjects();
  277. void flushAllDeletedGLObjects();
  278. void discardAllDeletedGLObjects();
  279. void flushDeletedGLObjects(double currentTime, double& availableTime);
  280. GLBufferObjectSet* getGLBufferObjectSet(const BufferObjectProfile& profile);
  281. void newFrame(osg::FrameStamp* fs);
  282. void resetStats();
  283. void reportStats(std::ostream& out);
  284. void recomputeStats(std::ostream& out) const;
  285. unsigned int& getFrameNumber() { return _frameNumber; }
  286. unsigned int& getNumberFrames() { return _numFrames; }
  287. unsigned int& getNumberDeleted() { return _numDeleted; }
  288. double& getDeleteTime() { return _deleteTime; }
  289. unsigned int& getNumberGenerated() { return _numGenerated; }
  290. double& getGenerateTime() { return _generateTime; }
  291. unsigned int& getNumberApplied() { return _numApplied; }
  292. double& getApplyTime() { return _applyTime; }
  293. protected:
  294. virtual ~GLBufferObjectManager();
  295. typedef std::map< BufferObjectProfile, osg::ref_ptr<GLBufferObjectSet> > GLBufferObjectSetMap;
  296. unsigned int _numActiveGLBufferObjects;
  297. unsigned int _numOrphanedGLBufferObjects;
  298. unsigned int _currGLBufferObjectPoolSize;
  299. unsigned int _maxGLBufferObjectPoolSize;
  300. GLBufferObjectSetMap _glBufferObjectSetMap;
  301. unsigned int _frameNumber;
  302. unsigned int _numFrames;
  303. unsigned int _numDeleted;
  304. double _deleteTime;
  305. unsigned int _numGenerated;
  306. double _generateTime;
  307. unsigned int _numApplied;
  308. double _applyTime;
  309. };
  310. class OSG_EXPORT BufferObject : public Object
  311. {
  312. public:
  313. BufferObject();
  314. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  315. BufferObject(const BufferObject& bo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  316. virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferObject*>(obj)!=NULL; }
  317. virtual const char* libraryName() const { return "osg"; }
  318. virtual const char* className() const { return "BufferObject"; }
  319. void setTarget(GLenum target) { _profile._target = target; }
  320. GLenum getTarget() const { return _profile._target; }
  321. /** Set what type of usage the buffer object will have. Options are:
  322. * GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
  323. * GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
  324. * GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY.
  325. */
  326. void setUsage(GLenum usage) { _profile._usage = usage; }
  327. /** Get the type of usage the buffer object has been set up for.*/
  328. GLenum getUsage() const { return _profile._usage; }
  329. BufferObjectProfile& getProfile() { return _profile; }
  330. const BufferObjectProfile& getProfile() const { return _profile; }
  331. /** Set whether the BufferObject should use a GLBufferObject just for copying the BufferData and release it immediately so that it may be reused.*/
  332. void setCopyDataAndReleaseGLBufferObject(bool copyAndRelease) { _copyDataAndReleaseGLBufferObject = copyAndRelease; }
  333. /** Get whether the BufferObject should use a GLBufferObject just for copying the BufferData and release it immediately.*/
  334. bool getCopyDataAndReleaseGLBufferObject() const { return _copyDataAndReleaseGLBufferObject; }
  335. void dirty();
  336. /** Resize any per context GLObject buffers to specified size. */
  337. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  338. /** If State is non-zero, this function releases OpenGL objects for
  339. * the specified graphics context. Otherwise, releases OpenGL objects
  340. * for all graphics contexts. */
  341. void releaseGLObjects(State* state=0) const;
  342. unsigned int addBufferData(BufferData* bd);
  343. void removeBufferData(unsigned int index);
  344. void removeBufferData(BufferData* bd);
  345. void setBufferData(unsigned int index, BufferData* bd);
  346. BufferData* getBufferData(unsigned int index) { return _bufferDataList[index]; }
  347. const BufferData* getBufferData(unsigned int index) const { return _bufferDataList[index]; }
  348. unsigned int getNumBufferData() const { return static_cast<unsigned int>(_bufferDataList.size()); }
  349. void setGLBufferObject(unsigned int contextID, GLBufferObject* glbo) { _glBufferObjects[contextID] = glbo; }
  350. GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _glBufferObjects[contextID].get(); }
  351. GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const;
  352. unsigned int computeRequiredBufferSize() const;
  353. /** deprecated, provided for backwards compatibility.*/
  354. static void deleteBufferObject(unsigned int contextID,GLuint globj);
  355. protected:
  356. ~BufferObject();
  357. typedef std::vector< BufferData* > BufferDataList;
  358. typedef osg::buffered_object< osg::ref_ptr<GLBufferObject> > GLBufferObjects;
  359. BufferObjectProfile _profile;
  360. bool _copyDataAndReleaseGLBufferObject;
  361. BufferDataList _bufferDataList;
  362. mutable GLBufferObjects _glBufferObjects;
  363. };
  364. class OSG_EXPORT BufferData : public Object
  365. {
  366. public:
  367. BufferData():
  368. Object(true),
  369. _modifiedCount(0),
  370. _bufferIndex(0),
  371. _numClients(0) {}
  372. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  373. BufferData(const BufferData& bd,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
  374. osg::Object(bd,copyop),
  375. _modifiedCount(0),
  376. _bufferIndex(0),
  377. _modifiedCallback(bd._modifiedCallback),
  378. _numClients(0) {}
  379. virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferData*>(obj)!=NULL; }
  380. virtual const char* libraryName() const { return "osg"; }
  381. virtual const char* className() const { return "BufferData"; }
  382. virtual const GLvoid* getDataPointer() const = 0;
  383. virtual unsigned int getTotalDataSize() const = 0;
  384. virtual osg::Array* asArray() { return 0; }
  385. virtual const osg::Array* asArray() const { return 0; }
  386. virtual osg::PrimitiveSet* asPrimitiveSet() { return 0; }
  387. virtual const osg::PrimitiveSet* asPrimitiveSet() const { return 0; }
  388. virtual osg::Image* asImage() { return 0; }
  389. virtual const osg::Image* asImage() const { return 0; }
  390. void setBufferObject(BufferObject* bufferObject);
  391. BufferObject* getBufferObject() { return _bufferObject.get(); }
  392. const BufferObject* getBufferObject() const { return _bufferObject.get(); }
  393. void setBufferIndex(unsigned int index) { _bufferIndex = index; }
  394. unsigned int getBufferIndex() const { return _bufferIndex; }
  395. GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getGLBufferObject(contextID) : 0; }
  396. GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const { return _bufferObject.valid() ? _bufferObject->getOrCreateGLBufferObject(contextID) : 0; }
  397. struct ModifiedCallback : public virtual osg::Object
  398. {
  399. ModifiedCallback() {}
  400. ModifiedCallback(const ModifiedCallback& org, const CopyOp& copyop) :
  401. Object(org, copyop) {}
  402. META_Object(osg,ModifiedCallback);
  403. virtual void modified(BufferData* /*bufferData*/) const {}
  404. };
  405. void setModifiedCallback(ModifiedCallback* md) { _modifiedCallback = md; }
  406. ModifiedCallback* getModifiedCallback() { return _modifiedCallback.get(); }
  407. const ModifiedCallback* getModifiedCallback() const { return _modifiedCallback.get(); }
  408. /** Dirty the primitive, which increments the modified count, to force buffer objects to update.
  409. * If a ModifiedCallback is attached to this BufferData then the callback is called prior to the bufferObject's dirty is called. */
  410. inline void dirty()
  411. {
  412. ++_modifiedCount;
  413. if (_modifiedCallback.valid()) _modifiedCallback->modified(this);
  414. if (_bufferObject.valid()) _bufferObject->dirty();
  415. }
  416. /** Set the modified count value.*/
  417. inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
  418. /** Get modified count value.*/
  419. inline unsigned int getModifiedCount() const { return _modifiedCount; }
  420. /** Resize any per context GLObject buffers to specified size. */
  421. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  422. /** If State is non-zero, this function releases OpenGL objects for
  423. * the specified graphics context. Otherwise, releases OpenGL objects
  424. * for all graphics contexts. */
  425. void releaseGLObjects(State* state=0) const;
  426. unsigned int getNumClients() const { return _numClients; }
  427. void addClient(osg::Object * /*client*/) { ++_numClients; }
  428. void removeClient(osg::Object * /*client*/) { --_numClients; }
  429. protected:
  430. virtual ~BufferData();
  431. unsigned int _modifiedCount;
  432. unsigned int _bufferIndex;
  433. osg::ref_ptr<BufferObject> _bufferObject;
  434. osg::ref_ptr<ModifiedCallback> _modifiedCallback;
  435. unsigned int _numClients;
  436. };
  437. class Array;
  438. class OSG_EXPORT VertexBufferObject : public BufferObject
  439. {
  440. public:
  441. VertexBufferObject();
  442. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  443. VertexBufferObject(const VertexBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  444. META_Object(osg,VertexBufferObject);
  445. unsigned int addArray(osg::Array* array);
  446. void removeArray(osg::Array* array);
  447. void setArray(unsigned int i, Array* array);
  448. Array* getArray(unsigned int i);
  449. const Array* getArray(unsigned int i) const;
  450. protected:
  451. virtual ~VertexBufferObject();
  452. };
  453. class DrawElements;
  454. class OSG_EXPORT ElementBufferObject : public BufferObject
  455. {
  456. public:
  457. ElementBufferObject();
  458. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  459. ElementBufferObject(const ElementBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  460. META_Object(osg,ElementBufferObject);
  461. unsigned int addDrawElements(osg::DrawElements* PrimitiveSet);
  462. void removeDrawElements(osg::DrawElements* PrimitiveSet);
  463. void setDrawElements(unsigned int i, DrawElements* PrimitiveSet);
  464. DrawElements* getDrawElements(unsigned int i);
  465. const DrawElements* getDrawElements(unsigned int i) const;
  466. protected:
  467. virtual ~ElementBufferObject();
  468. };
  469. class OSG_EXPORT DrawIndirectBufferObject : public BufferObject
  470. {
  471. public:
  472. DrawIndirectBufferObject();
  473. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  474. DrawIndirectBufferObject(const DrawIndirectBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  475. META_Object(osg,DrawIndirectBufferObject);
  476. unsigned int addArray(osg::Array* array);
  477. void removeArray(osg::Array* array);
  478. void setArray(unsigned int i, Array* array);
  479. Array* getArray(unsigned int i);
  480. const Array* getArray(unsigned int i) const;
  481. protected:
  482. virtual ~DrawIndirectBufferObject();
  483. };
  484. class Image;
  485. class OSG_EXPORT PixelBufferObject : public BufferObject
  486. {
  487. public:
  488. PixelBufferObject(osg::Image* image=0);
  489. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  490. PixelBufferObject(const PixelBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  491. META_Object(osg,PixelBufferObject);
  492. void setImage(osg::Image* image);
  493. Image* getImage();
  494. const Image* getImage() const;
  495. bool isPBOSupported(unsigned int contextID) const { return _glBufferObjects[contextID]->isPBOSupported(); }
  496. protected:
  497. virtual ~PixelBufferObject();
  498. };
  499. /**
  500. * This object represent a general class of pixel buffer objects,
  501. * which are capable of allocating buffer object (memory)
  502. * on the GPU. The memory can then be used either for CPU-GPU
  503. * pixel transfer or directly for GPU-GPU transfer, without CPU intervention.
  504. **/
  505. class OSG_EXPORT PixelDataBufferObject : public BufferObject
  506. {
  507. public:
  508. PixelDataBufferObject();
  509. PixelDataBufferObject(const PixelDataBufferObject& pbo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  510. META_Object(osg, PixelDataBufferObject);
  511. //! Set new size of the buffer object. This will reallocate the memory on the next compile
  512. inline void setDataSize(unsigned int size) { _profile._size = size; dirty(); }
  513. //! Get data size of the used buffer
  514. inline unsigned int getDataSize() const { return _profile._size; }
  515. //! Compile the buffer (reallocate the memory if buffer is dirty)
  516. virtual void compileBuffer(State& state) const;
  517. //! Bind the buffer in read mode, which means that data can be downloaded from the buffer (note: GL_PIXEL_UNPACK_BUFFER_ARB)
  518. virtual void bindBufferInReadMode(State& state);
  519. //! Bind the buffer in write mode, which means following OpenGL instructions will write data into the buffer (note: GL_PIXEL_PACK_BUFFER_ARB)
  520. virtual void bindBufferInWriteMode(State& state);
  521. //! Unbind the buffer
  522. virtual void unbindBuffer(unsigned int contextID) const;
  523. /** Resize any per context GLObject buffers to specified size. */
  524. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  525. enum Mode
  526. {
  527. //! A normal mode of this data buffer
  528. NONE = 0,
  529. //! Buffer is in read mode (@see bindBufferInReadMode)
  530. READ = 1,
  531. //! Buffer is in write mode (@see bindBufferInWriteMode)
  532. WRITE = 2
  533. };
  534. Mode getMode(unsigned int contextID) const { return (Mode)_mode[contextID]; }
  535. protected:
  536. virtual ~PixelDataBufferObject();
  537. typedef osg::buffered_value<unsigned int> ModeList;
  538. mutable ModeList _mode;
  539. };
  540. class OSG_EXPORT UniformBufferObject : public BufferObject
  541. {
  542. public:
  543. UniformBufferObject();
  544. UniformBufferObject(const UniformBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  545. META_Object(osg, UniformBufferObject);
  546. protected:
  547. virtual ~UniformBufferObject();
  548. };
  549. class OSG_EXPORT AtomicCounterBufferObject : public BufferObject
  550. {
  551. public:
  552. AtomicCounterBufferObject();
  553. AtomicCounterBufferObject(const AtomicCounterBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  554. META_Object(osg, AtomicCounterBufferObject);
  555. protected:
  556. virtual ~AtomicCounterBufferObject();
  557. };
  558. inline void GLBufferObject::bindBuffer()
  559. {
  560. _extensions->glBindBuffer(_profile._target,_glObjectID);
  561. if (_set) _set->moveToBack(this);
  562. }
  563. class OSG_EXPORT ShaderStorageBufferObject : public BufferObject
  564. {
  565. public:
  566. ShaderStorageBufferObject();
  567. ShaderStorageBufferObject(const ShaderStorageBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
  568. META_Object(osg, ShaderStorageBufferObject);
  569. protected:
  570. virtual ~ShaderStorageBufferObject();
  571. };
  572. }
  573. #endif