/* -*-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_ArrayDispatchers #define OSG_ArrayDispatchers 1 #include #include #include namespace osg { // forward declare class State; class AttributeDispatchMap; struct AttributeDispatch : public osg::Referenced { virtual void assign(const GLvoid*) {} virtual void operator() (unsigned int) {}; }; /** Helper class for managing the dispatch to OpenGL of various attribute arrays such as stored in osg::Geometry.*/ class OSG_EXPORT ArrayDispatchers : public osg::Referenced { public: ArrayDispatchers(); ~ArrayDispatchers(); void setState(osg::State* state); void reset(); void setUseVertexAttribAlias(bool flag) { _useVertexAttribAlias = flag; } bool getUseVertexAttribAlias() const { return _useVertexAttribAlias; } void activate(unsigned int binding, AttributeDispatch* at) { if (at) _activeDispatchList[binding].push_back(at); } void activateVertexArray(osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), vertexDispatcher(array)); } void activateColorArray(osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), colorDispatcher(array)); } void activateNormalArray(osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), normalDispatcher(array)); } void activateSecondaryColorArray(osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), secondaryColorDispatcher(array)); } void activateFogCoordArray(osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), fogCoordDispatcher(array)); } void activateTexCoordArray(unsigned int unit, osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), texCoordDispatcher(unit, array)); } void activateVertexAttribArray(unsigned int unit, osg::Array* array) { if (array && array->getBinding()>osg::Array::BIND_OFF) activate(array->getBinding(), vertexAttribDispatcher(unit, array)); } AttributeDispatch* vertexDispatcher(Array* array); AttributeDispatch* normalDispatcher(Array* array); AttributeDispatch* colorDispatcher(Array* array); AttributeDispatch* secondaryColorDispatcher(Array* array); AttributeDispatch* fogCoordDispatcher(Array* array); AttributeDispatch* texCoordDispatcher(unsigned int unit, Array* array); AttributeDispatch* vertexAttribDispatcher(unsigned int unit, Array* array); void dispatch(unsigned int binding, unsigned int index) { AttributeDispatchList& ad = _activeDispatchList[binding]; for(AttributeDispatchList::iterator itr = ad.begin(); itr != ad.end(); ++itr) { (*(*itr))(index); } } bool active(unsigned int binding) const { return !_activeDispatchList[binding].empty(); } protected: void init(); void assignTexCoordDispatchers(unsigned int unit); void assignVertexAttribDispatchers(unsigned int unit); bool _initialized; State* _state; AttributeDispatchMap* _vertexDispatchers; AttributeDispatchMap* _normalDispatchers; AttributeDispatchMap* _colorDispatchers; AttributeDispatchMap* _secondaryColorDispatchers; AttributeDispatchMap* _fogCoordDispatchers; typedef std::vector AttributeDispatchMapList; AttributeDispatchMapList _texCoordDispatchers; AttributeDispatchMapList _vertexAttribDispatchers; typedef std::vector AttributeDispatchList; typedef std::vector ActiveDispatchList; ActiveDispatchList _activeDispatchList; bool _useVertexAttribAlias; }; } #endif