VertexArrayState 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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. #ifndef OSG_VertexArrayState
  14. #define OSG_VertexArrayState 1
  15. #include <osg/Referenced>
  16. #include <osg/GLExtensions>
  17. #include <osg/Array>
  18. #include <osg/AttributeDispatchers>
  19. namespace osg {
  20. class OSG_EXPORT VertexArrayState : public osg::Referenced
  21. {
  22. public:
  23. VertexArrayState(osg::State* state);
  24. struct ArrayDispatch : public osg::Referenced
  25. {
  26. ArrayDispatch():
  27. array(0),
  28. modifiedCount(0xffffffff),
  29. active(false) {}
  30. virtual bool isVertexAttribDispatch() const { return false; }
  31. virtual const char* className() const = 0; // { return "ArrayDispatch"; }
  32. virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
  33. virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
  34. virtual void enable_and_dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
  35. virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
  36. virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
  37. virtual void dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
  38. virtual void disable(osg::State& /*state*/) {} // = 0;
  39. const osg::Array* array;
  40. unsigned int modifiedCount;
  41. bool active;
  42. };
  43. typedef std::vector< ref_ptr<ArrayDispatch> > ArrayDispatchList;
  44. void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
  45. GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
  46. inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
  47. {
  48. if (vbo->isDirty())
  49. {
  50. vbo->compileBuffer();
  51. _currentVBO = vbo;
  52. }
  53. else if (vbo != _currentVBO)
  54. {
  55. vbo->bindBuffer();
  56. _currentVBO = vbo;
  57. }
  58. }
  59. inline void unbindVertexBufferObject()
  60. {
  61. if (!_currentVBO) return;
  62. _ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
  63. _currentVBO = 0;
  64. }
  65. void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
  66. GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
  67. inline void bindElementBufferObject(osg::GLBufferObject* ebo)
  68. {
  69. if (ebo->isDirty())
  70. {
  71. ebo->compileBuffer();
  72. _currentEBO = ebo;
  73. }
  74. else if (ebo != _currentEBO)
  75. {
  76. ebo->bindBuffer();
  77. _currentEBO = ebo;
  78. }
  79. }
  80. inline void unbindElementBufferObject()
  81. {
  82. if (!_currentEBO) return;
  83. _ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
  84. _currentEBO = 0;
  85. }
  86. void resetBufferObjectPointers() { _currentVBO = 0; _currentEBO = 0; }
  87. bool correctArrayDispatchAssigned(const ArrayDispatch* ad);
  88. void assignAllDispatchers();
  89. void assignVertexArrayDispatcher();
  90. void assignNormalArrayDispatcher();
  91. void assignColorArrayDispatcher();
  92. void assignSecondaryColorArrayDispatcher();
  93. void assignFogCoordArrayDispatcher();
  94. void assignTexCoordArrayDispatcher(unsigned int numUnits);
  95. void assignVertexAttribArrayDispatcher(unsigned int numUnits);
  96. inline void setVertexBufferObjectSupported(bool flag) { _isVertexBufferObjectSupported = flag; }
  97. inline bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupported; }
  98. void setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array);
  99. void setArray(ArrayDispatch* vad, osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized);
  100. inline void disable(ArrayDispatch* vad, osg::State& state) { vad->disable(state); vad->array=0; vad->modifiedCount=0xffffffff; vad->active=false; }
  101. void setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer);
  102. inline void setVertexArray(osg::State& state, const osg::Array* array) { setArray(_vertexArray.get(), state, array); }
  103. inline void setVertexArray(osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE) { setArray(_vertexArray.get(), state, size, type, stride, ptr, normalized); }
  104. inline void disableVertexArray(osg::State& state) { disable(_vertexArray.get(), state); }
  105. inline void setNormalArray(osg::State& state, const osg::Array* array) { setArray(_normalArray.get(), state, array); }
  106. inline void setNormalArray(osg::State& state, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE ) { setArray(_normalArray.get(), state, 3, type, stride, ptr, normalized); }
  107. inline void disableNormalArray(osg::State& state) { disable(_normalArray.get(), state); }
  108. inline void setColorArray(osg::State& state, const osg::Array* array) { setArray(_colorArray.get(), state, array); }
  109. inline void setColorArray(osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_TRUE ) { setArray(_colorArray.get(), state, size, type, stride, ptr, normalized); }
  110. inline void disableColorArray(osg::State& state) { disable(_colorArray.get(), state); }
  111. inline void setSecondaryColorArray(osg::State& state, const osg::Array* array) { setArray(_secondaryColorArray.get(), state, array); }
  112. inline void disableSecondaryColorArray(osg::State& state) { disable(_secondaryColorArray.get(), state); }
  113. inline void setFogCoordArray(osg::State& state, const osg::Array* array) { setArray(_fogCoordArray.get(), state, array); }
  114. inline void disableFogCoordArray(osg::State& state) { disable(_fogCoordArray.get(), state); }
  115. inline void setTexCoordArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_texCoordArrays[unit].get(), state, array); }
  116. inline void setTexCoordArray(osg::State& state, unsigned int unit, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE ) { setArray(_texCoordArrays[unit].get(), state, size, type, stride, ptr, normalized); }
  117. inline void disableTexCoordArray(osg::State& state, unsigned int unit) { disable(_texCoordArrays[unit].get(),state); }
  118. inline void disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index);
  119. inline void setVertexAttribArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_vertexAttribArrays[unit].get(), state, array); }
  120. inline void disableVertexAttribArray(osg::State& state, unsigned int unit) { disable(_vertexAttribArrays[unit].get(), state); }
  121. inline void disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index);
  122. /** Mark all the vertex attributes as being disabled but leave the disabling till a later call to applyDisablingOfVertexAttributes.*/
  123. inline void lazyDisablingOfVertexAttributes();
  124. /** Disable all the vertex attributes that have been marked as to be disabled.*/
  125. inline void applyDisablingOfVertexAttributes(osg::State& state);
  126. // Verex Array Object methods.
  127. void generateVertexArrayObject();
  128. void deleteVertexArrayObject();
  129. GLuint getVertexArrayObject() const { return _vertexArrayObject; }
  130. void setRequiresSetArrays(bool flag) { _requiresSetArrays = flag; }
  131. bool getRequiresSetArrays() const { return _requiresSetArrays; }
  132. void dirty();
  133. void release();
  134. public:
  135. virtual ~VertexArrayState();
  136. // osg::GLBufferObject* getGLBufferObject(osg::Array* array);
  137. osg::State* _state;
  138. osg::ref_ptr<ObserverSet> _stateObserverSet;
  139. osg::ref_ptr<osg::GLExtensions> _ext;
  140. bool _isVertexBufferObjectSupported;
  141. GLuint _vertexArrayObject;
  142. osg::ref_ptr<ArrayDispatch> _vertexArray;
  143. osg::ref_ptr<ArrayDispatch> _normalArray;
  144. osg::ref_ptr<ArrayDispatch> _colorArray;
  145. osg::ref_ptr<ArrayDispatch> _secondaryColorArray;
  146. osg::ref_ptr<ArrayDispatch> _fogCoordArray;
  147. ArrayDispatchList _texCoordArrays;
  148. ArrayDispatchList _vertexAttribArrays;
  149. typedef std::vector<ArrayDispatch*> ActiveDispatchers;
  150. ActiveDispatchers _activeDispatchers;
  151. ActiveDispatchers _previous_activeDispatchers;
  152. GLBufferObject* _currentVBO;
  153. GLBufferObject* _currentEBO;
  154. bool _requiresSetArrays;
  155. };
  156. class OSG_EXPORT VertexArrayStateList
  157. {
  158. public:
  159. VertexArrayStateList();
  160. VertexArrayStateList& operator = (const VertexArrayStateList& rhs);
  161. inline void clear() { _array.clear(); }
  162. inline bool empty() const { return _array.empty(); }
  163. inline unsigned int size() const { return _array.size(); }
  164. inline void resize(unsigned int newSize) { _array.resize(newSize); }
  165. inline ref_ptr<VertexArrayState>& operator[] (unsigned int pos)
  166. {
  167. // automatically resize array.
  168. if (_array.size()<=pos)
  169. _array.resize(pos+1,0);
  170. return _array[pos];
  171. }
  172. inline const ref_ptr<VertexArrayState>& operator[] (unsigned int pos) const
  173. {
  174. // automatically resize array.
  175. if (_array.size()<=pos)
  176. _array.resize(pos+1,0);
  177. return _array[pos];
  178. }
  179. void assignAllDispatchers();
  180. void assignVertexArrayDispatcher();
  181. void assignNormalArrayDispatcher();
  182. void assignColorArrayDispatcher();
  183. void assignSecondaryColorArrayDispatcher();
  184. void assignFogCoordArrayDispatcher();
  185. void assignTexCoordArrayDispatcher(unsigned int numUnits);
  186. void assignVertexAttribArrayDispatcher(unsigned int numUnits);
  187. protected:
  188. typedef std::vector< osg::ref_ptr<VertexArrayState> > Array;
  189. mutable Array _array;
  190. };
  191. inline void VertexArrayState::lazyDisablingOfVertexAttributes()
  192. {
  193. _activeDispatchers.swap(_previous_activeDispatchers);
  194. _activeDispatchers.clear();
  195. for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
  196. itr != _previous_activeDispatchers.end();
  197. ++itr)
  198. {
  199. ArrayDispatch* ad = (*itr);
  200. // ad->array = 0;
  201. ad->active = false;
  202. }
  203. }
  204. inline void VertexArrayState::applyDisablingOfVertexAttributes(osg::State& state)
  205. {
  206. for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
  207. itr != _previous_activeDispatchers.end();
  208. ++itr)
  209. {
  210. ArrayDispatch* ad = (*itr);
  211. if (!ad->active)
  212. {
  213. ad->disable(state);
  214. ad->array = 0;
  215. ad->modifiedCount = 0xffffffff;
  216. }
  217. }
  218. _previous_activeDispatchers.clear();
  219. }
  220. inline void VertexArrayState::disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index)
  221. {
  222. for(unsigned int i=index; i<_texCoordArrays.size(); ++i)
  223. {
  224. disable(_texCoordArrays[i].get(), state);
  225. }
  226. }
  227. inline void VertexArrayState::disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index)
  228. {
  229. for(unsigned int i=index; i<_vertexAttribArrays.size(); ++i)
  230. {
  231. disable(_vertexAttribArrays[i].get(), state);
  232. }
  233. }
  234. }
  235. #endif