188 lines
7.5 KiB
C++
188 lines
7.5 KiB
C++
/* -*-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/ArrayDispatchers>
|
|
|
|
namespace osg {
|
|
|
|
class VertexArrayState : public osg::Referenced
|
|
{
|
|
public:
|
|
|
|
VertexArrayState(osg::GLExtensions* ext);
|
|
|
|
struct ArrayDispatch : public osg::Referenced
|
|
{
|
|
ArrayDispatch():
|
|
array(0),
|
|
modifiedCount(0xffffffff),
|
|
active(false) {}
|
|
|
|
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 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 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 == _currentVBO) return;
|
|
if (vbo->isDirty()) vbo->compileBuffer();
|
|
else 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 == _currentEBO) return;
|
|
if (ebo->isDirty()) ebo->compileBuffer();
|
|
else 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; }
|
|
|
|
void assignAllDispatchers();
|
|
|
|
virtual void assignVertexArrayDispatcher();
|
|
virtual void assignNormalArrayDispatcher();
|
|
virtual void assignColorArrayDispatcher();
|
|
virtual void assignSecondaryColorArrayDispatcher();
|
|
virtual void assignFogCoordArrayDispatcher();
|
|
virtual void assignTexCoordArrayDispatcher(unsigned int numUnits);
|
|
virtual void assignVertexAttribArrayDispatcher(unsigned int numUnits);
|
|
|
|
inline bool isVertexBufferObjectSupported() const { return true; }
|
|
|
|
void setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array);
|
|
void disable(ArrayDispatch* vad, osg::State& state) { vad->disable(state); vad->array=0; vad->modifiedCount=0xffffffff; vad->active=false; }
|
|
|
|
inline void setVertexArray(osg::State& state, const osg::Array* array) { setArray(_vertexArray.get(), state, array); }
|
|
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 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 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 disableTexCoordArray(osg::State& state, unsigned int unit) { disable(_texCoordArrays[unit].get(),state); }
|
|
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); }
|
|
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.*/
|
|
void lazyDisablingOfVertexAttributes();
|
|
|
|
/** Disable all the vertex attributes that have been marked as to be disabled.*/
|
|
void applyDisablingOfVertexAttributes(osg::State& state);
|
|
|
|
|
|
|
|
|
|
// Verex Array Object methods.
|
|
void generateVretexArrayObject();
|
|
|
|
void bindVertexArrayObject() const;
|
|
|
|
void unbindVertexArrayObject() const;
|
|
|
|
GLint getVertexArrayObject() const { return _vertexArrayObject; }
|
|
|
|
void releaseGLObjects();
|
|
|
|
|
|
void setRequiresSetArrays(bool flag) { _requiresSetArrays = flag; }
|
|
bool getRequiresSetArrays() const { return _requiresSetArrays; }
|
|
|
|
|
|
public:
|
|
|
|
|
|
// osg::GLBufferObject* getGLBufferObject(osg::Array* array);
|
|
|
|
osg::ref_ptr<osg::GLExtensions> _ext;
|
|
|
|
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;
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#endif
|