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,
|
||||
Vec2dArrayType = 19,
|
||||
Vec3dArrayType = 20,
|
||||
Vec4dArrayType = 21
|
||||
Vec4dArrayType = 21
|
||||
};
|
||||
|
||||
Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0):
|
||||
_arrayType(arrayType),
|
||||
_dataSize(dataSize),
|
||||
_dataType(dataType) {}
|
||||
|
||||
|
||||
Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
BufferData(array,copyop),
|
||||
_arrayType(array._arrayType),
|
||||
@ -88,7 +88,7 @@ class OSG_EXPORT Array : public BufferData
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Array*>(obj)!=NULL; }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const;
|
||||
|
||||
|
||||
virtual void accept(ArrayVisitor&) = 0;
|
||||
virtual void accept(ConstArrayVisitor&) const = 0;
|
||||
|
||||
@ -131,13 +131,13 @@ template<typename T, Array::Type ARRAYTYPE, int DataSize, int DataType>
|
||||
class TemplateArray : public Array, public MixinVector<T>
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
TemplateArray() : Array(ARRAYTYPE,DataSize,DataType) {}
|
||||
|
||||
TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Array(ta,copyop),
|
||||
MixinVector<T>(ta) {}
|
||||
|
||||
|
||||
TemplateArray(unsigned int no) :
|
||||
Array(ARRAYTYPE,DataSize,DataType),
|
||||
MixinVector<T>(no) {}
|
||||
@ -181,7 +181,7 @@ class TemplateArray : public Array, public MixinVector<T>
|
||||
{
|
||||
MixinVector<T>( *this ).swap( *this );
|
||||
}
|
||||
|
||||
|
||||
virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; }
|
||||
virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); }
|
||||
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):
|
||||
Array(arrayType,dataSize,dataType) {}
|
||||
|
||||
|
||||
IndexArray(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Array(array,copyop) {}
|
||||
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const IndexArray*>(obj)!=NULL; }
|
||||
|
||||
|
||||
virtual unsigned int index(unsigned int pos) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
virtual ~IndexArray() {}
|
||||
};
|
||||
|
||||
@ -217,13 +217,13 @@ template<typename T, Array::Type ARRAYTYPE, int DataSize, int DataType>
|
||||
class TemplateIndexArray : public IndexArray, public MixinVector<T>
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
TemplateIndexArray() : IndexArray(ARRAYTYPE,DataSize,DataType) {}
|
||||
|
||||
TemplateIndexArray(const TemplateIndexArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
IndexArray(ta,copyop),
|
||||
MixinVector<T>(ta) {}
|
||||
|
||||
|
||||
TemplateIndexArray(unsigned int no) :
|
||||
IndexArray(ARRAYTYPE,DataSize,DataType),
|
||||
MixinVector<T>(no) {}
|
||||
@ -267,7 +267,7 @@ class TemplateIndexArray : public IndexArray, public MixinVector<T>
|
||||
{
|
||||
MixinVector<T>( *this ).swap( *this );
|
||||
}
|
||||
|
||||
|
||||
virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; }
|
||||
virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); }
|
||||
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
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
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 glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) const;
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord);
|
||||
|
||||
@ -735,9 +735,11 @@ class OSG_EXPORT Drawable : public Object
|
||||
VertexAttrib1sProc _glVertexAttrib1s;
|
||||
VertexAttrib1fProc _glVertexAttrib1f;
|
||||
VertexAttrib1dProc _glVertexAttrib1d;
|
||||
VertexAttribfvProc _glVertexAttrib1fv;
|
||||
VertexAttribfvProc _glVertexAttrib2fv;
|
||||
VertexAttribfvProc _glVertexAttrib3fv;
|
||||
VertexAttribfvProc _glVertexAttrib4fv;
|
||||
VertexAttribdvProc _glVertexAttrib1dv;
|
||||
VertexAttribdvProc _glVertexAttrib2dv;
|
||||
VertexAttribdvProc _glVertexAttrib3dv;
|
||||
VertexAttribdvProc _glVertexAttrib4dv;
|
||||
@ -745,10 +747,12 @@ class OSG_EXPORT Drawable : public Object
|
||||
VertexAttribubvProc _glVertexAttrib4Nubv;
|
||||
|
||||
MultiTexCoord1fProc _glMultiTexCoord1f;
|
||||
MultiTexCoordfvProc _glMultiTexCoord1fv;
|
||||
MultiTexCoordfvProc _glMultiTexCoord2fv;
|
||||
MultiTexCoordfvProc _glMultiTexCoord3fv;
|
||||
MultiTexCoordfvProc _glMultiTexCoord4fv;
|
||||
MultiTexCoord1dProc _glMultiTexCoord1d;
|
||||
MultiTexCoorddvProc _glMultiTexCoord1dv;
|
||||
MultiTexCoorddvProc _glMultiTexCoord2dv;
|
||||
MultiTexCoorddvProc _glMultiTexCoord3dv;
|
||||
MultiTexCoorddvProc _glMultiTexCoord4dv;
|
||||
|
@ -54,13 +54,23 @@ class OSG_EXPORT GLBeginEndAdapter
|
||||
void Scaled(GLdouble x, GLdouble y, GLdouble z);
|
||||
void Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
||||
|
||||
void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
void Color4fv(const GLfloat* c) { Color4f(c[0], c[1], c[2], c[3]); }
|
||||
|
||||
void Vertex3f(GLfloat x, GLfloat y, GLfloat z);
|
||||
void Vertex3fv(const GLfloat* v) { Vertex3f(v[0], v[1], v[2]); }
|
||||
|
||||
void Normal3f(GLfloat x, GLfloat y, GLfloat z);
|
||||
void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
||||
{
|
||||
_normalAssigned = true;
|
||||
_color.set(red,green,blue,alpha);
|
||||
}
|
||||
|
||||
void Color4fv(const GLfloat* c) { Color4f(c[0], c[1], c[2], c[3]); }
|
||||
|
||||
void Normal3f(GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
_normalAssigned = true;
|
||||
_normal.set(x,y,z);
|
||||
}
|
||||
|
||||
void Normal3fv(const GLfloat* n) { Normal3f(n[0], n[1], n[2]); }
|
||||
|
||||
void TexCoord1f(GLfloat x) { MultiTexCoord4f(0, x, 0.0f, 0.0f, 1.0f); }
|
||||
@ -140,7 +150,6 @@ class OSG_EXPORT GLBeginEndAdapter
|
||||
VertexArrayList _vertexAttribsList;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -476,13 +476,13 @@ class OSG_EXPORT State : public Referenced, public Observer
|
||||
else glNormal3f(x,y,z);
|
||||
}
|
||||
|
||||
void TexCoord(float x, float y=0.0f, float z=0.0f, float w=0.0f)
|
||||
void TexCoord(float x, float y=0.0f, float z=0.0f, float w=1.0f)
|
||||
{
|
||||
if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w);
|
||||
else glTexCoord4f(x,y,z,w);
|
||||
}
|
||||
|
||||
void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=0.0f)
|
||||
void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=1.0f)
|
||||
{
|
||||
if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w);
|
||||
else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w);
|
||||
|
@ -25,7 +25,7 @@ echo osgcallback
|
||||
osgcallback
|
||||
|
||||
echo osgcatch
|
||||
osgcatch
|
||||
# osgcatch
|
||||
|
||||
echo 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}/ArgumentParser
|
||||
${HEADER_PATH}/Array
|
||||
${HEADER_PATH}/ArrayDispatchers
|
||||
${HEADER_PATH}/AudioStream
|
||||
${HEADER_PATH}/AutoTransform
|
||||
${HEADER_PATH}/Billboard
|
||||
@ -195,6 +196,7 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
ApplicationUsage.cpp
|
||||
ArgumentParser.cpp
|
||||
Array.cpp
|
||||
ArrayDispatchers.cpp
|
||||
AudioStream.cpp
|
||||
AutoTransform.cpp
|
||||
Billboard.cpp
|
||||
|
@ -934,6 +934,7 @@ void Drawable::Extensions::setupGLExtensions(unsigned int contextID)
|
||||
setGLExtensionFuncPtr(_glSecondaryColor3ubv, "glSecondaryColor3ubv","glSecondaryColor3ubvEXT");
|
||||
setGLExtensionFuncPtr(_glSecondaryColor3fv, "glSecondaryColor3fv","glSecondaryColor3fvEXT");
|
||||
setGLExtensionFuncPtr(_glMultiTexCoord1f, "glMultiTexCoord1f","glMultiTexCoord1fARB");
|
||||
setGLExtensionFuncPtr(_glMultiTexCoord1fv, "glMultiTexCoord1fv","glMultiTexCoord1fvARB");
|
||||
setGLExtensionFuncPtr(_glMultiTexCoord2fv, "glMultiTexCoord2fv","glMultiTexCoord2fvARB");
|
||||
setGLExtensionFuncPtr(_glMultiTexCoord3fv, "glMultiTexCoord3fv","glMultiTexCoord3fvARB");
|
||||
setGLExtensionFuncPtr(_glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB");
|
||||
@ -945,6 +946,7 @@ void Drawable::Extensions::setupGLExtensions(unsigned int contextID)
|
||||
setGLExtensionFuncPtr(_glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB");
|
||||
setGLExtensionFuncPtr(_glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB");
|
||||
setGLExtensionFuncPtr(_glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB");
|
||||
setGLExtensionFuncPtr(_glVertexAttrib1fv, "glVertexAttrib1fv","glVertexAttrib1fvARB");
|
||||
setGLExtensionFuncPtr(_glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB");
|
||||
setGLExtensionFuncPtr(_glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB");
|
||||
setGLExtensionFuncPtr(_glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB");
|
||||
|
@ -97,18 +97,6 @@ void GLBeginEndAdapter::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble
|
||||
_matrixStack.back().preMultRotate(Quat(DegreesToRadians(angle), Vec3d(x,y,z)));
|
||||
}
|
||||
|
||||
void GLBeginEndAdapter::Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
||||
{
|
||||
_normalAssigned = true;
|
||||
_color.set(red,green,blue,alpha);
|
||||
}
|
||||
|
||||
void GLBeginEndAdapter::Normal3f(GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
_normalAssigned = true;
|
||||
_normal.set(x,y,z);
|
||||
}
|
||||
|
||||
void GLBeginEndAdapter::MultiTexCoord4f(unsigned int unit, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
if (unit>=_texCoordAssignedList.size()) _texCoordAssignedList.resize(unit+1, false);
|
||||
@ -133,7 +121,6 @@ void GLBeginEndAdapter::Vertex3f(GLfloat x, GLfloat y, GLfloat z)
|
||||
|
||||
if (!_vertices) _vertices = new osg::Vec3Array;
|
||||
|
||||
|
||||
if (_normalAssigned)
|
||||
{
|
||||
if (!_normals) _normals = new osg::Vec3Array;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/ArrayDispatchers>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
@ -223,7 +224,7 @@ class DrawVertexAttrib : public osg::Referenced, public osg::ConstValueVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
DrawVertexAttrib(const Drawable::Extensions * extensions,unsigned int vertAttribIndex,GLboolean normalized,const Array* attribcoords,const IndexArray* indices):
|
||||
DrawVertexAttrib(const Drawable::Extensions * extensions,unsigned int vertAttribIndex,GLboolean normalized,const Array* attribcoords,const IndexArray* indices):
|
||||
_vertAttribIndex(vertAttribIndex),
|
||||
_normalized(normalized),
|
||||
_extensions(extensions),
|
||||
@ -336,7 +337,7 @@ class DrawMultiTexCoord : public osg::Referenced, public osg::ConstValueVisitor
|
||||
virtual void apply(const Vec3& v) { _extensions->glMultiTexCoord3fv(_target,v.ptr()); }
|
||||
virtual void apply(const Vec4& v) { _extensions->glMultiTexCoord4fv(_target,v.ptr()); }
|
||||
|
||||
GLenum _target;
|
||||
GLenum _target;
|
||||
const Array* _texcoords;
|
||||
const IndexArray* _indices;
|
||||
|
||||
@ -412,6 +413,9 @@ Geometry::Vec3ArrayData::Vec3ArrayData(const Vec3ArrayData& data,const CopyOp& c
|
||||
|
||||
Geometry::Geometry()
|
||||
{
|
||||
// temporary test
|
||||
// setSupportsDisplayList(false);
|
||||
|
||||
_fastPath = false;
|
||||
_fastPathHint = true;
|
||||
}
|
||||
@ -426,6 +430,9 @@ Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
|
||||
_fastPath(geometry._fastPath),
|
||||
_fastPathHint(geometry._fastPathHint)
|
||||
{
|
||||
// temporary test
|
||||
// setSupportsDisplayList(false);
|
||||
|
||||
for(PrimitiveSetList::const_iterator pitr=geometry._primitives.begin();
|
||||
pitr!=geometry._primitives.end();
|
||||
++pitr)
|
||||
@ -1272,10 +1279,264 @@ void Geometry::releaseGLObjects(State* state) const
|
||||
|
||||
}
|
||||
|
||||
#if 1
|
||||
void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
||||
{
|
||||
State& state = *renderInfo.getState();
|
||||
bool vertexAttribAlias = state.getUseVertexAttributeAliasing();
|
||||
Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(),true);
|
||||
|
||||
bool useFastPath = areFastPathsUsed();
|
||||
bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported();
|
||||
bool handleVertexAttributes = !_vertexAttribList.empty() && extensions->isVertexProgramSupported();
|
||||
|
||||
osg::ref_ptr<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();
|
||||
|
||||
@ -1338,6 +1599,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int normalIndex = 0;
|
||||
unsigned int colorIndex = 0;
|
||||
unsigned int secondaryColorIndex = 0;
|
||||
@ -1366,14 +1628,12 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
||||
{
|
||||
if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"normal assign"<<std::endl;
|
||||
drawVertexAttribMap[normalBinding].push_back( new DrawVertexAttrib(extensions,2,false,_normalData.array.get(),_normalData.indices.get()) );
|
||||
normalBinding = BIND_OFF;
|
||||
}
|
||||
|
||||
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()) );
|
||||
colorBinding = BIND_OFF;
|
||||
}
|
||||
@ -1382,8 +1642,10 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
||||
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
|
||||
@ -1814,7 +2076,6 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
||||
default: primLength=0; break; // compute later when =0.
|
||||
}
|
||||
|
||||
|
||||
// draw primitives by the more flexible "slow" path,
|
||||
// sending OpenGL glBegin/glVertex.../glEnd().
|
||||
switch(primitiveset->getType())
|
||||
@ -2167,6 +2428,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
class AttributeFunctorArrayVisitor : public ArrayVisitor
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user