openscenegraph
VertexArrayState
Go to the documentation of this file.
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_VertexArrayState
15#define OSG_VertexArrayState 1
16
17#include <osg/Referenced>
18#include <osg/GLExtensions>
19#include <osg/Array>
20#include <osg/AttributeDispatchers>
21
22namespace osg {
23
24class OSG_EXPORT VertexArrayState : public osg::Referenced
25{
26 public:
27
28 VertexArrayState(osg::State* state);
29
30 struct ArrayDispatch : public osg::Referenced
31 {
32 ArrayDispatch():
33 array(0),
34 modifiedCount(0xffffffff),
35 active(false) {}
36
37 virtual bool isVertexAttribDispatch() const { return false; }
38
39 virtual const char* className() const = 0; // { return "ArrayDispatch"; }
40
41 virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
42
43 virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
44
45 virtual void enable_and_dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
46
47 virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
48
49 virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
50
51 virtual void dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
52
53 virtual void disable(osg::State& /*state*/) {} // = 0;
54
55 const osg::Array* array;
56 unsigned int modifiedCount;
57 bool active;
58 };
59
60 typedef std::vector< ref_ptr<ArrayDispatch> > ArrayDispatchList;
61
62 void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
63 GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
64
65 inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
66 {
67 if (vbo->isDirty())
68 {
69 vbo->compileBuffer();
70 _currentVBO = vbo;
71 }
72 else if (vbo != _currentVBO)
73 {
74 vbo->bindBuffer();
75 _currentVBO = vbo;
76 }
77 }
78
79 inline void unbindVertexBufferObject()
80 {
81 if (!_currentVBO) return;
82 _ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
83 _currentVBO = 0;
84 }
85
86
87 void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
88 GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
89
90 inline void bindElementBufferObject(osg::GLBufferObject* ebo)
91 {
92 if (ebo->isDirty())
93 {
94 ebo->compileBuffer();
95 _currentEBO = ebo;
96 }
97 else if (ebo != _currentEBO)
98 {
99 ebo->bindBuffer();
100 _currentEBO = ebo;
101 }
102 }
103
104 inline void unbindElementBufferObject()
105 {
106 if (!_currentEBO) return;
107 _ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
108 _currentEBO = 0;
109 }
110
111 void resetBufferObjectPointers() { _currentVBO = 0; _currentEBO = 0; }
112
113 bool correctArrayDispatchAssigned(const ArrayDispatch* ad);
114
115 void assignAllDispatchers();
116
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);
124
125 inline void setVertexBufferObjectSupported(bool flag) { _isVertexBufferObjectSupported = flag; }
126 inline bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupported; }
127
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);
130
131 inline void disable(ArrayDispatch* vad, osg::State& state) { vad->disable(state); vad->array=0; vad->modifiedCount=0xffffffff; vad->active=false; }
132
133 void setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer);
134
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); }
138
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); }
142
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); }
146
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); }
149
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); }
152
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);
157
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);
161
162 /** Mark all the vertex attributes as being disabled but leave the disabling till a later call to applyDisablingOfVertexAttributes.*/
163 inline void lazyDisablingOfVertexAttributes();
164
165 /** Disable all the vertex attributes that have been marked as to be disabled.*/
166 inline void applyDisablingOfVertexAttributes(osg::State& state);
167
168 // Verex Array Object methods.
169 void generateVertexArrayObject();
170
171 void deleteVertexArrayObject();
172
173 GLuint getVertexArrayObject() const { return _vertexArrayObject; }
174
175
176 void setRequiresSetArrays(bool flag) { _requiresSetArrays = flag; }
177 bool getRequiresSetArrays() const { return _requiresSetArrays; }
178
179 void dirty();
180
181 void release();
182
183 public:
184
185 virtual ~VertexArrayState();
186
187 // osg::GLBufferObject* getGLBufferObject(osg::Array* array);
188
189 osg::State* _state;
190 osg::ref_ptr<ObserverSet> _stateObserverSet;
191 osg::ref_ptr<osg::GLExtensions> _ext;
192
193 bool _isVertexBufferObjectSupported;
194
195 GLuint _vertexArrayObject;
196
197
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;
205
206 typedef std::vector<ArrayDispatch*> ActiveDispatchers;
207 ActiveDispatchers _activeDispatchers;
208 ActiveDispatchers _previous_activeDispatchers;
209
210 GLBufferObject* _currentVBO;
211 GLBufferObject* _currentEBO;
212
213 bool _requiresSetArrays;
214};
215
216
217
218class OSG_EXPORT VertexArrayStateList
219{
220 public:
221
222 VertexArrayStateList();
223
224 VertexArrayStateList& operator = (const VertexArrayStateList& rhs);
225
226 inline void clear() { _array.clear(); }
227
228 inline bool empty() const { return _array.empty(); }
229
230 inline unsigned int size() const { return _array.size(); }
231
232 inline void resize(unsigned int newSize) { _array.resize(newSize); }
233
234 inline ref_ptr<VertexArrayState>& operator[] (unsigned int pos)
235 {
236 // automatically resize array.
237 if (_array.size()<=pos)
238 _array.resize(pos+1,0);
239
240 return _array[pos];
241 }
242
243 inline const ref_ptr<VertexArrayState>& operator[] (unsigned int pos) const
244 {
245 // automatically resize array.
246 if (_array.size()<=pos)
247 _array.resize(pos+1,0);
248
249 return _array[pos];
250 }
251
252 void assignAllDispatchers();
253
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);
261
262protected:
263
264 typedef std::vector< osg::ref_ptr<VertexArrayState> > Array;
265 mutable Array _array;
266};
267
268
269
270inline void VertexArrayState::lazyDisablingOfVertexAttributes()
271{
272 _activeDispatchers.swap(_previous_activeDispatchers);
273 _activeDispatchers.clear();
274
275 for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
276 itr != _previous_activeDispatchers.end();
277 ++itr)
278 {
279 ArrayDispatch* ad = (*itr);
280 // ad->array = 0;
281 ad->active = false;
282 }
283}
284
285inline void VertexArrayState::applyDisablingOfVertexAttributes(osg::State& state)
286{
287 for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
288 itr != _previous_activeDispatchers.end();
289 ++itr)
290 {
291 ArrayDispatch* ad = (*itr);
292 if (!ad->active)
293 {
294 ad->disable(state);
295 ad->array = 0;
296 ad->modifiedCount = 0xffffffff;
297 }
298 }
299 _previous_activeDispatchers.clear();
300}
301
302inline void VertexArrayState::disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index)
303{
304 for(unsigned int i=index; i<_texCoordArrays.size(); ++i)
305 {
306 disable(_texCoordArrays[i].get(), state);
307 }
308}
309
310inline void VertexArrayState::disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index)
311{
312 for(unsigned int i=index; i<_vertexAttribArrays.size(); ++i)
313 {
314 disable(_vertexAttribArrays[i].get(), state);
315 }
316}
317
318
319
320}
321
322#endif