Moved the ArrayDispatchers management so that osg::State now has a ArrayDispatchers object that any osg::Geometry can reuse,

and optimized the implementation to reduce the CPU overhead.
This commit is contained in:
Robert Osfield
2009-10-21 11:18:13 +00:00
parent b7ffae25ce
commit 9499b19b43
6 changed files with 162 additions and 132 deletions

View File

@@ -17,12 +17,12 @@
#include <osg/ref_ptr>
#include <osg/Array>
#include <osg/Matrixd>
#include <osg/GLBeginEndAdapter>
namespace osg {
// forward declare
class State;
class GLBeginEndAdapter;
class AttributeDispatchMap;
struct AttributeDispatch : public osg::Referenced
@@ -36,11 +36,10 @@ class OSG_EXPORT ArrayDispatchers : public osg::Referenced
{
public:
ArrayDispatchers(osg::State& state);
ArrayDispatchers();
~ArrayDispatchers();
void assignTexCoordDispatchers(unsigned int unit);
void assignVertexAttribDispatchers(unsigned int unit);
void setState(osg::State* state);
AttributeDispatch* vertexDispatcher(Array* array, IndexArray* indices);
AttributeDispatch* normalDispatcher(Array* array, IndexArray* indices);
@@ -55,24 +54,52 @@ class OSG_EXPORT ArrayDispatchers : public osg::Referenced
void setUseGLBeginEndAdapter(bool flag) { _useGLBeginEndAdapter = flag; }
bool getUseGLBeginEndAdapter() const { return _useGLBeginEndAdapter; }
void activate(unsigned int binding, AttributeDispatch* at);
void activate(unsigned int binding, AttributeDispatch* at)
{
if (at) _activeDispatchList[binding].push_back(at);
}
void activateVertexArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { activate(binding, vertexDispatcher(array, indices)); }
void activateColorArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { activate(binding, colorDispatcher(array, indices)); }
void activateNormalArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { activate(binding, normalDispatcher(array, indices)); }
void activateSecondaryColorArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { activate(binding, secondaryColorDispatcher(array, indices)); }
void activateFogCoordArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { activate(binding, fogCoordDispatcher(array, indices)); }
void activateTexCoordArray(unsigned int binding, unsigned int unit, osg::Array* array, osg::IndexArray* indices) { activate(binding, texCoordDispatcher(unit, array, indices)); }
void activateVertexAttribArray(unsigned int binding, unsigned int unit, osg::Array* array, osg::IndexArray* indices) { activate(binding, vertexAttribDispatcher(unit, array, indices)); }
void activateVertexArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, vertexDispatcher(array, indices)); }
void activateColorArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, colorDispatcher(array, indices)); }
void activateNormalArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, normalDispatcher(array, indices)); }
void activateSecondaryColorArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, secondaryColorDispatcher(array, indices)); }
void activateFogCoordArray(unsigned int binding, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, fogCoordDispatcher(array, indices)); }
void activateTexCoordArray(unsigned int binding, unsigned int unit, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, texCoordDispatcher(unit, array, indices)); }
void activateVertexAttribArray(unsigned int binding, unsigned int unit, osg::Array* array, osg::IndexArray* indices) { if (binding && array) activate(binding, vertexAttribDispatcher(unit, array, indices)); }
void dispatch(unsigned int binding);
void dispatch(unsigned int binding, unsigned int index);
void dispatch(unsigned int binding, unsigned int index)
{
AttributeDispatchList& ad = _activeDispatchList[binding];
for(AttributeDispatchList::iterator itr = ad.begin();
itr != ad.end();
++itr)
{
(*(*itr))(index);
}
}
void Begin(GLenum mode);
void End();
bool active(unsigned int binding) const { return !_activeDispatchList[binding].empty(); }
void Begin(GLenum mode)
{
if (_useGLBeginEndAdapter) _glBeginEndAdapter->Begin(mode);
else ::glBegin(mode);
}
void End()
{
if (_useGLBeginEndAdapter) _glBeginEndAdapter->End();
else ::glEnd();
}
protected:
void init();
void assignTexCoordDispatchers(unsigned int unit);
void assignVertexAttribDispatchers(unsigned int unit);
bool _initialized;
State* _state;
GLBeginEndAdapter* _glBeginEndAdapter;
@@ -88,19 +115,12 @@ class OSG_EXPORT ArrayDispatchers : public osg::Referenced
typedef std::vector<AttributeDispatch*> AttributeDispatchList;
struct BindingGroup
{
unsigned int _index;
AttributeDispatchList _attributeDispatchList;
};
typedef std::vector<BindingGroup> BindingGroupList;
BindingGroupList _bindingGroupList;
typedef std::vector<AttributeDispatchList> ActiveDispatchList;
ActiveDispatchList _activeDispatchList;
bool _useGLBeginEndAdapter;
};
}
#endif

View File

@@ -73,6 +73,7 @@ class Vec4f;
class Vec4ub;
class Geometry;
class NodeVisitor;
class ArrayDispatchers;
// this is defined to alter the way display lists are compiled inside the
// the draw method, it has been found that the NVidia drivers fail completely
@@ -666,7 +667,9 @@ class OSG_EXPORT Drawable : public Object
void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) const;
void glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) const;
public:
protected:
friend class ArrayDispatchers;
typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord);

View File

@@ -26,6 +26,7 @@
#include <osg/Polytope>
#include <osg/Viewport>
#include <osg/GLBeginEndAdapter>
#include <osg/ArrayDispatchers>
#include <vector>
#include <map>
@@ -1246,6 +1247,8 @@ class OSG_EXPORT State : public Referenced, public Observer
/** get the GL adapter object used to map OpenGL 1.0 glBegin/glEnd usage to vertex arrays.*/
inline GLBeginEndAdapter& getGLBeginEndAdapter() { return _glBeginEndAdapter; }
/** get the helper class for dispatching osg::Arrays as OpenGL attribute data.*/
inline ArrayDispatchers& getArrayDispatchers() { return _arrayDispatchers; }
protected:
@@ -1558,6 +1561,7 @@ class OSG_EXPORT State : public Referenced, public Observer
osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;
GLBeginEndAdapter _glBeginEndAdapter;
ArrayDispatchers _arrayDispatchers;
};