Updates to the handling of vertex attributes.

This commit is contained in:
Robert Osfield 2003-05-09 13:07:06 +00:00
parent b7fcc68e6f
commit 57af40ee95
7 changed files with 369 additions and 163 deletions

View File

@ -171,6 +171,9 @@ int main( int argc, char **argv )
Broadcaster bc; Broadcaster bc;
Receiver rc; Receiver rc;
bc.setPort(socketNumber);
rc.setPort(socketNumber);
while( !viewer.done() ) while( !viewer.done() )
{ {
// wait for all cull and draw threads to complete. // wait for all cull and draw threads to complete.

View File

@ -250,12 +250,19 @@ class SG_EXPORT Drawable : public Object
static void flushDeletedDisplayLists(unsigned int contextID); static void flushDeletedDisplayLists(unsigned int contextID);
enum AttributeType typedef unsigned int AttributeType;
enum AttributeTypes
{ {
VERTICES, VERTICES = 0,
NORMALS, WEIGHTS = 1,
COLORS, NORMALS = 2,
TEXTURE_COORDS, COLORS = 3,
SECONDARY_COLORS = 4,
FOG_COORDS = 5,
ATTIBUTE_6 = 6,
ATTIBUTE_7 = 7,
TEXTURE_COORDS = 8,
TEXTURE_COORDS_0 = TEXTURE_COORDS, TEXTURE_COORDS_0 = TEXTURE_COORDS,
TEXTURE_COORDS_1 = TEXTURE_COORDS_0+1, TEXTURE_COORDS_1 = TEXTURE_COORDS_0+1,
TEXTURE_COORDS_2 = TEXTURE_COORDS_0+2, TEXTURE_COORDS_2 = TEXTURE_COORDS_0+2,

View File

@ -127,6 +127,49 @@ class SG_EXPORT Geometry : public Drawable
const TexCoordArrayList& getTexCoordArrayList() const { return _texCoordList; } const TexCoordArrayList& getTexCoordArrayList() const { return _texCoordList; }
#ifdef COMPILE_POSSIBLE_NEW_ARRAY_METHODS
void setArray(AttributeType type, Array* array);
Array* getArray(AttributeType type);
const Array* getArray(AttributeType type) const;
void setIndices(AttributeType type, IndexArray* indices);
IndexArray* getIndices(AttributeType type);
const IndexArray* getIndices(AttributeType type) const;
void setNormalize(AttributeType type, GLboolean normalize);
GLboolean getNormalize(AttributeType type) const;
void setBinding(AttributeType type,AttributeBinding binding);
AttributeBinding getBinding(AttributeType type) const;
struct AttributeData
{
AttributeData():
_normalize(GL_FALSE),
_binding(BIND_OFF) {}
ref_ptr<Array> _array;
ref_ptr<IndexArray> _indices;
GLboolean _normalize;
AttributeBinding _binding;
};
unsigned int getNumArrays() const { return _attributeList.size(); }
AttributeData& getAttributeData(unsigned int type) { return _attributeList[type]; }
const AttributeData& getAttributeData(unsigned int type) const { return _attributeList[type]; }
typedef std::vector<AttributeData> AttributeList;
void setAttributeList(AttributeList& al) { _attributeList = al; }
AttributeList& getAttributeList() { return _attributeList; }
const AttributeList& getAttributeList() const { return _attributeList; }
#endif
typedef std::pair< ref_ptr<Array>, ref_ptr<IndexArray> > VertexAttribArrayPair; typedef std::pair< ref_ptr<Array>, ref_ptr<IndexArray> > VertexAttribArrayPair;
typedef std::pair< GLboolean, VertexAttribArrayPair > VertexAttribNormArrayPair; typedef std::pair< GLboolean, VertexAttribArrayPair > VertexAttribNormArrayPair;
@ -320,6 +363,9 @@ class SG_EXPORT Geometry : public Drawable
PrimitiveSetList _primitives; PrimitiveSetList _primitives;
#ifdef COMPILE_POSSIBLE_NEW_ARRAY_METHODS
AttributeList _attributeList;
#endif
ref_ptr<Vec3Array> _vertexArray; ref_ptr<Vec3Array> _vertexArray;
ref_ptr<IndexArray> _vertexIndices; ref_ptr<IndexArray> _vertexIndices;

View File

@ -17,7 +17,6 @@
#include <osg/Export> #include <osg/Export>
#include <osg/StateSet> #include <osg/StateSet>
#include <osg/Matrix> #include <osg/Matrix>
#include <osg/GLExtensions>
#include <osg/FrameStamp> #include <osg/FrameStamp>
#include <osg/DisplaySettings> #include <osg/DisplaySettings>
@ -537,84 +536,17 @@ class SG_EXPORT State : public Referenced
* note, only updates values that change.*/ * note, only updates values that change.*/
bool setActiveTextureUnit( unsigned int unit ); bool setActiveTextureUnit( unsigned int unit );
typedef void (APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int);
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..); /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void setVertexAttribPointer( unsigned int index, void setVertexAttribPointer( unsigned int index,
GLint size, GLenum type, GLboolean normalized, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid *ptr ) GLsizei stride, const GLvoid *ptr );
{
static VertexAttribPointerProc s_glVertexAttribPointer =
(VertexAttribPointerProc) osg::getGLExtensionFuncPtr("glVertexAttribPointer","glVertexAttribPointerARB");
static EnableVertexAttribProc s_glEnableVertexAttribArray =
(EnableVertexAttribProc) osg::getGLExtensionFuncPtr("glEnableVertexAttribArray","glEnableVertexAttribArrayARB");
if( s_glVertexAttribPointer )
{
if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (!eap._enabled || eap._dirty)
{
eap._enabled = true;
s_glEnableVertexAttribArray( index );
}
if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
{
s_glVertexAttribPointer( index, size, type, normalized, stride, ptr );
eap._pointer = ptr;
eap._normalized = normalized;
}
eap._dirty = false;
}
}
/** wrapper around DisableVertexAttribArrayARB(index); /** wrapper around DisableVertexAttribArrayARB(index);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableVertexAttribPointer( unsigned int index ) void disableVertexAttribPointer( unsigned int index );
{
static DisableVertexAttribProc s_glDisableVertexAttribArray =
(DisableVertexAttribProc) osg::getGLExtensionFuncPtr("glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
if (s_glDisableVertexAttribArray) void disableVertexAttribPointersAboveAndIncluding( unsigned int index );
{
if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (eap._enabled || eap._dirty)
{
eap._enabled = false;
eap._dirty = false;
s_glDisableVertexAttribArray( index );
}
}
}
inline void disableVertexAttribPointersAboveAndIncluding( unsigned int index )
{
static DisableVertexAttribProc s_glDisableVertexAttribArray =
(DisableVertexAttribProc) osg::getGLExtensionFuncPtr("glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
if (s_glDisableVertexAttribArray)
{
while (index<_vertexAttribArrayList.size())
{
EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (eap._enabled || eap._dirty)
{
eap._enabled = false;
eap._dirty = false;
s_glDisableVertexAttribArray( index );
}
++index;
}
}
}
inline void dirtyVertexAttribPointersAboveAndIncluding( unsigned int index ) inline void dirtyVertexAttribPointersAboveAndIncluding( unsigned int index )
{ {

View File

@ -16,10 +16,10 @@
using namespace osg; using namespace osg;
AutoTransform::AutoTransform(): AutoTransform::AutoTransform():
_scale(1.0f,1.0f,1.0f),
_autoUpdateEyeMovementTolerance(0.0f), _autoUpdateEyeMovementTolerance(0.0f),
_autoRotateToScreen(false), _autoRotateToScreen(false),
_autoScaleToScreen(false), _autoScaleToScreen(false),
_scale(1.0f,1.0f,1.0f),
_firstTimeToInitEyePoint(true), _firstTimeToInitEyePoint(true),
_matrixDirty(true) _matrixDirty(true)
{ {
@ -30,8 +30,8 @@ AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop):
Transform(pat,copyop), Transform(pat,copyop),
_position(pat._position), _position(pat._position),
_pivotPoint(pat._pivotPoint), _pivotPoint(pat._pivotPoint),
_scale(pat._scale), _rotation(pat._rotation),
_rotation(pat._rotation) _scale(pat._scale)
{ {
// setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); // setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
} }

View File

@ -83,7 +83,7 @@ public:
_normalized(normalized), _normalized(normalized),
_extensions(extensions), _extensions(extensions),
_attribcoords(attribcoords), _attribcoords(attribcoords),
_indices(indices) {} _indices(indices) {;}
void operator () (unsigned int pos) void operator () (unsigned int pos)
{ {
@ -123,11 +123,11 @@ public:
_extensions->glVertexAttrib4fv( _index, v.ptr() ); _extensions->glVertexAttrib4fv( _index, v.ptr() );
} }
unsigned int _index;
GLboolean _normalized;
const Geometry::Extensions *_extensions; const Geometry::Extensions *_extensions;
const Array* _attribcoords; const Array* _attribcoords;
const IndexArray* _indices; const IndexArray* _indices;
GLboolean _normalized;
unsigned int _index;
}; };
class DrawTexCoord : public osg::Referenced, public osg::ConstValueVisitor class DrawTexCoord : public osg::Referenced, public osg::ConstValueVisitor
@ -247,6 +247,9 @@ Geometry::Geometry()
Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
Drawable(geometry,copyop), Drawable(geometry,copyop),
#ifdef COMPILE_POSSIBLE_NEW_ARRAY_METHODS
_attributeList(geometry._attributeList),
#endif
_vertexArray(dynamic_cast<Vec3Array*>(copyop(geometry._vertexArray.get()))), _vertexArray(dynamic_cast<Vec3Array*>(copyop(geometry._vertexArray.get()))),
_normalBinding(geometry._normalBinding), _normalBinding(geometry._normalBinding),
_normalArray(dynamic_cast<Vec3Array*>(copyop(geometry._normalArray.get()))), _normalArray(dynamic_cast<Vec3Array*>(copyop(geometry._normalArray.get()))),
@ -331,6 +334,89 @@ const IndexArray* Geometry::getTexCoordIndices(unsigned int unit) const
else return 0; else return 0;
} }
#ifdef COMPILE_POSSIBLE_NEW_ARRAY_METHODS
void Geometry::setArray(AttributeType type,Array* array)
{
if (_attributeList.size()<=type)
_attributeList.resize(type+1);
_attributeList[type]._array = array;
dirtyDisplayList();
}
Array* Geometry::getArray(AttributeType type)
{
if (type<_attributeList.size()) return _attributeList[type]._array.get();
else return 0;
}
const Array* Geometry::getArray(AttributeType type) const
{
if (type<_attributeList.size()) return _attributeList[type]._array.get();
else return 0;
}
void Geometry::setIndices(AttributeType type,IndexArray* array)
{
if (_attributeList.size()<=type)
_attributeList.resize(type+1);
_attributeList[type]._indices = array;
dirtyDisplayList();
}
IndexArray* Geometry::getIndices(AttributeType type)
{
if (type<_attributeList.size()) return _attributeList[type]._indices.get();
else return 0;
}
const IndexArray* Geometry::getIndices(AttributeType type) const
{
if (type<_attributeList.size()) return _attributeList[type]._indices.get();
else return 0;
}
void Geometry::setNormalize(AttributeType type,GLboolean normalize)
{
if (_attributeList.size()<=type)
_attributeList.resize(type+1);
_attributeList[type]._normalize = normalize;
dirtyDisplayList();
}
GLboolean Geometry::getNormalize(AttributeType type) const
{
if (type<_attributeList.size()) return _attributeList[type]._normalize;
else return GL_FALSE;
}
void Geometry::setBinding(AttributeType type,AttributeBinding binding)
{
if (_attributeList.size()<=type)
_attributeList.resize(type+1);
_attributeList[type]._binding = binding;
dirtyDisplayList();
}
Geometry::AttributeBinding Geometry::getBinding(AttributeType type) const
{
if (type<_attributeList.size()) return _attributeList[type]._binding;
else return BIND_OFF;
}
#endif
void Geometry::setVertexAttribArray(unsigned int index,bool normalize,Array* array,AttributeBinding ab) void Geometry::setVertexAttribArray(unsigned int index,bool normalize,Array* array,AttributeBinding ab)
{ {
if (_vertexAttribList.size()<=index) if (_vertexAttribList.size()<=index)
@ -342,7 +428,15 @@ void Geometry::setVertexAttribArray(unsigned int index,bool normalize,Array* arr
_vertexAttribList[index].first = normalize; _vertexAttribList[index].first = normalize;
_vertexAttribList[index].second.first = array; _vertexAttribList[index].second.first = array;
if( index == 0 )
{
// Force bind per vertex
_vertexAttribBindingList[index] = BIND_PER_VERTEX;
}
else
{
_vertexAttribBindingList[index] = ab; _vertexAttribBindingList[index] = ab;
}
_fastPathComputed = false; _fastPathComputed = false;
dirtyDisplayList(); dirtyDisplayList();
@ -683,8 +777,6 @@ void Geometry::drawImplementation(State& state) const
// //
if(!extensions->isVertexProgramSupported()) if(!extensions->isVertexProgramSupported())
{ {
notify(WARN) << "Error: VertexProgram not supported by OpenGL driver" << std::endl;
for( unsigned int va = 0; va < _vertexAttribBindingList.size(); ++va ) for( unsigned int va = 0; va < _vertexAttribBindingList.size(); ++va )
{ {
if (_vertexAttribBindingList[va]!=BIND_OFF) if (_vertexAttribBindingList[va]!=BIND_OFF)
@ -720,7 +812,10 @@ void Geometry::drawImplementation(State& state) const
// fast path. // fast path.
// //
if( _vertexArray.valid() )
state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->getDataPointer()); state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->getDataPointer());
else
state.disableVertexPointer();
if (_normalBinding==BIND_PER_VERTEX) if (_normalBinding==BIND_PER_VERTEX)
state.setNormalPointer(GL_FLOAT,0,_normalArray->getDataPointer()); state.setNormalPointer(GL_FLOAT,0,_normalArray->getDataPointer());
@ -759,35 +854,30 @@ void Geometry::drawImplementation(State& state) const
for( index = 0; index < _vertexAttribList.size(); ++index ) for( index = 0; index < _vertexAttribList.size(); ++index )
{ {
const Array* array = _vertexAttribList[index].second.first.get(); const Array* array = _vertexAttribList[index].second.first.get();
const IndexArray* indexArray = _vertexAttribList[index].second.second.get(); const AttributeBinding ab = _vertexAttribBindingList[index];
if( _vertexAttribBindingList[index] == BIND_PER_VERTEX ) if( ab == BIND_PER_VERTEX && array )
{
if( array )
{ {
state.setVertexAttribPointer( index, array->getDataSize(), array->getDataType(), state.setVertexAttribPointer( index, array->getDataSize(), array->getDataType(),
_vertexAttribList[index].first, 0, array->getDataPointer() ); _vertexAttribList[index].first, 0, array->getDataPointer() );
} }
else else
{ {
state.disableVertexAttribPointer( index ); if( array )
}
}
else
{ {
if( indexArray ) const IndexArray* indexArray = _vertexAttribList[index].second.second.get();
if( indexArray && indexArray->getNumElements() > 0 )
{ {
if( indexArray->getNumElements() > 0 ) drawVertexAttribMap[ab].push_back(
{
drawVertexAttribMap[_vertexAttribBindingList[index]].push_back(
new DrawVertexAttrib(extensions,index,_vertexAttribList[index].first,array,indexArray) ); new DrawVertexAttrib(extensions,index,_vertexAttribList[index].first,array,indexArray) );
} }
}
else else
{ {
drawVertexAttribMap[_vertexAttribBindingList[index]].push_back( drawVertexAttribMap[ab].push_back(
new DrawVertexAttrib(extensions,index,_vertexAttribList[index].first,array,0) ); new DrawVertexAttrib(extensions,index,_vertexAttribList[index].first,array,0) );
} }
}
state.disableVertexAttribPointer( index ); state.disableVertexAttribPointer( index );
} }
@ -908,19 +998,19 @@ void Geometry::drawImplementation(State& state) const
if( extensions->isVertexProgramSupported() ) if( extensions->isVertexProgramSupported() )
{ {
unsigned int index; unsigned int index;
for( index = 0; index < _vertexAttribList.size(); ++index ) for( index = 1; index < _vertexAttribList.size(); ++index )
{ {
const Array* array = _vertexAttribList[index].second.first.get(); const Array* array = _vertexAttribList[index].second.first.get();
if( array && array->getNumElements() > 0 )
{
const IndexArray* indexArray = _vertexAttribList[index].second.second.get(); const IndexArray* indexArray = _vertexAttribList[index].second.second.get();
if( indexArray ) if( indexArray && indexArray->getNumElements() > 0 )
{
if( indexArray->getNumElements() > 0 )
{ {
drawVertexAttribMap[_vertexAttribBindingList[index]].push_back( drawVertexAttribMap[_vertexAttribBindingList[index]].push_back(
new DrawVertexAttrib(extensions,index,_vertexAttribList[index].first,array,indexArray) ); new DrawVertexAttrib(extensions,index,_vertexAttribList[index].first,array,indexArray) );
} }
}
else else
{ {
drawVertexAttribMap[_vertexAttribBindingList[index]].push_back( drawVertexAttribMap[_vertexAttribBindingList[index]].push_back(
@ -928,6 +1018,7 @@ void Geometry::drawImplementation(State& state) const
} }
} }
} }
}
// disable all the vertex arrays in the slow path as we are // disable all the vertex arrays in the slow path as we are
// sending everything using glVertex etc. // sending everything using glVertex etc.
@ -955,6 +1046,18 @@ void Geometry::drawImplementation(State& state) const
// set up vertex functor. // set up vertex functor.
DrawVertex drawVertex(_vertexArray.get(),_vertexIndices.get()); DrawVertex drawVertex(_vertexArray.get(),_vertexIndices.get());
bool useVertexAttrib = _vertexAttribList.size() > 0 &&
_vertexAttribList[0].second.first.valid() &&
_vertexAttribList[0].second.first->getNumElements();
ref_ptr<DrawVertexAttrib> drawVertexAttribZero;
if( useVertexAttrib )
{
drawVertexAttribZero = new DrawVertexAttrib(extensions,0,
_vertexAttribList[0].first,_vertexAttribList[0].second.first.get(),
_vertexAttribList[0].second.second.get());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// draw the primitives themselves. // draw the primitives themselves.
@ -1048,8 +1151,15 @@ void Geometry::drawImplementation(State& state) const
} }
if (drawTextCoord.valid()) (*drawTextCoord)(vindex); if (drawTextCoord.valid()) (*drawTextCoord)(vindex);
if( useVertexAttrib )
{
(*drawVertexAttribZero)(vindex);
}
else
{
drawVertex(vindex); drawVertex(vindex);
} }
}
glEnd(); glEnd();
break; break;
@ -1109,7 +1219,14 @@ void Geometry::drawImplementation(State& state) const
} }
if (drawTextCoord.valid()) (*drawTextCoord)(vindex); if (drawTextCoord.valid()) (*drawTextCoord)(vindex);
if( useVertexAttrib )
{
(*drawVertexAttribZero)(vindex);
}
else
{
drawVertex(vindex); drawVertex(vindex);
}
++vindex; ++vindex;
} }
@ -1173,8 +1290,15 @@ void Geometry::drawImplementation(State& state) const
} }
if (drawTextCoord.valid()) (*drawTextCoord)(vindex); if (drawTextCoord.valid()) (*drawTextCoord)(vindex);
if( useVertexAttrib )
{
(*drawVertexAttribZero)(vindex);
}
else
{
drawVertex(vindex); drawVertex(vindex);
} }
}
glEnd(); glEnd();
break; break;
@ -1233,8 +1357,15 @@ void Geometry::drawImplementation(State& state) const
} }
if (drawTextCoord.valid()) (*drawTextCoord)(vindex); if (drawTextCoord.valid()) (*drawTextCoord)(vindex);
if( useVertexAttrib )
{
(*drawVertexAttribZero)(vindex);
}
else
{
drawVertex(vindex); drawVertex(vindex);
} }
}
glEnd(); glEnd();
break; break;
@ -1293,8 +1424,15 @@ void Geometry::drawImplementation(State& state) const
} }
if (drawTextCoord.valid()) (*drawTextCoord)(vindex); if (drawTextCoord.valid()) (*drawTextCoord)(vindex);
if( useVertexAttrib )
{
(*drawVertexAttribZero)(vindex);
}
else
{
drawVertex(vindex); drawVertex(vindex);
} }
}
glEnd(); glEnd();
break; break;

View File

@ -13,6 +13,8 @@
#include <osg/State> #include <osg/State>
#include <osg/Notify> #include <osg/Notify>
#include <osg/GLU> #include <osg/GLU>
#include <osg/GLExtensions>
using namespace osg; using namespace osg;
@ -614,6 +616,84 @@ void State::setSecondaryColorPointer( GLint size, GLenum type,
} }
} }
typedef void (APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int);
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note, only updates values that change.*/
void State::setVertexAttribPointer( unsigned int index,
GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid *ptr )
{
static VertexAttribPointerProc s_glVertexAttribPointer =
(VertexAttribPointerProc) osg::getGLExtensionFuncPtr("glVertexAttribPointer","glVertexAttribPointerARB");
static EnableVertexAttribProc s_glEnableVertexAttribArray =
(EnableVertexAttribProc) osg::getGLExtensionFuncPtr("glEnableVertexAttribArray","glEnableVertexAttribArrayARB");
if( s_glVertexAttribPointer )
{
if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (!eap._enabled || eap._dirty)
{
eap._enabled = true;
s_glEnableVertexAttribArray( index );
}
if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
{
s_glVertexAttribPointer( index, size, type, normalized, stride, ptr );
eap._pointer = ptr;
eap._normalized = normalized;
}
eap._dirty = false;
}
}
/** wrapper around DisableVertexAttribArrayARB(index);
* note, only updates values that change.*/
void State::disableVertexAttribPointer( unsigned int index )
{
static DisableVertexAttribProc s_glDisableVertexAttribArray =
(DisableVertexAttribProc) osg::getGLExtensionFuncPtr("glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
if (s_glDisableVertexAttribArray)
{
if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (eap._enabled || eap._dirty)
{
eap._enabled = false;
eap._dirty = false;
s_glDisableVertexAttribArray( index );
}
}
}
void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
{
static DisableVertexAttribProc s_glDisableVertexAttribArray =
(DisableVertexAttribProc) osg::getGLExtensionFuncPtr("glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
if (s_glDisableVertexAttribArray)
{
while (index<_vertexAttribArrayList.size())
{
EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (eap._enabled || eap._dirty)
{
eap._enabled = false;
eap._dirty = false;
s_glDisableVertexAttribArray( index );
}
++index;
}
}
}
bool State::computeSecondaryColorSupported() const bool State::computeSecondaryColorSupported() const
{ {
_isSecondColorSupportResolved = true; _isSecondColorSupportResolved = true;