1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
14#ifndef OSG_VertexArrayState
15#define OSG_VertexArrayState 1
17#include <osg/Referenced>
18#include <osg/GLExtensions>
20#include <osg/AttributeDispatchers>
24class OSG_EXPORT VertexArrayState : public osg::Referenced
28 VertexArrayState(osg::State* state);
30 struct ArrayDispatch : public osg::Referenced
34 modifiedCount(0xffffffff),
37 virtual bool isVertexAttribDispatch() const { return false; }
39 virtual const char* className() const = 0; // { return "ArrayDispatch"; }
41 virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
43 virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
45 virtual void enable_and_dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
47 virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
49 virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
51 virtual void dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
53 virtual void disable(osg::State& /*state*/) {} // = 0;
55 const osg::Array* array;
56 unsigned int modifiedCount;
60 typedef std::vector< ref_ptr<ArrayDispatch> > ArrayDispatchList;
62 void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
63 GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
65 inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
72 else if (vbo != _currentVBO)
79 inline void unbindVertexBufferObject()
81 if (!_currentVBO) return;
82 _ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
87 void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
88 GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
90 inline void bindElementBufferObject(osg::GLBufferObject* ebo)
97 else if (ebo != _currentEBO)
104 inline void unbindElementBufferObject()
106 if (!_currentEBO) return;
107 _ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
111 void resetBufferObjectPointers() { _currentVBO = 0; _currentEBO = 0; }
113 bool correctArrayDispatchAssigned(const ArrayDispatch* ad);
115 void assignAllDispatchers();
117 void assignVertexArrayDispatcher();
118 void assignNormalArrayDispatcher();
119 void assignColorArrayDispatcher();
120 void assignSecondaryColorArrayDispatcher();
121 void assignFogCoordArrayDispatcher();
122 void assignTexCoordArrayDispatcher(unsigned int numUnits);
123 void assignVertexAttribArrayDispatcher(unsigned int numUnits);
125 inline void setVertexBufferObjectSupported(bool flag) { _isVertexBufferObjectSupported = flag; }
126 inline bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupported; }
128 void setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array);
129 void setArray(ArrayDispatch* vad, osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized);
131 inline void disable(ArrayDispatch* vad, osg::State& state) { vad->disable(state); vad->array=0; vad->modifiedCount=0xffffffff; vad->active=false; }
133 void setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer);
135 inline void setVertexArray(osg::State& state, const osg::Array* array) { setArray(_vertexArray.get(), state, array); }
136 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); }
137 inline void disableVertexArray(osg::State& state) { disable(_vertexArray.get(), state); }
139 inline void setNormalArray(osg::State& state, const osg::Array* array) { setArray(_normalArray.get(), state, array); }
140 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); }
141 inline void disableNormalArray(osg::State& state) { disable(_normalArray.get(), state); }
143 inline void setColorArray(osg::State& state, const osg::Array* array) { setArray(_colorArray.get(), state, array); }
144 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); }
145 inline void disableColorArray(osg::State& state) { disable(_colorArray.get(), state); }
147 inline void setSecondaryColorArray(osg::State& state, const osg::Array* array) { setArray(_secondaryColorArray.get(), state, array); }
148 inline void disableSecondaryColorArray(osg::State& state) { disable(_secondaryColorArray.get(), state); }
150 inline void setFogCoordArray(osg::State& state, const osg::Array* array) { setArray(_fogCoordArray.get(), state, array); }
151 inline void disableFogCoordArray(osg::State& state) { disable(_fogCoordArray.get(), state); }
153 inline void setTexCoordArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_texCoordArrays[unit].get(), state, array); }
154 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); }
155 inline void disableTexCoordArray(osg::State& state, unsigned int unit) { disable(_texCoordArrays[unit].get(),state); }
156 inline void disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index);
158 inline void setVertexAttribArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_vertexAttribArrays[unit].get(), state, array); }
159 inline void disableVertexAttribArray(osg::State& state, unsigned int unit) { disable(_vertexAttribArrays[unit].get(), state); }
160 inline void disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index);
162 /** Mark all the vertex attributes as being disabled but leave the disabling till a later call to applyDisablingOfVertexAttributes.*/
163 inline void lazyDisablingOfVertexAttributes();
165 /** Disable all the vertex attributes that have been marked as to be disabled.*/
166 inline void applyDisablingOfVertexAttributes(osg::State& state);
168 // Verex Array Object methods.
169 void generateVertexArrayObject();
171 void deleteVertexArrayObject();
173 GLuint getVertexArrayObject() const { return _vertexArrayObject; }
176 void setRequiresSetArrays(bool flag) { _requiresSetArrays = flag; }
177 bool getRequiresSetArrays() const { return _requiresSetArrays; }
185 virtual ~VertexArrayState();
187 // osg::GLBufferObject* getGLBufferObject(osg::Array* array);
190 osg::ref_ptr<ObserverSet> _stateObserverSet;
191 osg::ref_ptr<osg::GLExtensions> _ext;
193 bool _isVertexBufferObjectSupported;
195 GLuint _vertexArrayObject;
198 osg::ref_ptr<ArrayDispatch> _vertexArray;
199 osg::ref_ptr<ArrayDispatch> _normalArray;
200 osg::ref_ptr<ArrayDispatch> _colorArray;
201 osg::ref_ptr<ArrayDispatch> _secondaryColorArray;
202 osg::ref_ptr<ArrayDispatch> _fogCoordArray;
203 ArrayDispatchList _texCoordArrays;
204 ArrayDispatchList _vertexAttribArrays;
206 typedef std::vector<ArrayDispatch*> ActiveDispatchers;
207 ActiveDispatchers _activeDispatchers;
208 ActiveDispatchers _previous_activeDispatchers;
210 GLBufferObject* _currentVBO;
211 GLBufferObject* _currentEBO;
213 bool _requiresSetArrays;
218class OSG_EXPORT VertexArrayStateList
222 VertexArrayStateList();
224 VertexArrayStateList& operator = (const VertexArrayStateList& rhs);
226 inline void clear() { _array.clear(); }
228 inline bool empty() const { return _array.empty(); }
230 inline unsigned int size() const { return _array.size(); }
232 inline void resize(unsigned int newSize) { _array.resize(newSize); }
234 inline ref_ptr<VertexArrayState>& operator[] (unsigned int pos)
236 // automatically resize array.
237 if (_array.size()<=pos)
238 _array.resize(pos+1,0);
243 inline const ref_ptr<VertexArrayState>& operator[] (unsigned int pos) const
245 // automatically resize array.
246 if (_array.size()<=pos)
247 _array.resize(pos+1,0);
252 void assignAllDispatchers();
254 void assignVertexArrayDispatcher();
255 void assignNormalArrayDispatcher();
256 void assignColorArrayDispatcher();
257 void assignSecondaryColorArrayDispatcher();
258 void assignFogCoordArrayDispatcher();
259 void assignTexCoordArrayDispatcher(unsigned int numUnits);
260 void assignVertexAttribArrayDispatcher(unsigned int numUnits);
264 typedef std::vector< osg::ref_ptr<VertexArrayState> > Array;
265 mutable Array _array;
270inline void VertexArrayState::lazyDisablingOfVertexAttributes()
272 _activeDispatchers.swap(_previous_activeDispatchers);
273 _activeDispatchers.clear();
275 for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
276 itr != _previous_activeDispatchers.end();
279 ArrayDispatch* ad = (*itr);
285inline void VertexArrayState::applyDisablingOfVertexAttributes(osg::State& state)
287 for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
288 itr != _previous_activeDispatchers.end();
291 ArrayDispatch* ad = (*itr);
296 ad->modifiedCount = 0xffffffff;
299 _previous_activeDispatchers.clear();
302inline void VertexArrayState::disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index)
304 for(unsigned int i=index; i<_texCoordArrays.size(); ++i)
306 disable(_texCoordArrays[i].get(), state);
310inline void VertexArrayState::disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index)
312 for(unsigned int i=index; i<_vertexAttribArrays.size(); ++i)
314 disable(_vertexAttribArrays[i].get(), state);