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:
parent
b0057e258c
commit
6a56b6e6be
@ -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() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
106
include/osg/ArrayDispatchers
Normal file
106
include/osg/ArrayDispatchers
Normal 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
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -25,7 +25,7 @@ echo osgcallback
|
|||||||
osgcallback
|
osgcallback
|
||||||
|
|
||||||
echo osgcatch
|
echo osgcatch
|
||||||
osgcatch
|
# osgcatch
|
||||||
|
|
||||||
echo osgclip
|
echo osgclip
|
||||||
osgclip
|
osgclip
|
||||||
|
521
src/osg/ArrayDispatchers.cpp
Normal file
521
src/osg/ArrayDispatchers.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user