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

@@ -345,15 +345,62 @@ public:
AttributeDispatchList _glBeginEndAttributeDispatchWithIndicesList;
};
ArrayDispatchers::ArrayDispatchers(osg::State& state):
_state(&state),
_vertexDispatchers(new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()))),
_normalDispatchers(new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()))),
_colorDispatchers(new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()))),
_secondaryColorDispatchers(new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()))),
_fogCoordDispatchers(new AttributeDispatchMap(&(_state->getGLBeginEndAdapter())))
ArrayDispatchers::ArrayDispatchers():
_initialized(false),
_state(0),
_glBeginEndAdapter(0),
_vertexDispatchers(0),
_normalDispatchers(0),
_colorDispatchers(0),
_secondaryColorDispatchers(0),
_fogCoordDispatchers(0),
_useGLBeginEndAdapter(false)
{
Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(),true);
}
ArrayDispatchers::~ArrayDispatchers()
{
delete _vertexDispatchers;
delete _normalDispatchers;
delete _colorDispatchers;
delete _secondaryColorDispatchers;
delete _fogCoordDispatchers;
for(AttributeDispatchMapList::iterator itr = _texCoordDispatchers.begin();
itr != _texCoordDispatchers.end();
++itr)
{
delete *itr;
}
for(AttributeDispatchMapList::iterator itr = _vertexAttribDispatchers.begin();
itr != _vertexAttribDispatchers.end();
++itr)
{
delete *itr;
}
}
void ArrayDispatchers::setState(osg::State* state)
{
_state = state;
_glBeginEndAdapter = &(state->getGLBeginEndAdapter());
}
void ArrayDispatchers::init()
{
if (_initialized) return;
_initialized = true;
_vertexDispatchers = new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()));
_normalDispatchers = new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()));
_colorDispatchers = new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()));
_secondaryColorDispatchers = new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()));
_fogCoordDispatchers = new AttributeDispatchMap(&(_state->getGLBeginEndAdapter()));
Drawable::Extensions* extensions = Drawable::getExtensions(_state->getContextID(),true);
_glBeginEndAdapter = &(_state->getGLBeginEndAdapter());
_useGLBeginEndAdapter = false;
@@ -378,10 +425,9 @@ ArrayDispatchers::ArrayDispatchers(osg::State& state):
_secondaryColorDispatchers->assign<GLfloat>(Array::Vec3ArrayType, extensions->_glSecondaryColor3fv, 3);
_fogCoordDispatchers->assign<GLfloat>(Array::FloatArrayType, extensions->_glFogCoordfv, 1);
}
ArrayDispatchers::~ArrayDispatchers()
{
// pre allocate.
_activeDispatchList.resize(5);
}
AttributeDispatch* ArrayDispatchers::vertexDispatcher(Array* array, IndexArray* indices) { return _vertexDispatchers->dispatcher(_useGLBeginEndAdapter, array, indices); }
@@ -452,70 +498,16 @@ void ArrayDispatchers::assignVertexAttribDispatchers(unsigned int unit)
void ArrayDispatchers::reset()
{
if (!_initialized) init();
_useGLBeginEndAdapter = false;
for(BindingGroupList::iterator itr = _bindingGroupList.begin();
itr != _bindingGroupList.end();
for(ActiveDispatchList::iterator itr = _activeDispatchList.begin();
itr != _activeDispatchList.end();
++itr)
{
itr->_index = 0;
itr->_attributeDispatchList.clear();
(*itr).clear();
}
}
void ArrayDispatchers::activate(unsigned int binding, AttributeDispatch* at)
{
if (!at) return;
if (binding>=_bindingGroupList.size()) _bindingGroupList.resize(binding+1);
BindingGroup& bindingGroup = _bindingGroupList[binding];
bindingGroup._attributeDispatchList.push_back(at);
}
void ArrayDispatchers::dispatch(unsigned int binding, unsigned int index)
{
if (binding>=_bindingGroupList.size()) return;
BindingGroup& bg = _bindingGroupList[binding];
for(AttributeDispatchList::iterator itr = bg._attributeDispatchList.begin();
itr != bg._attributeDispatchList.end();
++itr)
{
AttributeDispatch* at = *itr;
(*at)(index);
}
}
void ArrayDispatchers::dispatch(unsigned int binding)
{
if (binding>=_bindingGroupList.size()) return;
BindingGroup& bg = _bindingGroupList[binding];
unsigned int index = bg._index;
for(AttributeDispatchList::iterator itr = bg._attributeDispatchList.begin();
itr != bg._attributeDispatchList.end();
++itr)
{
AttributeDispatch* at = *itr;
(*at)(index);
}
// advance the index so that it's ready for the next dispatch
++(bg._index);
}
void ArrayDispatchers::Begin(GLenum mode)
{
if (_useGLBeginEndAdapter) _glBeginEndAdapter->Begin(mode);
else ::glBegin(mode);
}
void ArrayDispatchers::End()
{
if (_useGLBeginEndAdapter) _glBeginEndAdapter->End();
else ::glEnd();
}
}