123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSG_VertexArrayState
- #define OSG_VertexArrayState 1
- #include <osg/Referenced>
- #include <osg/GLExtensions>
- #include <osg/Array>
- #include <osg/AttributeDispatchers>
- namespace osg {
- class OSG_EXPORT VertexArrayState : public osg::Referenced
- {
- public:
- VertexArrayState(osg::State* state);
- struct ArrayDispatch : public osg::Referenced
- {
- ArrayDispatch():
- array(0),
- modifiedCount(0xffffffff),
- active(false) {}
- virtual bool isVertexAttribDispatch() const { return false; }
- virtual const char* className() const = 0; // { return "ArrayDispatch"; }
- virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
- virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
- virtual void enable_and_dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
- virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
- virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
- virtual void dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;
- virtual void disable(osg::State& /*state*/) {} // = 0;
- const osg::Array* array;
- unsigned int modifiedCount;
- bool active;
- };
- typedef std::vector< ref_ptr<ArrayDispatch> > ArrayDispatchList;
- void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
- GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
- inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
- {
- if (vbo->isDirty())
- {
- vbo->compileBuffer();
- _currentVBO = vbo;
- }
- else if (vbo != _currentVBO)
- {
- vbo->bindBuffer();
- _currentVBO = vbo;
- }
- }
- inline void unbindVertexBufferObject()
- {
- if (!_currentVBO) return;
- _ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
- _currentVBO = 0;
- }
- void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
- GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
- inline void bindElementBufferObject(osg::GLBufferObject* ebo)
- {
- if (ebo->isDirty())
- {
- ebo->compileBuffer();
- _currentEBO = ebo;
- }
- else if (ebo != _currentEBO)
- {
- ebo->bindBuffer();
- _currentEBO = ebo;
- }
- }
- inline void unbindElementBufferObject()
- {
- if (!_currentEBO) return;
- _ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
- _currentEBO = 0;
- }
- void resetBufferObjectPointers() { _currentVBO = 0; _currentEBO = 0; }
- bool correctArrayDispatchAssigned(const ArrayDispatch* ad);
- void assignAllDispatchers();
- void assignVertexArrayDispatcher();
- void assignNormalArrayDispatcher();
- void assignColorArrayDispatcher();
- void assignSecondaryColorArrayDispatcher();
- void assignFogCoordArrayDispatcher();
- void assignTexCoordArrayDispatcher(unsigned int numUnits);
- void assignVertexAttribArrayDispatcher(unsigned int numUnits);
- inline void setVertexBufferObjectSupported(bool flag) { _isVertexBufferObjectSupported = flag; }
- inline bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupported; }
- void setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array);
- void setArray(ArrayDispatch* vad, osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized);
- inline void disable(ArrayDispatch* vad, osg::State& state) { vad->disable(state); vad->array=0; vad->modifiedCount=0xffffffff; vad->active=false; }
- void setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer);
- inline void setVertexArray(osg::State& state, const osg::Array* array) { setArray(_vertexArray.get(), state, array); }
- 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); }
- inline void disableVertexArray(osg::State& state) { disable(_vertexArray.get(), state); }
- inline void setNormalArray(osg::State& state, const osg::Array* array) { setArray(_normalArray.get(), state, array); }
- 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); }
- inline void disableNormalArray(osg::State& state) { disable(_normalArray.get(), state); }
- inline void setColorArray(osg::State& state, const osg::Array* array) { setArray(_colorArray.get(), state, array); }
- 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); }
- inline void disableColorArray(osg::State& state) { disable(_colorArray.get(), state); }
- inline void setSecondaryColorArray(osg::State& state, const osg::Array* array) { setArray(_secondaryColorArray.get(), state, array); }
- inline void disableSecondaryColorArray(osg::State& state) { disable(_secondaryColorArray.get(), state); }
- inline void setFogCoordArray(osg::State& state, const osg::Array* array) { setArray(_fogCoordArray.get(), state, array); }
- inline void disableFogCoordArray(osg::State& state) { disable(_fogCoordArray.get(), state); }
- inline void setTexCoordArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_texCoordArrays[unit].get(), state, array); }
- 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); }
- inline void disableTexCoordArray(osg::State& state, unsigned int unit) { disable(_texCoordArrays[unit].get(),state); }
- inline void disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index);
- inline void setVertexAttribArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_vertexAttribArrays[unit].get(), state, array); }
- inline void disableVertexAttribArray(osg::State& state, unsigned int unit) { disable(_vertexAttribArrays[unit].get(), state); }
- inline void disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index);
- /** Mark all the vertex attributes as being disabled but leave the disabling till a later call to applyDisablingOfVertexAttributes.*/
- inline void lazyDisablingOfVertexAttributes();
- /** Disable all the vertex attributes that have been marked as to be disabled.*/
- inline void applyDisablingOfVertexAttributes(osg::State& state);
- // Verex Array Object methods.
- void generateVertexArrayObject();
- void deleteVertexArrayObject();
- GLuint getVertexArrayObject() const { return _vertexArrayObject; }
- void setRequiresSetArrays(bool flag) { _requiresSetArrays = flag; }
- bool getRequiresSetArrays() const { return _requiresSetArrays; }
- void dirty();
- void release();
- public:
- virtual ~VertexArrayState();
- // osg::GLBufferObject* getGLBufferObject(osg::Array* array);
- osg::State* _state;
- osg::ref_ptr<ObserverSet> _stateObserverSet;
- osg::ref_ptr<osg::GLExtensions> _ext;
- bool _isVertexBufferObjectSupported;
- GLuint _vertexArrayObject;
- osg::ref_ptr<ArrayDispatch> _vertexArray;
- osg::ref_ptr<ArrayDispatch> _normalArray;
- osg::ref_ptr<ArrayDispatch> _colorArray;
- osg::ref_ptr<ArrayDispatch> _secondaryColorArray;
- osg::ref_ptr<ArrayDispatch> _fogCoordArray;
- ArrayDispatchList _texCoordArrays;
- ArrayDispatchList _vertexAttribArrays;
- typedef std::vector<ArrayDispatch*> ActiveDispatchers;
- ActiveDispatchers _activeDispatchers;
- ActiveDispatchers _previous_activeDispatchers;
- GLBufferObject* _currentVBO;
- GLBufferObject* _currentEBO;
- bool _requiresSetArrays;
- };
- class OSG_EXPORT VertexArrayStateList
- {
- public:
- VertexArrayStateList();
- VertexArrayStateList& operator = (const VertexArrayStateList& rhs);
- inline void clear() { _array.clear(); }
- inline bool empty() const { return _array.empty(); }
- inline unsigned int size() const { return _array.size(); }
- inline void resize(unsigned int newSize) { _array.resize(newSize); }
- inline ref_ptr<VertexArrayState>& operator[] (unsigned int pos)
- {
- // automatically resize array.
- if (_array.size()<=pos)
- _array.resize(pos+1,0);
- return _array[pos];
- }
- inline const ref_ptr<VertexArrayState>& operator[] (unsigned int pos) const
- {
- // automatically resize array.
- if (_array.size()<=pos)
- _array.resize(pos+1,0);
- return _array[pos];
- }
- void assignAllDispatchers();
- void assignVertexArrayDispatcher();
- void assignNormalArrayDispatcher();
- void assignColorArrayDispatcher();
- void assignSecondaryColorArrayDispatcher();
- void assignFogCoordArrayDispatcher();
- void assignTexCoordArrayDispatcher(unsigned int numUnits);
- void assignVertexAttribArrayDispatcher(unsigned int numUnits);
- protected:
- typedef std::vector< osg::ref_ptr<VertexArrayState> > Array;
- mutable Array _array;
- };
- inline void VertexArrayState::lazyDisablingOfVertexAttributes()
- {
- _activeDispatchers.swap(_previous_activeDispatchers);
- _activeDispatchers.clear();
- for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
- itr != _previous_activeDispatchers.end();
- ++itr)
- {
- ArrayDispatch* ad = (*itr);
- // ad->array = 0;
- ad->active = false;
- }
- }
- inline void VertexArrayState::applyDisablingOfVertexAttributes(osg::State& state)
- {
- for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
- itr != _previous_activeDispatchers.end();
- ++itr)
- {
- ArrayDispatch* ad = (*itr);
- if (!ad->active)
- {
- ad->disable(state);
- ad->array = 0;
- ad->modifiedCount = 0xffffffff;
- }
- }
- _previous_activeDispatchers.clear();
- }
- inline void VertexArrayState::disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index)
- {
- for(unsigned int i=index; i<_texCoordArrays.size(); ++i)
- {
- disable(_texCoordArrays[i].get(), state);
- }
- }
- inline void VertexArrayState::disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index)
- {
- for(unsigned int i=index; i<_vertexAttribArrays.size(); ++i)
- {
- disable(_vertexAttribArrays[i].get(), state);
- }
- }
- }
- #endif
|