Refactored osg::Geometry::drawImplementation(..) to use new osg::ArrayDispatchers that encapsulate the task

of dispatch osg::Array data as OpenGL attributes.
This commit is contained in:
Robert Osfield 2009-10-20 19:34:24 +00:00
parent b0057e258c
commit 6a56b6e6be
11 changed files with 934 additions and 41 deletions

View File

@ -71,14 +71,14 @@ class OSG_EXPORT Array : public BufferData
DoubleArrayType = 18, DoubleArrayType = 18,
Vec2dArrayType = 19, Vec2dArrayType = 19,
Vec3dArrayType = 20, Vec3dArrayType = 20,
Vec4dArrayType = 21 Vec4dArrayType = 21
}; };
Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0):
_arrayType(arrayType), _arrayType(arrayType),
_dataSize(dataSize), _dataSize(dataSize),
_dataType(dataType) {} _dataType(dataType) {}
Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
BufferData(array,copyop), BufferData(array,copyop),
_arrayType(array._arrayType), _arrayType(array._arrayType),
@ -88,7 +88,7 @@ class OSG_EXPORT Array : public BufferData
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Array*>(obj)!=NULL; } virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Array*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osg"; } virtual const char* libraryName() const { return "osg"; }
virtual const char* className() const; virtual const char* className() const;
virtual void accept(ArrayVisitor&) = 0; virtual void accept(ArrayVisitor&) = 0;
virtual void accept(ConstArrayVisitor&) const = 0; virtual void accept(ConstArrayVisitor&) const = 0;
@ -131,13 +131,13 @@ template<typename T, Array::Type ARRAYTYPE, int DataSize, int DataType>
class TemplateArray : public Array, public MixinVector<T> class TemplateArray : public Array, public MixinVector<T>
{ {
public: public:
TemplateArray() : Array(ARRAYTYPE,DataSize,DataType) {} TemplateArray() : Array(ARRAYTYPE,DataSize,DataType) {}
TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Array(ta,copyop), Array(ta,copyop),
MixinVector<T>(ta) {} MixinVector<T>(ta) {}
TemplateArray(unsigned int no) : TemplateArray(unsigned int no) :
Array(ARRAYTYPE,DataSize,DataType), Array(ARRAYTYPE,DataSize,DataType),
MixinVector<T>(no) {} MixinVector<T>(no) {}
@ -181,7 +181,7 @@ class TemplateArray : public Array, public MixinVector<T>
{ {
MixinVector<T>( *this ).swap( *this ); MixinVector<T>( *this ).swap( *this );
} }
virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; }
virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); } virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); }
virtual unsigned int getNumElements() const { return static_cast<unsigned int>(this->size()); } virtual unsigned int getNumElements() const { return static_cast<unsigned int>(this->size()); }
@ -200,16 +200,16 @@ class OSG_EXPORT IndexArray : public Array
IndexArray(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0): IndexArray(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0):
Array(arrayType,dataSize,dataType) {} Array(arrayType,dataSize,dataType) {}
IndexArray(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): IndexArray(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Array(array,copyop) {} Array(array,copyop) {}
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const IndexArray*>(obj)!=NULL; } virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const IndexArray*>(obj)!=NULL; }
virtual unsigned int index(unsigned int pos) const = 0; virtual unsigned int index(unsigned int pos) const = 0;
protected: protected:
virtual ~IndexArray() {} virtual ~IndexArray() {}
}; };
@ -217,13 +217,13 @@ template<typename T, Array::Type ARRAYTYPE, int DataSize, int DataType>
class TemplateIndexArray : public IndexArray, public MixinVector<T> class TemplateIndexArray : public IndexArray, public MixinVector<T>
{ {
public: public:
TemplateIndexArray() : IndexArray(ARRAYTYPE,DataSize,DataType) {} TemplateIndexArray() : IndexArray(ARRAYTYPE,DataSize,DataType) {}
TemplateIndexArray(const TemplateIndexArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY): TemplateIndexArray(const TemplateIndexArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
IndexArray(ta,copyop), IndexArray(ta,copyop),
MixinVector<T>(ta) {} MixinVector<T>(ta) {}
TemplateIndexArray(unsigned int no) : TemplateIndexArray(unsigned int no) :
IndexArray(ARRAYTYPE,DataSize,DataType), IndexArray(ARRAYTYPE,DataSize,DataType),
MixinVector<T>(no) {} MixinVector<T>(no) {}
@ -267,7 +267,7 @@ class TemplateIndexArray : public IndexArray, public MixinVector<T>
{ {
MixinVector<T>( *this ).swap( *this ); MixinVector<T>( *this ).swap( *this );
} }
virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; } virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; }
virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); } virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); }
virtual unsigned int getNumElements() const { return static_cast<unsigned int>(this->size()); } virtual unsigned int getNumElements() const { return static_cast<unsigned int>(this->size()); }
@ -277,7 +277,7 @@ class TemplateIndexArray : public IndexArray, public MixinVector<T>
typedef T ElementDataType; // expose T typedef T ElementDataType; // expose T
protected: protected:
virtual ~TemplateIndexArray() {} virtual ~TemplateIndexArray() {}
}; };

View File

@ -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 <osg/ref_ptr>
#include <osg/Array>
#include <osg/Matrixd>
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<AttributeDispatchMap*> AttributeDispatchMapList;
AttributeDispatchMapList _texCoordDispatchers;
AttributeDispatchMapList _vertexAttribDispatchers;
typedef std::vector<AttributeDispatch*> AttributeDispatchList;
struct BindingGroup
{
unsigned int _index;
AttributeDispatchList _attributeDispatchList;
};
typedef std::vector<BindingGroup> BindingGroupList;
BindingGroupList _bindingGroupList;
bool _useGLBeginEndAdapter;
};
}
#endif

View File

@ -666,7 +666,7 @@ class OSG_EXPORT Drawable : public Object
void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) const; void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) const;
void glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) const; void glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) const;
protected: public:
typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord); typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord);
@ -735,9 +735,11 @@ class OSG_EXPORT Drawable : public Object
VertexAttrib1sProc _glVertexAttrib1s; VertexAttrib1sProc _glVertexAttrib1s;
VertexAttrib1fProc _glVertexAttrib1f; VertexAttrib1fProc _glVertexAttrib1f;
VertexAttrib1dProc _glVertexAttrib1d; VertexAttrib1dProc _glVertexAttrib1d;
VertexAttribfvProc _glVertexAttrib1fv;
VertexAttribfvProc _glVertexAttrib2fv; VertexAttribfvProc _glVertexAttrib2fv;
VertexAttribfvProc _glVertexAttrib3fv; VertexAttribfvProc _glVertexAttrib3fv;
VertexAttribfvProc _glVertexAttrib4fv; VertexAttribfvProc _glVertexAttrib4fv;
VertexAttribdvProc _glVertexAttrib1dv;
VertexAttribdvProc _glVertexAttrib2dv; VertexAttribdvProc _glVertexAttrib2dv;
VertexAttribdvProc _glVertexAttrib3dv; VertexAttribdvProc _glVertexAttrib3dv;
VertexAttribdvProc _glVertexAttrib4dv; VertexAttribdvProc _glVertexAttrib4dv;
@ -745,10 +747,12 @@ class OSG_EXPORT Drawable : public Object
VertexAttribubvProc _glVertexAttrib4Nubv; VertexAttribubvProc _glVertexAttrib4Nubv;
MultiTexCoord1fProc _glMultiTexCoord1f; MultiTexCoord1fProc _glMultiTexCoord1f;
MultiTexCoordfvProc _glMultiTexCoord1fv;
MultiTexCoordfvProc _glMultiTexCoord2fv; MultiTexCoordfvProc _glMultiTexCoord2fv;
MultiTexCoordfvProc _glMultiTexCoord3fv; MultiTexCoordfvProc _glMultiTexCoord3fv;
MultiTexCoordfvProc _glMultiTexCoord4fv; MultiTexCoordfvProc _glMultiTexCoord4fv;
MultiTexCoord1dProc _glMultiTexCoord1d; MultiTexCoord1dProc _glMultiTexCoord1d;
MultiTexCoorddvProc _glMultiTexCoord1dv;
MultiTexCoorddvProc _glMultiTexCoord2dv; MultiTexCoorddvProc _glMultiTexCoord2dv;
MultiTexCoorddvProc _glMultiTexCoord3dv; MultiTexCoorddvProc _glMultiTexCoord3dv;
MultiTexCoorddvProc _glMultiTexCoord4dv; MultiTexCoorddvProc _glMultiTexCoord4dv;

View File

@ -54,13 +54,23 @@ class OSG_EXPORT GLBeginEndAdapter
void Scaled(GLdouble x, GLdouble y, GLdouble z); void Scaled(GLdouble x, GLdouble y, GLdouble z);
void Rotated(GLdouble angle, 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 Vertex3f(GLfloat x, GLfloat y, GLfloat z);
void Vertex3fv(const GLfloat* v) { Vertex3f(v[0], v[1], v[2]); } 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 Normal3fv(const GLfloat* n) { Normal3f(n[0], n[1], n[2]); }
void TexCoord1f(GLfloat x) { MultiTexCoord4f(0, x, 0.0f, 0.0f, 1.0f); } void TexCoord1f(GLfloat x) { MultiTexCoord4f(0, x, 0.0f, 0.0f, 1.0f); }
@ -140,7 +150,6 @@ class OSG_EXPORT GLBeginEndAdapter
VertexArrayList _vertexAttribsList; VertexArrayList _vertexAttribsList;
}; };
} }
#endif #endif

View File

@ -476,13 +476,13 @@ class OSG_EXPORT State : public Referenced, public Observer
else glNormal3f(x,y,z); 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); if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w);
else glTexCoord4f(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); if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w);
else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w); else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w);

View File

@ -25,7 +25,7 @@ echo osgcallback
osgcallback osgcallback
echo osgcatch echo osgcatch
osgcatch # osgcatch
echo osgclip echo osgclip
osgclip osgclip

View File

@ -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 <osg/ArrayDispatchers>
#include <osg/State>
#include <osg/Drawable>
#include <osg/Notify>
#include <osg/io_utils>
namespace osg
{
template<typename T>
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<const T*>(array);
}
virtual void operator () (unsigned int pos)
{
_functionPtr(&(_array[pos*_stride]));
}
F _functionPtr;
unsigned int _stride;
const T* _array;
};
template<typename T>
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<const T*>(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<typename T>
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<const T*>(array);
}
virtual void operator () (unsigned int pos)
{
(_glBeginEndAdapter->*_functionPtr)(&(_array[pos*_stride]));
}
GLBeginEndAdapter* _glBeginEndAdapter;
F _functionPtr;
unsigned int _stride;
const T* _array;
};
template<typename T>
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<const T*>(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<typename I, typename T>
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<const T*>(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<typename I, typename T>
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<const T*>(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<typename I, typename T>
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<const T*>(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<typename I, typename T>
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<const T*>(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<typename T>
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<T>(functionPtr, stride) : 0;
if ((unsigned int)type >= _attributeDispatchWithIndicesList.size()) _attributeDispatchWithIndicesList.resize(type+1);
_attributeDispatchWithIndicesList[type] = functionPtr ? new TemplateAttributeWithIndicesDispatch<T>(functionPtr, stride) : 0;
}
template<typename I, typename T>
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<I,T>(target, functionPtr, stride) : 0;
if ((unsigned int)type >= _attributeDispatchWithIndicesList.size()) _attributeDispatchWithIndicesList.resize(type+1);
_attributeDispatchWithIndicesList[type] = functionPtr ? new TemplateTargetAttributeWithIndicesDispatch<I,T>(target, functionPtr, stride) : 0;
}
template<typename T>
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<T>(_glBeginEndAdapter, functionPtr, stride) : 0;
if ((unsigned int)type >= _glBeginEndAttributeDispatchWithIndicesList.size()) _glBeginEndAttributeDispatchWithIndicesList.resize(type+1);
_glBeginEndAttributeDispatchWithIndicesList[type] = functionPtr ? new TemplateBeginEndAttributeWithIndicesDispatch<T>(_glBeginEndAdapter, functionPtr, stride) : 0;
}
template<typename I, typename T>
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<I,T>(_glBeginEndAdapter, target, functionPtr, stride) : 0;
if ((unsigned int)type >= _glBeginEndAttributeDispatchWithIndicesList.size()) _glBeginEndAttributeDispatchWithIndicesList.resize(type+1);
_glBeginEndAttributeDispatchWithIndicesList[type] = functionPtr ? new TemplateBeginEndTargetAttributeWithIndicesDispatch<I,T>(_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<AttributeDispatch> > 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<GLfloat>(Array::Vec2ArrayType, glVertex2fv, 2);
_vertexDispatchers->assign<GLfloat>(Array::Vec3ArrayType, glVertex3fv, 3);
_vertexDispatchers->assign<GLdouble>(Array::Vec2dArrayType, glVertex2dv, 2);
_vertexDispatchers->assign<GLdouble>(Array::Vec3dArrayType, glVertex3dv, 3);
_vertexDispatchers->assignGLBeginEnd<GLfloat>(Array::Vec3ArrayType, &GLBeginEndAdapter::Vertex3fv, 3);
_normalDispatchers->assign<GLbyte>(Array::Vec3bArrayType, glNormal3bv, 3);
_normalDispatchers->assign<GLshort>(Array::Vec3sArrayType, glNormal3sv, 3);
_normalDispatchers->assign<GLfloat>(Array::Vec3ArrayType, glNormal3fv, 3);
_normalDispatchers->assign<GLdouble>(Array::Vec3dArrayType, glNormal3dv, 3);
_normalDispatchers->assignGLBeginEnd<GLfloat>(Array::Vec3ArrayType, &GLBeginEndAdapter::Normal3fv, 3);
_colorDispatchers->assign<GLfloat>(Array::Vec3ArrayType, glColor3fv, 3);
_colorDispatchers->assign<GLfloat>(Array::Vec4ArrayType, glColor4fv, 4);
_colorDispatchers->assign<GLdouble>(Array::Vec3dArrayType, glColor3dv, 3);
_colorDispatchers->assign<GLdouble>(Array::Vec4dArrayType, glColor4dv, 4);
_colorDispatchers->assignGLBeginEnd<GLfloat>(Array::Vec4ArrayType, &GLBeginEndAdapter::Color4fv, 4);
_secondaryColorDispatchers->assign<GLfloat>(Array::Vec3ArrayType, extensions->_glSecondaryColor3fv, 3);
_fogCoordDispatchers->assign<GLfloat>(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<GLfloat>(Array::FloatArrayType, glTexCoord1fv, 1);
texCoordDispatcher.assign<GLfloat>(Array::Vec2ArrayType, glTexCoord2fv, 2);
texCoordDispatcher.assign<GLfloat>(Array::Vec3ArrayType, glTexCoord3fv, 3);
texCoordDispatcher.assign<GLfloat>(Array::Vec4ArrayType, glTexCoord4fv, 4);
texCoordDispatcher.assignGLBeginEnd<GLfloat>(Array::FloatArrayType, &GLBeginEndAdapter::TexCoord1fv, 3);
texCoordDispatcher.assignGLBeginEnd<GLfloat>(Array::Vec2ArrayType, &GLBeginEndAdapter::TexCoord2fv, 3);
texCoordDispatcher.assignGLBeginEnd<GLfloat>(Array::Vec3ArrayType, &GLBeginEndAdapter::TexCoord3fv, 3);
texCoordDispatcher.assignGLBeginEnd<GLfloat>(Array::Vec4ArrayType, &GLBeginEndAdapter::TexCoord4fv, 4);
}
else
{
texCoordDispatcher.targetAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::FloatArrayType, extensions->_glMultiTexCoord1fv, 1);
texCoordDispatcher.targetAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::Vec2ArrayType, extensions->_glMultiTexCoord2fv, 2);
texCoordDispatcher.targetAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::Vec3ArrayType, extensions->_glMultiTexCoord3fv, 3);
texCoordDispatcher.targetAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::Vec4ArrayType, extensions->_glMultiTexCoord4fv, 4);
texCoordDispatcher.targetGLBeginEndAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::FloatArrayType, &GLBeginEndAdapter::MultiTexCoord1fv, 1);
texCoordDispatcher.targetGLBeginEndAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::Vec2ArrayType, &GLBeginEndAdapter::MultiTexCoord2fv, 2);
texCoordDispatcher.targetGLBeginEndAssign<GLenum, GLfloat>((GLenum)(GL_TEXTURE0+i), Array::Vec3ArrayType, &GLBeginEndAdapter::MultiTexCoord3fv, 3);
texCoordDispatcher.targetGLBeginEndAssign<GLenum, GLfloat>((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<unsigned int, GLfloat>(i, Array::FloatArrayType, extensions->_glVertexAttrib1fv, 1);
texCoordDispatcher.targetAssign<unsigned int, GLfloat>(i, Array::Vec2ArrayType, extensions->_glVertexAttrib2fv, 2);
texCoordDispatcher.targetAssign<unsigned int, GLfloat>(i, Array::Vec3ArrayType, extensions->_glVertexAttrib3fv, 3);
texCoordDispatcher.targetAssign<unsigned int, GLfloat>(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();
}
}

View File

@ -25,6 +25,7 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/ApplicationUsage ${HEADER_PATH}/ApplicationUsage
${HEADER_PATH}/ArgumentParser ${HEADER_PATH}/ArgumentParser
${HEADER_PATH}/Array ${HEADER_PATH}/Array
${HEADER_PATH}/ArrayDispatchers
${HEADER_PATH}/AudioStream ${HEADER_PATH}/AudioStream
${HEADER_PATH}/AutoTransform ${HEADER_PATH}/AutoTransform
${HEADER_PATH}/Billboard ${HEADER_PATH}/Billboard
@ -195,6 +196,7 @@ ADD_LIBRARY(${LIB_NAME}
ApplicationUsage.cpp ApplicationUsage.cpp
ArgumentParser.cpp ArgumentParser.cpp
Array.cpp Array.cpp
ArrayDispatchers.cpp
AudioStream.cpp AudioStream.cpp
AutoTransform.cpp AutoTransform.cpp
Billboard.cpp Billboard.cpp

View File

@ -934,6 +934,7 @@ void Drawable::Extensions::setupGLExtensions(unsigned int contextID)
setGLExtensionFuncPtr(_glSecondaryColor3ubv, "glSecondaryColor3ubv","glSecondaryColor3ubvEXT"); setGLExtensionFuncPtr(_glSecondaryColor3ubv, "glSecondaryColor3ubv","glSecondaryColor3ubvEXT");
setGLExtensionFuncPtr(_glSecondaryColor3fv, "glSecondaryColor3fv","glSecondaryColor3fvEXT"); setGLExtensionFuncPtr(_glSecondaryColor3fv, "glSecondaryColor3fv","glSecondaryColor3fvEXT");
setGLExtensionFuncPtr(_glMultiTexCoord1f, "glMultiTexCoord1f","glMultiTexCoord1fARB"); setGLExtensionFuncPtr(_glMultiTexCoord1f, "glMultiTexCoord1f","glMultiTexCoord1fARB");
setGLExtensionFuncPtr(_glMultiTexCoord1fv, "glMultiTexCoord1fv","glMultiTexCoord1fvARB");
setGLExtensionFuncPtr(_glMultiTexCoord2fv, "glMultiTexCoord2fv","glMultiTexCoord2fvARB"); setGLExtensionFuncPtr(_glMultiTexCoord2fv, "glMultiTexCoord2fv","glMultiTexCoord2fvARB");
setGLExtensionFuncPtr(_glMultiTexCoord3fv, "glMultiTexCoord3fv","glMultiTexCoord3fvARB"); setGLExtensionFuncPtr(_glMultiTexCoord3fv, "glMultiTexCoord3fv","glMultiTexCoord3fvARB");
setGLExtensionFuncPtr(_glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB"); setGLExtensionFuncPtr(_glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB");
@ -945,6 +946,7 @@ void Drawable::Extensions::setupGLExtensions(unsigned int contextID)
setGLExtensionFuncPtr(_glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB"); setGLExtensionFuncPtr(_glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB");
setGLExtensionFuncPtr(_glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB"); setGLExtensionFuncPtr(_glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB");
setGLExtensionFuncPtr(_glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB"); setGLExtensionFuncPtr(_glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB");
setGLExtensionFuncPtr(_glVertexAttrib1fv, "glVertexAttrib1fv","glVertexAttrib1fvARB");
setGLExtensionFuncPtr(_glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB"); setGLExtensionFuncPtr(_glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB");
setGLExtensionFuncPtr(_glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB"); setGLExtensionFuncPtr(_glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB");
setGLExtensionFuncPtr(_glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB"); setGLExtensionFuncPtr(_glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB");

View File

@ -97,18 +97,6 @@ void GLBeginEndAdapter::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble
_matrixStack.back().preMultRotate(Quat(DegreesToRadians(angle), Vec3d(x,y,z))); _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) void GLBeginEndAdapter::MultiTexCoord4f(unsigned int unit, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{ {
if (unit>=_texCoordAssignedList.size()) _texCoordAssignedList.resize(unit+1, false); 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 (!_vertices) _vertices = new osg::Vec3Array;
if (_normalAssigned) if (_normalAssigned)
{ {
if (!_normals) _normals = new osg::Vec3Array; if (!_normals) _normals = new osg::Vec3Array;

View File

@ -13,6 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <osg/Geometry> #include <osg/Geometry>
#include <osg/ArrayDispatchers>
#include <osg/Notify> #include <osg/Notify>
using namespace osg; using namespace osg;
@ -223,7 +224,7 @@ class DrawVertexAttrib : public osg::Referenced, public osg::ConstValueVisitor
{ {
public: 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), _vertAttribIndex(vertAttribIndex),
_normalized(normalized), _normalized(normalized),
_extensions(extensions), _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 Vec3& v) { _extensions->glMultiTexCoord3fv(_target,v.ptr()); }
virtual void apply(const Vec4& v) { _extensions->glMultiTexCoord4fv(_target,v.ptr()); } virtual void apply(const Vec4& v) { _extensions->glMultiTexCoord4fv(_target,v.ptr()); }
GLenum _target; GLenum _target;
const Array* _texcoords; const Array* _texcoords;
const IndexArray* _indices; const IndexArray* _indices;
@ -412,6 +413,9 @@ Geometry::Vec3ArrayData::Vec3ArrayData(const Vec3ArrayData& data,const CopyOp& c
Geometry::Geometry() Geometry::Geometry()
{ {
// temporary test
// setSupportsDisplayList(false);
_fastPath = false; _fastPath = false;
_fastPathHint = true; _fastPathHint = true;
} }
@ -426,6 +430,9 @@ Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
_fastPath(geometry._fastPath), _fastPath(geometry._fastPath),
_fastPathHint(geometry._fastPathHint) _fastPathHint(geometry._fastPathHint)
{ {
// temporary test
// setSupportsDisplayList(false);
for(PrimitiveSetList::const_iterator pitr=geometry._primitives.begin(); for(PrimitiveSetList::const_iterator pitr=geometry._primitives.begin();
pitr!=geometry._primitives.end(); pitr!=geometry._primitives.end();
++pitr) ++pitr)
@ -1272,10 +1279,264 @@ void Geometry::releaseGLObjects(State* state) const
} }
#if 1
void Geometry::drawImplementation(RenderInfo& renderInfo) const void Geometry::drawImplementation(RenderInfo& renderInfo) const
{ {
State& state = *renderInfo.getState(); State& state = *renderInfo.getState();
bool vertexAttribAlias = state.getUseVertexAttributeAliasing(); 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<ArrayDispatchers> 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<const DrawArrays*>(primitiveset);
arrayDispatchers.Begin(mode);
unsigned int primCount=0;
unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount();
for(unsigned int vindex=drawArray->getFirst();
vindex<indexEnd;
++vindex,++primCount)
{
if ((primCount%primLength)==0)
{
arrayDispatchers.dispatch(BIND_PER_PRIMITIVE);
}
arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex);
}
arrayDispatchers.End();
break;
}
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
{
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(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<const DrawElementsUByte*>(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<const DrawElementsUShort*>(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<const DrawElementsUInt*>(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(); // unsigned int contextID = state.getContextID();
@ -1338,6 +1599,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
} }
unsigned int normalIndex = 0; unsigned int normalIndex = 0;
unsigned int colorIndex = 0; unsigned int colorIndex = 0;
unsigned int secondaryColorIndex = 0; unsigned int secondaryColorIndex = 0;
@ -1366,14 +1628,12 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
{ {
if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX) if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX)
{ {
osg::notify(osg::NOTICE)<<"normal assign"<<std::endl;
drawVertexAttribMap[normalBinding].push_back( new DrawVertexAttrib(extensions,2,false,_normalData.array.get(),_normalData.indices.get()) ); drawVertexAttribMap[normalBinding].push_back( new DrawVertexAttrib(extensions,2,false,_normalData.array.get(),_normalData.indices.get()) );
normalBinding = BIND_OFF; normalBinding = BIND_OFF;
} }
if (colorBinding!=BIND_OFF && colorBinding!=BIND_PER_VERTEX) if (colorBinding!=BIND_OFF && colorBinding!=BIND_PER_VERTEX)
{ {
osg::notify(osg::NOTICE)<<"color assign"<<std::endl;
drawVertexAttribMap[colorBinding].push_back( new DrawVertexAttrib(extensions,3,false,_colorData.array.get(),_colorData.indices.get()) ); drawVertexAttribMap[colorBinding].push_back( new DrawVertexAttrib(extensions,3,false,_colorData.array.get(),_colorData.indices.get()) );
colorBinding = BIND_OFF; colorBinding = BIND_OFF;
} }
@ -1382,8 +1642,10 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
fogCoordBinding = BIND_OFF; fogCoordBinding = BIND_OFF;
} }
// force the use of the slow path code to test the glBegin/glEnd replacement codes.
bool forceSlowPath = false;
if (areFastPathsUsed()) if (areFastPathsUsed() && !forceSlowPath)
{ {
#define USE_LAZY_DISABLING #define USE_LAZY_DISABLING
@ -1814,7 +2076,6 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
default: primLength=0; break; // compute later when =0. default: primLength=0; break; // compute later when =0.
} }
// draw primitives by the more flexible "slow" path, // draw primitives by the more flexible "slow" path,
// sending OpenGL glBegin/glVertex.../glEnd(). // sending OpenGL glBegin/glVertex.../glEnd().
switch(primitiveset->getType()) switch(primitiveset->getType())
@ -2167,6 +2428,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
} }
} }
#endif
class AttributeFunctorArrayVisitor : public ArrayVisitor class AttributeFunctorArrayVisitor : public ArrayVisitor
{ {