From 6a56b6e6bef7a8c90cdfd7cf1b85b2fc0b954379 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 20 Oct 2009 19:34:24 +0000 Subject: [PATCH] Refactored osg::Geometry::drawImplementation(..) to use new osg::ArrayDispatchers that encapsulate the task of dispatch osg::Array data as OpenGL attributes. --- include/osg/Array | 26 +- include/osg/ArrayDispatchers | 106 +++++++ include/osg/Drawable | 6 +- include/osg/GLBeginEndAdapter | 19 +- include/osg/State | 4 +- runexamples.bat | 2 +- src/osg/ArrayDispatchers.cpp | 521 ++++++++++++++++++++++++++++++++++ src/osg/CMakeLists.txt | 2 + src/osg/Drawable.cpp | 2 + src/osg/GLBeginEndAdapter.cpp | 13 - src/osg/Geometry.cpp | 274 +++++++++++++++++- 11 files changed, 934 insertions(+), 41 deletions(-) create mode 100644 include/osg/ArrayDispatchers create mode 100644 src/osg/ArrayDispatchers.cpp diff --git a/include/osg/Array b/include/osg/Array index 1a6a6f826..f5c08b3ba 100644 --- a/include/osg/Array +++ b/include/osg/Array @@ -71,14 +71,14 @@ class OSG_EXPORT Array : public BufferData DoubleArrayType = 18, Vec2dArrayType = 19, Vec3dArrayType = 20, - Vec4dArrayType = 21 + Vec4dArrayType = 21 }; Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): _arrayType(arrayType), _dataSize(dataSize), _dataType(dataType) {} - + Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): BufferData(array,copyop), _arrayType(array._arrayType), @@ -88,7 +88,7 @@ class OSG_EXPORT Array : public BufferData virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* libraryName() const { return "osg"; } virtual const char* className() const; - + virtual void accept(ArrayVisitor&) = 0; virtual void accept(ConstArrayVisitor&) const = 0; @@ -131,13 +131,13 @@ template class TemplateArray : public Array, public MixinVector { public: - + TemplateArray() : Array(ARRAYTYPE,DataSize,DataType) {} TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Array(ta,copyop), MixinVector(ta) {} - + TemplateArray(unsigned int no) : Array(ARRAYTYPE,DataSize,DataType), MixinVector(no) {} @@ -181,7 +181,7 @@ class TemplateArray : public Array, public MixinVector { MixinVector( *this ).swap( *this ); } - + virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual unsigned int getTotalDataSize() const { return static_cast(this->size()*sizeof(T)); } virtual unsigned int getNumElements() const { return static_cast(this->size()); } @@ -200,16 +200,16 @@ class OSG_EXPORT IndexArray : public Array IndexArray(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): Array(arrayType,dataSize,dataType) {} - + IndexArray(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Array(array,copyop) {} virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } - + virtual unsigned int index(unsigned int pos) const = 0; protected: - + virtual ~IndexArray() {} }; @@ -217,13 +217,13 @@ template class TemplateIndexArray : public IndexArray, public MixinVector { public: - + TemplateIndexArray() : IndexArray(ARRAYTYPE,DataSize,DataType) {} TemplateIndexArray(const TemplateIndexArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): IndexArray(ta,copyop), MixinVector(ta) {} - + TemplateIndexArray(unsigned int no) : IndexArray(ARRAYTYPE,DataSize,DataType), MixinVector(no) {} @@ -267,7 +267,7 @@ class TemplateIndexArray : public IndexArray, public MixinVector { MixinVector( *this ).swap( *this ); } - + virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual unsigned int getTotalDataSize() const { return static_cast(this->size()*sizeof(T)); } virtual unsigned int getNumElements() const { return static_cast(this->size()); } @@ -277,7 +277,7 @@ class TemplateIndexArray : public IndexArray, public MixinVector typedef T ElementDataType; // expose T protected: - + virtual ~TemplateIndexArray() {} }; diff --git a/include/osg/ArrayDispatchers b/include/osg/ArrayDispatchers new file mode 100644 index 000000000..1fec13726 --- /dev/null +++ b/include/osg/ArrayDispatchers @@ -0,0 +1,106 @@ +/* -*-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 GLBeginEndAdapter; +class AttributeDispatchMap; + +struct AttributeDispatch : public osg::Referenced +{ + virtual void assign(const GLvoid*, const IndexArray*) {} + 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(osg::State& state); + ~ArrayDispatchers(); + + void assignTexCoordDispatchers(unsigned int unit); + void assignVertexAttribDispatchers(unsigned int unit); + + AttributeDispatch* vertexDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* normalDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* colorDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* secondaryColorDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* fogCoordDispatcher(Array* array, IndexArray* indices); + AttributeDispatch* texCoordDispatcher(unsigned int unit, Array* array, IndexArray* indices); + AttributeDispatch* vertexAttribDispatcher(unsigned int unit, Array* array, IndexArray* indices); + + void reset(); + + void setUseGLBeginEndAdapter(bool flag) { _useGLBeginEndAdapter = flag; } + bool getUseGLBeginEndAdapter() const { return _useGLBeginEndAdapter; } + + void activate(unsigned int binding, AttributeDispatch* 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 dispatch(unsigned int binding); + void dispatch(unsigned int binding, unsigned int index); + + void Begin(GLenum mode); + void End(); + + protected: + + State* _state; + GLBeginEndAdapter* _glBeginEndAdapter; + + AttributeDispatchMap* _vertexDispatchers; + AttributeDispatchMap* _normalDispatchers; + AttributeDispatchMap* _colorDispatchers; + AttributeDispatchMap* _secondaryColorDispatchers; + AttributeDispatchMap* _fogCoordDispatchers; + + typedef std::vector AttributeDispatchMapList; + AttributeDispatchMapList _texCoordDispatchers; + AttributeDispatchMapList _vertexAttribDispatchers; + + typedef std::vector AttributeDispatchList; + + struct BindingGroup + { + unsigned int _index; + AttributeDispatchList _attributeDispatchList; + }; + + typedef std::vector BindingGroupList; + BindingGroupList _bindingGroupList; + + bool _useGLBeginEndAdapter; +}; + + +} + +#endif diff --git a/include/osg/Drawable b/include/osg/Drawable index 217fe47d4..0060bb3a6 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -666,7 +666,7 @@ class OSG_EXPORT Drawable : public Object void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) const; void glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) const; - protected: + public: typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord); @@ -735,9 +735,11 @@ class OSG_EXPORT Drawable : public Object VertexAttrib1sProc _glVertexAttrib1s; VertexAttrib1fProc _glVertexAttrib1f; VertexAttrib1dProc _glVertexAttrib1d; + VertexAttribfvProc _glVertexAttrib1fv; VertexAttribfvProc _glVertexAttrib2fv; VertexAttribfvProc _glVertexAttrib3fv; VertexAttribfvProc _glVertexAttrib4fv; + VertexAttribdvProc _glVertexAttrib1dv; VertexAttribdvProc _glVertexAttrib2dv; VertexAttribdvProc _glVertexAttrib3dv; VertexAttribdvProc _glVertexAttrib4dv; @@ -745,10 +747,12 @@ class OSG_EXPORT Drawable : public Object VertexAttribubvProc _glVertexAttrib4Nubv; MultiTexCoord1fProc _glMultiTexCoord1f; + MultiTexCoordfvProc _glMultiTexCoord1fv; MultiTexCoordfvProc _glMultiTexCoord2fv; MultiTexCoordfvProc _glMultiTexCoord3fv; MultiTexCoordfvProc _glMultiTexCoord4fv; MultiTexCoord1dProc _glMultiTexCoord1d; + MultiTexCoorddvProc _glMultiTexCoord1dv; MultiTexCoorddvProc _glMultiTexCoord2dv; MultiTexCoorddvProc _glMultiTexCoord3dv; MultiTexCoorddvProc _glMultiTexCoord4dv; diff --git a/include/osg/GLBeginEndAdapter b/include/osg/GLBeginEndAdapter index 3f8f40b29..255eb24bd 100644 --- a/include/osg/GLBeginEndAdapter +++ b/include/osg/GLBeginEndAdapter @@ -54,13 +54,23 @@ class OSG_EXPORT GLBeginEndAdapter void Scaled(GLdouble x, GLdouble y, GLdouble z); void Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); - void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - void Color4fv(const GLfloat* c) { Color4f(c[0], c[1], c[2], c[3]); } - void Vertex3f(GLfloat x, GLfloat y, GLfloat z); void Vertex3fv(const GLfloat* v) { Vertex3f(v[0], v[1], v[2]); } - void Normal3f(GLfloat x, GLfloat y, GLfloat z); + void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + { + _normalAssigned = true; + _color.set(red,green,blue,alpha); + } + + void Color4fv(const GLfloat* c) { Color4f(c[0], c[1], c[2], c[3]); } + + void Normal3f(GLfloat x, GLfloat y, GLfloat z) + { + _normalAssigned = true; + _normal.set(x,y,z); + } + void Normal3fv(const GLfloat* n) { Normal3f(n[0], n[1], n[2]); } void TexCoord1f(GLfloat x) { MultiTexCoord4f(0, x, 0.0f, 0.0f, 1.0f); } @@ -140,7 +150,6 @@ class OSG_EXPORT GLBeginEndAdapter VertexArrayList _vertexAttribsList; }; - } #endif diff --git a/include/osg/State b/include/osg/State index 296e8872f..dd144f578 100644 --- a/include/osg/State +++ b/include/osg/State @@ -476,13 +476,13 @@ class OSG_EXPORT State : public Referenced, public Observer else glNormal3f(x,y,z); } - void TexCoord(float x, float y=0.0f, float z=0.0f, float w=0.0f) + void TexCoord(float x, float y=0.0f, float z=0.0f, float w=1.0f) { if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w); else glTexCoord4f(x,y,z,w); } - void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=0.0f) + void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=1.0f) { if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w); else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w); diff --git a/runexamples.bat b/runexamples.bat index 8fd15f78e..21f092cdc 100644 --- a/runexamples.bat +++ b/runexamples.bat @@ -25,7 +25,7 @@ echo osgcallback osgcallback echo osgcatch -osgcatch +# osgcatch echo osgclip osgclip diff --git a/src/osg/ArrayDispatchers.cpp b/src/osg/ArrayDispatchers.cpp new file mode 100644 index 000000000..d19162b6d --- /dev/null +++ b/src/osg/ArrayDispatchers.cpp @@ -0,0 +1,521 @@ +/* -*-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. +*/ +#include +#include +#include + +#include +#include + +namespace osg +{ + +template +class TemplateAttributeDispatch : public AttributeDispatch +{ + public: + + typedef void (APIENTRY * F) (const T*); + + TemplateAttributeDispatch(F functionPtr, unsigned int stride): + _functionPtr(functionPtr), _stride(stride), _array(0) {} + + virtual void assign(const GLvoid* array, const IndexArray*) + { + _array = reinterpret_cast(array); + } + + virtual void operator () (unsigned int pos) + { + _functionPtr(&(_array[pos*_stride])); + } + + F _functionPtr; + unsigned int _stride; + const T* _array; +}; + +template +class TemplateAttributeWithIndicesDispatch : public AttributeDispatch +{ + public: + + typedef void (APIENTRY * F) (const T*); + + TemplateAttributeWithIndicesDispatch(F functionPtr, unsigned int stride): + _functionPtr(functionPtr), _stride(stride), _array(0), _indices(0) {} + + virtual void assign(const GLvoid* array, const IndexArray* indices) + { + _array = reinterpret_cast(array); + _indices = indices; + } + + virtual void operator () (unsigned int pos) + { + _functionPtr(&(_array[_indices->index(pos) * _stride])); + } + + F _functionPtr; + unsigned int _stride; + const T* _array; + const IndexArray* _indices; +}; + +template +class TemplateBeginEndAttributeDispatch : public AttributeDispatch +{ + public: + + typedef void (GLBeginEndAdapter::*F) (const T*); + + TemplateBeginEndAttributeDispatch(GLBeginEndAdapter* glBeginEndAdapter, F functionPtr, unsigned int stride): + _glBeginEndAdapter(glBeginEndAdapter), + _functionPtr(functionPtr), _stride(stride), _array(0) {} + + virtual void assign(const GLvoid* array, const IndexArray*) + { + _array = reinterpret_cast(array); + } + + virtual void operator () (unsigned int pos) + { + (_glBeginEndAdapter->*_functionPtr)(&(_array[pos*_stride])); + } + + GLBeginEndAdapter* _glBeginEndAdapter; + F _functionPtr; + unsigned int _stride; + const T* _array; +}; + +template +class TemplateBeginEndAttributeWithIndicesDispatch : public AttributeDispatch +{ + public: + + typedef void (GLBeginEndAdapter::*F) (const T*); + + TemplateBeginEndAttributeWithIndicesDispatch(GLBeginEndAdapter* glBeginEndAdapter, F functionPtr, unsigned int stride): + _glBeginEndAdapter(glBeginEndAdapter), + _functionPtr(functionPtr), _stride(stride), _array(0), _indices(0) {} + + virtual void assign(const GLvoid* array, const IndexArray* indices) + { + _array = reinterpret_cast(array); + _indices = indices; + } + + virtual void operator () (unsigned int pos) + { + (_glBeginEndAdapter->*_functionPtr)(&(_array[_indices->index(pos) * _stride])); + } + + GLBeginEndAdapter* _glBeginEndAdapter; + F _functionPtr; + unsigned int _stride; + const T* _array; + const IndexArray* _indices; +}; + + +template +class TemplateTargetAttributeDispatch : public AttributeDispatch +{ + public: + + typedef void (APIENTRY * F) (I, const T*); + + TemplateTargetAttributeDispatch(I target, F functionPtr, unsigned int stride): + _functionPtr(functionPtr), _target(target), _stride(stride), _array(0) {} + + virtual void assign(const GLvoid* array, const IndexArray*) + { + _array = reinterpret_cast(array); + } + + virtual void operator () (unsigned int pos) + { + _functionPtr(_target, &(_array[pos * _stride])); + } + + GLBeginEndAdapter* _glBeginEndAdapter; + F _functionPtr; + I _target; + unsigned int _stride; + const T* _array; +}; + +template +class TemplateTargetAttributeWithIndicesDispatch : public AttributeDispatch +{ + public: + + typedef void (APIENTRY * F) (I, const T*); + + TemplateTargetAttributeWithIndicesDispatch(I target, F functionPtr, unsigned int stride): + _functionPtr(functionPtr), _target(target), _stride(stride), _array(0), _indices(0) {} + + virtual void assign(const GLvoid* array, const IndexArray* indices) + { + _array = reinterpret_cast(array); + _indices = indices; + } + + virtual void operator () (unsigned int pos) + { + _functionPtr(_target, &(_array[_indices->index(pos) * _stride])); + } + + F _functionPtr; + I _target; + unsigned int _stride; + const T* _array; + const IndexArray* _indices; +}; + + +template +class TemplateBeginEndTargetAttributeDispatch : public AttributeDispatch +{ + public: + + typedef void (GLBeginEndAdapter::*F) (I, const T*); + + TemplateBeginEndTargetAttributeDispatch(GLBeginEndAdapter* glBeginEndAdapter, I target, F functionPtr, unsigned int stride): + _glBeginEndAdapter(glBeginEndAdapter), + _functionPtr(functionPtr), _target(target), _stride(stride), _array(0) {} + + virtual void assign(const GLvoid* array, const IndexArray*) + { + _array = reinterpret_cast(array); + } + + virtual void operator () (unsigned int pos) + { + (_glBeginEndAdapter->*_functionPtr)(_target, &(_array[pos * _stride])); + } + + GLBeginEndAdapter* _glBeginEndAdapter; + F _functionPtr; + I _target; + unsigned int _stride; + const T* _array; +}; + +template +class TemplateBeginEndTargetAttributeWithIndicesDispatch : public AttributeDispatch +{ + public: + + typedef void (GLBeginEndAdapter::*F) (I, const T*); + + TemplateBeginEndTargetAttributeWithIndicesDispatch(GLBeginEndAdapter* glBeginEndAdapter, I target, F functionPtr, unsigned int stride): + _glBeginEndAdapter(glBeginEndAdapter), + _functionPtr(functionPtr), _target(target), _stride(stride), _array(0), _indices(0) {} + + virtual void assign(const GLvoid* array, const IndexArray* indices) + { + _array = reinterpret_cast(array); + _indices = indices; + } + + virtual void operator () (unsigned int pos) + { + (_glBeginEndAdapter->*_functionPtr)(_target, &(_array[_indices->index(pos) * _stride])); + } + + GLBeginEndAdapter* _glBeginEndAdapter; + F _functionPtr; + I _target; + unsigned int _stride; + const T* _array; + const IndexArray* _indices; +}; + +class AttributeDispatchMap +{ +public: + + AttributeDispatchMap(GLBeginEndAdapter* glBeginEndAdapter): + _glBeginEndAdapter(glBeginEndAdapter) {} + + template + void assign(Array::Type type, void (APIENTRY *functionPtr) (const T*), unsigned int stride) + { + if ((unsigned int)type >= _attributeDispatchList.size()) _attributeDispatchList.resize(type+1); + _attributeDispatchList[type] = functionPtr ? new TemplateAttributeDispatch(functionPtr, stride) : 0; + + if ((unsigned int)type >= _attributeDispatchWithIndicesList.size()) _attributeDispatchWithIndicesList.resize(type+1); + _attributeDispatchWithIndicesList[type] = functionPtr ? new TemplateAttributeWithIndicesDispatch(functionPtr, stride) : 0; + } + + template + void targetAssign(I target, Array::Type type, void (APIENTRY *functionPtr) (I, const T*), unsigned int stride) + { + if ((unsigned int)type >= _attributeDispatchList.size()) _attributeDispatchList.resize(type+1); + _attributeDispatchList[type] = functionPtr ? new TemplateTargetAttributeDispatch(target, functionPtr, stride) : 0; + + if ((unsigned int)type >= _attributeDispatchWithIndicesList.size()) _attributeDispatchWithIndicesList.resize(type+1); + _attributeDispatchWithIndicesList[type] = functionPtr ? new TemplateTargetAttributeWithIndicesDispatch(target, functionPtr, stride) : 0; + } + + template + void assignGLBeginEnd(Array::Type type, void (GLBeginEndAdapter::*functionPtr) (const T*), unsigned int stride) + { + if ((unsigned int)type >= _glBeginEndAttributeDispatchList.size()) _glBeginEndAttributeDispatchList.resize(type+1); + _glBeginEndAttributeDispatchList[type] = functionPtr ? new TemplateBeginEndAttributeDispatch(_glBeginEndAdapter, functionPtr, stride) : 0; + + if ((unsigned int)type >= _glBeginEndAttributeDispatchWithIndicesList.size()) _glBeginEndAttributeDispatchWithIndicesList.resize(type+1); + _glBeginEndAttributeDispatchWithIndicesList[type] = functionPtr ? new TemplateBeginEndAttributeWithIndicesDispatch(_glBeginEndAdapter, functionPtr, stride) : 0; + } + + template + void targetGLBeginEndAssign(I target, Array::Type type, void (GLBeginEndAdapter::*functionPtr) (I, const T*), unsigned int stride) + { + if ((unsigned int)type >= _glBeginEndAttributeDispatchList.size()) _glBeginEndAttributeDispatchList.resize(type+1); + _glBeginEndAttributeDispatchList[type] = functionPtr ? new TemplateBeginEndTargetAttributeDispatch(_glBeginEndAdapter, target, functionPtr, stride) : 0; + + if ((unsigned int)type >= _glBeginEndAttributeDispatchWithIndicesList.size()) _glBeginEndAttributeDispatchWithIndicesList.resize(type+1); + _glBeginEndAttributeDispatchWithIndicesList[type] = functionPtr ? new TemplateBeginEndTargetAttributeWithIndicesDispatch(_glBeginEndAdapter, target, functionPtr, stride) : 0; + } + + + AttributeDispatch* dispatcher(bool useGLBeginEndAdapter, const Array* array, const IndexArray* indices) + { + if (!array) return 0; + + Array::Type type = array->getType(); + AttributeDispatch* dispatcher = 0; + if (useGLBeginEndAdapter) + { + if (indices) + { + if ((unsigned int)type<_glBeginEndAttributeDispatchWithIndicesList.size()) + { + dispatcher = _glBeginEndAttributeDispatchWithIndicesList[array->getType()].get(); + } + } + else if ((unsigned int)type<_glBeginEndAttributeDispatchList.size()) + { + dispatcher = _glBeginEndAttributeDispatchList[array->getType()].get(); + } + } + else + { + if (indices) + { + if ((unsigned int)type<_attributeDispatchWithIndicesList.size()) + { + dispatcher = _attributeDispatchWithIndicesList[array->getType()].get(); + } + } + else if ((unsigned int)type<_attributeDispatchList.size()) + { + dispatcher = _attributeDispatchList[array->getType()].get(); + } + } + + if (dispatcher) + { + dispatcher->assign(array->getDataPointer(), indices); + return dispatcher; + } + else + { + return 0; + } + } + + typedef std::vector< ref_ptr > AttributeDispatchList; + GLBeginEndAdapter* _glBeginEndAdapter; + AttributeDispatchList _attributeDispatchList; + AttributeDispatchList _attributeDispatchWithIndicesList; + AttributeDispatchList _glBeginEndAttributeDispatchList; + 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()))) +{ + Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(),true); + _glBeginEndAdapter = &(_state->getGLBeginEndAdapter()); + _useGLBeginEndAdapter = false; + + _vertexDispatchers->assign(Array::Vec2ArrayType, glVertex2fv, 2); + _vertexDispatchers->assign(Array::Vec3ArrayType, glVertex3fv, 3); + _vertexDispatchers->assign(Array::Vec2dArrayType, glVertex2dv, 2); + _vertexDispatchers->assign(Array::Vec3dArrayType, glVertex3dv, 3); + _vertexDispatchers->assignGLBeginEnd(Array::Vec3ArrayType, &GLBeginEndAdapter::Vertex3fv, 3); + + _normalDispatchers->assign(Array::Vec3bArrayType, glNormal3bv, 3); + _normalDispatchers->assign(Array::Vec3sArrayType, glNormal3sv, 3); + _normalDispatchers->assign(Array::Vec3ArrayType, glNormal3fv, 3); + _normalDispatchers->assign(Array::Vec3dArrayType, glNormal3dv, 3); + _normalDispatchers->assignGLBeginEnd(Array::Vec3ArrayType, &GLBeginEndAdapter::Normal3fv, 3); + + _colorDispatchers->assign(Array::Vec3ArrayType, glColor3fv, 3); + _colorDispatchers->assign(Array::Vec4ArrayType, glColor4fv, 4); + _colorDispatchers->assign(Array::Vec3dArrayType, glColor3dv, 3); + _colorDispatchers->assign(Array::Vec4dArrayType, glColor4dv, 4); + _colorDispatchers->assignGLBeginEnd(Array::Vec4ArrayType, &GLBeginEndAdapter::Color4fv, 4); + + _secondaryColorDispatchers->assign(Array::Vec3ArrayType, extensions->_glSecondaryColor3fv, 3); + + _fogCoordDispatchers->assign(Array::FloatArrayType, extensions->_glFogCoordfv, 1); +} + +ArrayDispatchers::~ArrayDispatchers() +{ +} + +AttributeDispatch* ArrayDispatchers::vertexDispatcher(Array* array, IndexArray* indices) { return _vertexDispatchers->dispatcher(_useGLBeginEndAdapter, array, indices); } +AttributeDispatch* ArrayDispatchers::normalDispatcher(Array* array, IndexArray* indices) { return _normalDispatchers->dispatcher(_useGLBeginEndAdapter, array, indices); } +AttributeDispatch* ArrayDispatchers::colorDispatcher(Array* array, IndexArray* indices) { return _colorDispatchers->dispatcher(_useGLBeginEndAdapter, array, indices); } +AttributeDispatch* ArrayDispatchers::secondaryColorDispatcher(Array* array, IndexArray* indices) { return _secondaryColorDispatchers->dispatcher(_useGLBeginEndAdapter, array, indices); } +AttributeDispatch* ArrayDispatchers::fogCoordDispatcher(Array* array, IndexArray* indices) { return _fogCoordDispatchers->dispatcher(_useGLBeginEndAdapter, array, indices); } + +AttributeDispatch* ArrayDispatchers::texCoordDispatcher(unsigned int unit, Array* array, IndexArray* indices) +{ + if (unit>=_texCoordDispatchers.size()) assignTexCoordDispatchers(unit); + return _texCoordDispatchers[unit]->dispatcher(_useGLBeginEndAdapter, array, indices); +} + +AttributeDispatch* ArrayDispatchers::vertexAttribDispatcher(unsigned int unit, Array* array, IndexArray* indices) +{ + if (unit>=_vertexAttribDispatchers.size()) assignVertexAttribDispatchers(unit); + return _vertexAttribDispatchers[unit]->dispatcher(_useGLBeginEndAdapter, array, indices); +} + +void ArrayDispatchers::assignTexCoordDispatchers(unsigned int unit) +{ + Drawable::Extensions* extensions = Drawable::getExtensions(_state->getContextID(),true); + + for(unsigned int i=_texCoordDispatchers.size(); i<=unit; ++i) + { + _texCoordDispatchers.push_back(new AttributeDispatchMap(_glBeginEndAdapter)); + AttributeDispatchMap& texCoordDispatcher = *_texCoordDispatchers[i]; + if (i==0) + { + texCoordDispatcher.assign(Array::FloatArrayType, glTexCoord1fv, 1); + texCoordDispatcher.assign(Array::Vec2ArrayType, glTexCoord2fv, 2); + texCoordDispatcher.assign(Array::Vec3ArrayType, glTexCoord3fv, 3); + texCoordDispatcher.assign(Array::Vec4ArrayType, glTexCoord4fv, 4); + texCoordDispatcher.assignGLBeginEnd(Array::FloatArrayType, &GLBeginEndAdapter::TexCoord1fv, 3); + texCoordDispatcher.assignGLBeginEnd(Array::Vec2ArrayType, &GLBeginEndAdapter::TexCoord2fv, 3); + texCoordDispatcher.assignGLBeginEnd(Array::Vec3ArrayType, &GLBeginEndAdapter::TexCoord3fv, 3); + texCoordDispatcher.assignGLBeginEnd(Array::Vec4ArrayType, &GLBeginEndAdapter::TexCoord4fv, 4); + } + else + { + texCoordDispatcher.targetAssign((GLenum)(GL_TEXTURE0+i), Array::FloatArrayType, extensions->_glMultiTexCoord1fv, 1); + texCoordDispatcher.targetAssign((GLenum)(GL_TEXTURE0+i), Array::Vec2ArrayType, extensions->_glMultiTexCoord2fv, 2); + texCoordDispatcher.targetAssign((GLenum)(GL_TEXTURE0+i), Array::Vec3ArrayType, extensions->_glMultiTexCoord3fv, 3); + texCoordDispatcher.targetAssign((GLenum)(GL_TEXTURE0+i), Array::Vec4ArrayType, extensions->_glMultiTexCoord4fv, 4); + texCoordDispatcher.targetGLBeginEndAssign((GLenum)(GL_TEXTURE0+i), Array::FloatArrayType, &GLBeginEndAdapter::MultiTexCoord1fv, 1); + texCoordDispatcher.targetGLBeginEndAssign((GLenum)(GL_TEXTURE0+i), Array::Vec2ArrayType, &GLBeginEndAdapter::MultiTexCoord2fv, 2); + texCoordDispatcher.targetGLBeginEndAssign((GLenum)(GL_TEXTURE0+i), Array::Vec3ArrayType, &GLBeginEndAdapter::MultiTexCoord3fv, 3); + texCoordDispatcher.targetGLBeginEndAssign((GLenum)(GL_TEXTURE0+i), Array::Vec4ArrayType, &GLBeginEndAdapter::MultiTexCoord4fv, 4); + } + } +} + +void ArrayDispatchers::assignVertexAttribDispatchers(unsigned int unit) +{ + Drawable::Extensions* extensions = Drawable::getExtensions(_state->getContextID(),true); + + for(unsigned int i=_vertexAttribDispatchers.size(); i<=unit; ++i) + { + _vertexAttribDispatchers.push_back(new AttributeDispatchMap(_glBeginEndAdapter)); + AttributeDispatchMap& texCoordDispatcher = *_vertexAttribDispatchers[i]; + texCoordDispatcher.targetAssign(i, Array::FloatArrayType, extensions->_glVertexAttrib1fv, 1); + texCoordDispatcher.targetAssign(i, Array::Vec2ArrayType, extensions->_glVertexAttrib2fv, 2); + texCoordDispatcher.targetAssign(i, Array::Vec3ArrayType, extensions->_glVertexAttrib3fv, 3); + texCoordDispatcher.targetAssign(i, Array::Vec4ArrayType, extensions->_glVertexAttrib4fv, 4); + } +} + +void ArrayDispatchers::reset() +{ + _useGLBeginEndAdapter = false; + + for(BindingGroupList::iterator itr = _bindingGroupList.begin(); + itr != _bindingGroupList.end(); + ++itr) + { + itr->_index = 0; + itr->_attributeDispatchList.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(); +} + +} + diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 43343e674..91f4e2a1f 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -25,6 +25,7 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/ApplicationUsage ${HEADER_PATH}/ArgumentParser ${HEADER_PATH}/Array + ${HEADER_PATH}/ArrayDispatchers ${HEADER_PATH}/AudioStream ${HEADER_PATH}/AutoTransform ${HEADER_PATH}/Billboard @@ -195,6 +196,7 @@ ADD_LIBRARY(${LIB_NAME} ApplicationUsage.cpp ArgumentParser.cpp Array.cpp + ArrayDispatchers.cpp AudioStream.cpp AutoTransform.cpp Billboard.cpp diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index defbf21a9..79a420652 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -934,6 +934,7 @@ void Drawable::Extensions::setupGLExtensions(unsigned int contextID) setGLExtensionFuncPtr(_glSecondaryColor3ubv, "glSecondaryColor3ubv","glSecondaryColor3ubvEXT"); setGLExtensionFuncPtr(_glSecondaryColor3fv, "glSecondaryColor3fv","glSecondaryColor3fvEXT"); setGLExtensionFuncPtr(_glMultiTexCoord1f, "glMultiTexCoord1f","glMultiTexCoord1fARB"); + setGLExtensionFuncPtr(_glMultiTexCoord1fv, "glMultiTexCoord1fv","glMultiTexCoord1fvARB"); setGLExtensionFuncPtr(_glMultiTexCoord2fv, "glMultiTexCoord2fv","glMultiTexCoord2fvARB"); setGLExtensionFuncPtr(_glMultiTexCoord3fv, "glMultiTexCoord3fv","glMultiTexCoord3fvARB"); setGLExtensionFuncPtr(_glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB"); @@ -945,6 +946,7 @@ void Drawable::Extensions::setupGLExtensions(unsigned int contextID) setGLExtensionFuncPtr(_glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB"); setGLExtensionFuncPtr(_glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB"); setGLExtensionFuncPtr(_glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB"); + setGLExtensionFuncPtr(_glVertexAttrib1fv, "glVertexAttrib1fv","glVertexAttrib1fvARB"); setGLExtensionFuncPtr(_glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB"); setGLExtensionFuncPtr(_glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB"); setGLExtensionFuncPtr(_glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB"); diff --git a/src/osg/GLBeginEndAdapter.cpp b/src/osg/GLBeginEndAdapter.cpp index da063d91b..eb281997c 100644 --- a/src/osg/GLBeginEndAdapter.cpp +++ b/src/osg/GLBeginEndAdapter.cpp @@ -97,18 +97,6 @@ void GLBeginEndAdapter::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble _matrixStack.back().preMultRotate(Quat(DegreesToRadians(angle), Vec3d(x,y,z))); } -void GLBeginEndAdapter::Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) -{ - _normalAssigned = true; - _color.set(red,green,blue,alpha); -} - -void GLBeginEndAdapter::Normal3f(GLfloat x, GLfloat y, GLfloat z) -{ - _normalAssigned = true; - _normal.set(x,y,z); -} - void GLBeginEndAdapter::MultiTexCoord4f(unsigned int unit, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { if (unit>=_texCoordAssignedList.size()) _texCoordAssignedList.resize(unit+1, false); @@ -133,7 +121,6 @@ void GLBeginEndAdapter::Vertex3f(GLfloat x, GLfloat y, GLfloat z) if (!_vertices) _vertices = new osg::Vec3Array; - if (_normalAssigned) { if (!_normals) _normals = new osg::Vec3Array; diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index a60386172..4a85a50ca 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -13,6 +13,7 @@ #include #include +#include #include using namespace osg; @@ -223,7 +224,7 @@ class DrawVertexAttrib : public osg::Referenced, public osg::ConstValueVisitor { public: - DrawVertexAttrib(const Drawable::Extensions * extensions,unsigned int vertAttribIndex,GLboolean normalized,const Array* attribcoords,const IndexArray* indices): + DrawVertexAttrib(const Drawable::Extensions * extensions,unsigned int vertAttribIndex,GLboolean normalized,const Array* attribcoords,const IndexArray* indices): _vertAttribIndex(vertAttribIndex), _normalized(normalized), _extensions(extensions), @@ -336,7 +337,7 @@ class DrawMultiTexCoord : public osg::Referenced, public osg::ConstValueVisitor virtual void apply(const Vec3& v) { _extensions->glMultiTexCoord3fv(_target,v.ptr()); } virtual void apply(const Vec4& v) { _extensions->glMultiTexCoord4fv(_target,v.ptr()); } - GLenum _target; + GLenum _target; const Array* _texcoords; const IndexArray* _indices; @@ -412,6 +413,9 @@ Geometry::Vec3ArrayData::Vec3ArrayData(const Vec3ArrayData& data,const CopyOp& c Geometry::Geometry() { + // temporary test + // setSupportsDisplayList(false); + _fastPath = false; _fastPathHint = true; } @@ -426,6 +430,9 @@ Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): _fastPath(geometry._fastPath), _fastPathHint(geometry._fastPathHint) { + // temporary test + // setSupportsDisplayList(false); + for(PrimitiveSetList::const_iterator pitr=geometry._primitives.begin(); pitr!=geometry._primitives.end(); ++pitr) @@ -1272,10 +1279,264 @@ void Geometry::releaseGLObjects(State* state) const } +#if 1 void Geometry::drawImplementation(RenderInfo& renderInfo) const { State& state = *renderInfo.getState(); bool vertexAttribAlias = state.getUseVertexAttributeAliasing(); + Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(),true); + + bool useFastPath = areFastPathsUsed(); + bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported(); + bool handleVertexAttributes = !_vertexAttribList.empty() && extensions->isVertexProgramSupported(); + + osg::ref_ptr s_ArrayDispatchers = 0; + if (!s_ArrayDispatchers) s_ArrayDispatchers = new ArrayDispatchers(state); + + ArrayDispatchers& arrayDispatchers = *s_ArrayDispatchers; + + arrayDispatchers.reset(); + arrayDispatchers.setUseGLBeginEndAdapter(!useFastPath); + + arrayDispatchers.activateNormalArray(_normalData.binding, _normalData.array.get(), _normalData.indices.get()); + arrayDispatchers.activateColorArray(_colorData.binding, _colorData.array.get(), _colorData.indices.get()); + arrayDispatchers.activateSecondaryColorArray(_secondaryColorData.binding, _secondaryColorData.array.get(), _secondaryColorData.indices.get()); + arrayDispatchers.activateFogCoordArray(_fogCoordData.binding, _fogCoordData.array.get(), _fogCoordData.indices.get()); + + for(unsigned int unit=0;unit<_texCoordList.size();++unit) + { + arrayDispatchers.activateTexCoordArray(BIND_PER_VERTEX, unit, _texCoordList[unit].array.get(), _texCoordList[unit].indices.get()); + } + + for(unsigned int unit=0;unit<_vertexAttribList.size();++unit) + { + arrayDispatchers.activateVertexAttribArray(_vertexAttribList[unit].binding, unit, _vertexAttribList[unit].array.get(), _vertexAttribList[unit].indices.get()); + } + + arrayDispatchers.activateVertexArray(BIND_PER_VERTEX, _vertexData.array.get(), _vertexData.indices.get()); + + + // dispatch any attributes that are bound overall + arrayDispatchers.dispatch(BIND_OVERALL); + + state.lazyDisablingOfVertexAttributes(); + + if (useFastPath) + { + // set up arrays + if( _vertexData.array.valid() ) + state.setVertexPointer(_vertexData.array.get()); + + if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) + state.setNormalPointer(_normalData.array.get()); + + if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) + state.setColorPointer(_colorData.array.get()); + + if (_secondaryColorData.binding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) + state.setSecondaryColorPointer(_secondaryColorData.array.get()); + + if (_fogCoordData.binding==BIND_PER_VERTEX && _fogCoordData.array.valid()) + state.setFogCoordPointer(_fogCoordData.array.get()); + + for(unsigned int unit=0;unit<_texCoordList.size();++unit) + { + const Array* array = _texCoordList[unit].array.get(); + if (array) state.setTexCoordPointer(unit,array); + } + + if( handleVertexAttributes ) + { + for(unsigned int index = 0; index < _vertexAttribList.size(); ++index ) + { + const Array* array = _vertexAttribList[index].array.get(); + const AttributeBinding ab = _vertexAttribList[index].binding; + if( ab == BIND_PER_VERTEX && array ) + { + state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize ); + } + } + } + } + + state.applyDisablingOfVertexAttributes(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // draw the primitives themselves. + // + for(PrimitiveSetList::const_iterator itr=_primitives.begin(); + itr!=_primitives.end(); + ++itr) + { + // dispatch any attributes that are bound per primitive + arrayDispatchers.dispatch(BIND_PER_PRIMITIVE_SET); + + const PrimitiveSet* primitiveset = itr->get(); + + if (useFastPath) + { + primitiveset->draw(state, usingVertexBufferObjects); + } + else + { + GLenum mode=primitiveset->getMode(); + + unsigned int primLength; + switch(mode) + { + case(GL_POINTS): primLength=1; break; + case(GL_LINES): primLength=2; break; + case(GL_TRIANGLES): primLength=3; break; + case(GL_QUADS): primLength=4; break; + default: primLength=0; break; // compute later when =0. + } + + // draw primitives by the more flexible "slow" path, + // sending OpenGL glBegin/glVertex.../glEnd(). + switch(primitiveset->getType()) + { + case(PrimitiveSet::DrawArraysPrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawArrays* drawArray = static_cast(primitiveset); + arrayDispatchers.Begin(mode); + + unsigned int primCount=0; + unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); + vindex(primitiveset); + unsigned int vindex=drawArrayLengths->getFirst(); + for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); + primItr!=drawArrayLengths->end(); + ++primItr) + { + unsigned int localPrimLength; + if (primLength==0) localPrimLength=*primItr; + else localPrimLength=primLength; + + arrayDispatchers.Begin(mode); + + for(GLsizei primCount=0; + primCount<*primItr; + ++vindex,++primCount) + { + if ((primCount%localPrimLength)==0) + { + arrayDispatchers.dispatch(BIND_PER_PRIMITIVE); + } + arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); + } + + arrayDispatchers.End(); + + } + break; + } + case(PrimitiveSet::DrawElementsUBytePrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawElementsUByte* drawElements = static_cast(primitiveset); + arrayDispatchers.Begin(mode); + + unsigned int primCount=0; + for(DrawElementsUByte::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + + if ((primCount%primLength)==0) + { + arrayDispatchers.dispatch(BIND_PER_PRIMITIVE); + } + + unsigned int vindex=*primItr; + arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); + } + + arrayDispatchers.End(); + break; + } + case(PrimitiveSet::DrawElementsUShortPrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawElementsUShort* drawElements = static_cast(primitiveset); + arrayDispatchers.Begin(mode); + + unsigned int primCount=0; + for(DrawElementsUShort::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + if ((primCount%primLength)==0) + { + arrayDispatchers.dispatch(BIND_PER_PRIMITIVE); + } + + unsigned int vindex=*primItr; + arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); + } + + arrayDispatchers.End(); + break; + } + case(PrimitiveSet::DrawElementsUIntPrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawElementsUInt* drawElements = static_cast(primitiveset); + arrayDispatchers.Begin(mode); + + unsigned int primCount=0; + for(DrawElementsUInt::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + if ((primCount%primLength)==0) + { + arrayDispatchers.dispatch(BIND_PER_PRIMITIVE); + } + + unsigned int vindex=*primItr; + arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex); + } + + arrayDispatchers.End(); + break; + } + default: + { + break; + } + } + } + } +} +#else +void Geometry::drawImplementation(RenderInfo& renderInfo) const +{ + State& state = *renderInfo.getState(); + bool vertexAttribAlias = state.getUseVertexAttributeAliasing(); + // unsigned int contextID = state.getContextID(); @@ -1338,6 +1599,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const } + unsigned int normalIndex = 0; unsigned int colorIndex = 0; unsigned int secondaryColorIndex = 0; @@ -1366,14 +1628,12 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const { if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX) { - osg::notify(osg::NOTICE)<<"normal assign"<getType()) @@ -2167,6 +2428,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const } } +#endif class AttributeFunctorArrayVisitor : public ArrayVisitor {