2003-01-22 00:45:36 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 .
*/
2002-06-21 03:54:08 +08:00
# include <osg/Geometry>
2002-07-18 08:53:03 +08:00
# include <osg/Notify>
2002-06-21 03:54:08 +08:00
using namespace osg ;
2003-08-09 08:46:48 +08:00
# if 1
class DrawVertex
{
public :
DrawVertex ( const Array * vertices , const IndexArray * indices ) :
_vertices ( vertices ) ,
_indices ( indices )
{
2003-08-12 18:15:59 +08:00
_verticesType = _vertices ? _vertices - > getType ( ) : Array : : ArrayType ;
_indicesType = _indices ? _indices - > getType ( ) : Array : : ArrayType ;
2003-08-09 08:46:48 +08:00
}
2003-08-12 18:15:59 +08:00
inline unsigned int index ( unsigned int pos )
{
switch ( _indicesType )
{
case ( Array : : ByteArrayType ) : return ( * static_cast < const ByteArray * > ( _indices ) ) [ pos ] ;
case ( Array : : ShortArrayType ) : return ( * static_cast < const ShortArray * > ( _indices ) ) [ pos ] ;
case ( Array : : IntArrayType ) : return ( * static_cast < const IntArray * > ( _indices ) ) [ pos ] ;
case ( Array : : UByteArrayType ) : return ( * static_cast < const UByteArray * > ( _indices ) ) [ pos ] ;
case ( Array : : UShortArrayType ) : return ( * static_cast < const UShortArray * > ( _indices ) ) [ pos ] ;
case ( Array : : UIntArrayType ) : return ( * static_cast < const UIntArray * > ( _indices ) ) [ pos ] ;
default : return 0 ;
}
}
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
{
2003-08-12 18:15:59 +08:00
if ( _indices ) pos = index ( pos ) ;
2003-08-09 08:46:48 +08:00
switch ( _verticesType )
{
case ( Array : : Vec3ArrayType ) :
apply ( ( * ( static_cast < const Vec3Array * > ( _vertices ) ) ) [ pos ] ) ;
break ;
case ( Array : : Vec2ArrayType ) :
apply ( ( * ( static_cast < const Vec2Array * > ( _vertices ) ) ) [ pos ] ) ;
break ;
case ( Array : : Vec4ArrayType ) :
apply ( ( * ( static_cast < const Vec4Array * > ( _vertices ) ) ) [ pos ] ) ;
break ;
2003-08-12 18:15:59 +08:00
default :
break ;
2003-08-09 08:46:48 +08:00
}
}
inline void apply ( const Vec2 & v ) { glVertex2fv ( v . ptr ( ) ) ; }
inline void apply ( const Vec3 & v ) { glVertex3fv ( v . ptr ( ) ) ; }
inline void apply ( const Vec4 & v ) { glVertex4fv ( v . ptr ( ) ) ; }
const Array * _vertices ;
const IndexArray * _indices ;
Array : : Type _verticesType ;
2003-08-12 18:15:59 +08:00
Array : : Type _indicesType ;
2003-08-09 08:46:48 +08:00
} ;
# else
2003-06-24 23:40:09 +08:00
class DrawVertex : public osg : : ConstValueVisitor
2002-10-02 21:12:16 +08:00
{
public :
2003-06-24 23:40:09 +08:00
DrawVertex ( const Array * vertices , const IndexArray * indices ) :
2002-10-02 21:12:16 +08:00
_vertices ( vertices ) ,
_indices ( indices ) { }
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2002-10-02 21:12:16 +08:00
{
2003-06-24 23:40:09 +08:00
if ( _indices ) _vertices - > accept ( _indices - > index ( pos ) , * this ) ;
else _vertices - > accept ( pos , * this ) ;
2002-10-02 21:12:16 +08:00
}
2003-06-24 23:40:09 +08:00
virtual void apply ( const Vec2 & v ) { glVertex2fv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec3 & v ) { glVertex3fv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec4 & v ) { glVertex4fv ( v . ptr ( ) ) ; }
const Array * _vertices ;
const IndexArray * _indices ;
2002-10-02 21:12:16 +08:00
} ;
2003-08-09 08:46:48 +08:00
# endif
2002-10-02 21:12:16 +08:00
class DrawNormal
{
public :
DrawNormal ( const Vec3Array * normals , const IndexArray * indices ) :
_normals ( normals ) ,
_indices ( indices ) { }
void operator ( ) ( unsigned int pos )
{
if ( _indices ) glNormal3fv ( ( * _normals ) [ _indices - > index ( pos ) ] . ptr ( ) ) ;
else glNormal3fv ( ( * _normals ) [ pos ] . ptr ( ) ) ;
}
const Vec3Array * _normals ;
const IndexArray * _indices ;
} ;
2003-08-09 08:46:48 +08:00
# if 1
class DrawColor
{
public :
DrawColor ( const Array * colors , const IndexArray * indices ) :
_colors ( colors ) ,
_indices ( indices )
{
2003-08-12 18:15:59 +08:00
_colorsType = _colors ? _colors - > getType ( ) : Array : : ArrayType ;
_indicesType = _indices ? _indices - > getType ( ) : Array : : ArrayType ;
2003-08-09 08:46:48 +08:00
}
inline unsigned int index ( unsigned int pos )
{
switch ( _indicesType )
{
case ( Array : : ByteArrayType ) : return ( * static_cast < const ByteArray * > ( _indices ) ) [ pos ] ;
case ( Array : : ShortArrayType ) : return ( * static_cast < const ShortArray * > ( _indices ) ) [ pos ] ;
case ( Array : : IntArrayType ) : return ( * static_cast < const IntArray * > ( _indices ) ) [ pos ] ;
case ( Array : : UByteArrayType ) : return ( * static_cast < const UByteArray * > ( _indices ) ) [ pos ] ;
case ( Array : : UShortArrayType ) : return ( * static_cast < const UShortArray * > ( _indices ) ) [ pos ] ;
case ( Array : : UIntArrayType ) : return ( * static_cast < const UIntArray * > ( _indices ) ) [ pos ] ;
default : return 0 ;
}
}
inline void operator ( ) ( unsigned int pos )
{
if ( _indices ) pos = index ( pos ) ;
switch ( _colorsType )
{
case ( Array : : Vec4ArrayType ) :
apply ( ( * static_cast < const Vec4Array * > ( _colors ) ) [ pos ] ) ;
break ;
case ( Array : : UByte4ArrayType ) :
apply ( ( * static_cast < const UByte4Array * > ( _colors ) ) [ pos ] ) ;
break ;
case ( Array : : Vec3ArrayType ) :
apply ( ( * static_cast < const Vec3Array * > ( _colors ) ) [ pos ] ) ;
break ;
2003-08-12 18:15:59 +08:00
default :
break ;
2003-08-09 08:46:48 +08:00
}
}
inline void apply ( const UByte4 & v ) { glColor4ubv ( v . ptr ( ) ) ; }
inline void apply ( const Vec3 & v ) { glColor3fv ( v . ptr ( ) ) ; }
inline void apply ( const Vec4 & v ) { glColor4fv ( v . ptr ( ) ) ; }
const Array * _colors ;
const IndexArray * _indices ;
Array : : Type _colorsType ;
Array : : Type _indicesType ;
} ;
# else
2002-10-02 21:12:16 +08:00
class DrawColor : public osg : : ConstValueVisitor
{
public :
DrawColor ( const Array * colors , const IndexArray * indices ) :
_colors ( colors ) ,
_indices ( indices ) { }
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2002-10-02 21:12:16 +08:00
{
if ( _indices ) _colors - > accept ( _indices - > index ( pos ) , * this ) ;
else _colors - > accept ( pos , * this ) ;
}
virtual void apply ( const UByte4 & v ) { glColor4ubv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec3 & v ) { glColor3fv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec4 & v ) { glColor4fv ( v . ptr ( ) ) ; }
const Array * _colors ;
const IndexArray * _indices ;
} ;
2003-08-09 08:46:48 +08:00
# endif
2003-05-07 21:13:13 +08:00
class DrawVertexAttrib : public osg : : Referenced , public osg : : ConstValueVisitor
{
public :
2003-06-30 05:41:57 +08:00
DrawVertexAttrib ( const Drawable : : Extensions * extensions , unsigned int index , GLboolean normalized , const Array * attribcoords , const IndexArray * indices ) :
2003-05-07 21:13:13 +08:00
_index ( index ) ,
_normalized ( normalized ) ,
_extensions ( extensions ) ,
_attribcoords ( attribcoords ) ,
2003-05-09 21:07:06 +08:00
_indices ( indices ) { ; }
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2003-05-09 21:07:06 +08:00
{
if ( _indices ) _attribcoords - > accept ( _indices - > index ( pos ) , * this ) ;
else _attribcoords - > accept ( pos , * this ) ;
}
virtual void apply ( const GLshort & s )
{
_extensions - > glVertexAttrib1s ( _index , s ) ;
}
virtual void apply ( const GLfloat & f )
{
_extensions - > glVertexAttrib1f ( _index , f ) ;
}
virtual void apply ( const UByte4 & v )
{
if ( _normalized )
{
_extensions - > glVertexAttrib4Nubv ( _index , v . ptr ( ) ) ;
}
else
{
_extensions - > glVertexAttrib4ubv ( _index , v . ptr ( ) ) ;
}
}
virtual void apply ( const Vec2 & v )
{
_extensions - > glVertexAttrib2fv ( _index , v . ptr ( ) ) ;
}
virtual void apply ( const Vec3 & v )
{
_extensions - > glVertexAttrib3fv ( _index , v . ptr ( ) ) ;
}
virtual void apply ( const Vec4 & v )
{
_extensions - > glVertexAttrib4fv ( _index , v . ptr ( ) ) ;
}
2003-05-07 21:13:13 +08:00
2003-05-22 23:29:20 +08:00
unsigned int _index ;
GLboolean _normalized ;
2003-06-30 05:41:57 +08:00
const Drawable : : Extensions * _extensions ;
2003-05-22 23:29:20 +08:00
const Array * _attribcoords ;
const IndexArray * _indices ;
2003-05-07 21:13:13 +08:00
} ;
2002-10-02 21:12:16 +08:00
class DrawTexCoord : public osg : : Referenced , public osg : : ConstValueVisitor
{
public :
DrawTexCoord ( const Array * texcoords , const IndexArray * indices ) :
_texcoords ( texcoords ) ,
_indices ( indices ) { }
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2002-10-02 21:12:16 +08:00
{
if ( _indices ) _texcoords - > accept ( _indices - > index ( pos ) , * this ) ;
else _texcoords - > accept ( pos , * this ) ;
}
virtual void apply ( const GLfloat & v ) { glTexCoord1f ( v ) ; }
virtual void apply ( const Vec2 & v ) { glTexCoord2fv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec3 & v ) { glTexCoord3fv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec4 & v ) { glTexCoord4fv ( v . ptr ( ) ) ; }
const Array * _texcoords ;
const IndexArray * _indices ;
} ;
class DrawMultiTexCoord : public osg : : Referenced , public osg : : ConstValueVisitor
{
public :
DrawMultiTexCoord ( GLenum target , const Array * texcoords , const IndexArray * indices ,
2003-06-30 05:41:57 +08:00
const Drawable : : Extensions * extensions ) :
2002-10-02 21:12:16 +08:00
_target ( target ) ,
_texcoords ( texcoords ) ,
_indices ( indices ) ,
2003-05-07 21:13:13 +08:00
_extensions ( extensions ) { }
2002-10-02 21:12:16 +08:00
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2002-10-02 21:12:16 +08:00
{
if ( _indices ) _texcoords - > accept ( _indices - > index ( pos ) , * this ) ;
else _texcoords - > accept ( pos , * this ) ;
}
2003-05-07 21:13:13 +08:00
virtual void apply ( const GLfloat & v ) { _extensions - > glMultiTexCoord1f ( _target , v ) ; }
virtual void apply ( const Vec2 & v ) { _extensions - > glMultiTexCoord2fv ( _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 ( ) ) ; }
2002-10-02 21:12:16 +08:00
GLenum _target ;
const Array * _texcoords ;
const IndexArray * _indices ;
2003-05-07 21:13:13 +08:00
2003-06-30 05:41:57 +08:00
const Drawable : : Extensions * _extensions ;
2002-10-02 21:12:16 +08:00
} ;
class DrawSecondaryColor : public osg : : ConstValueVisitor
{
public :
DrawSecondaryColor ( const Array * colors , const IndexArray * indices ,
2003-06-30 05:41:57 +08:00
const Drawable : : Extensions * extensions ) :
2002-10-02 21:12:16 +08:00
_colors ( colors ) ,
_indices ( indices ) ,
2003-05-07 21:13:13 +08:00
_extensions ( extensions )
{ }
2002-10-02 21:12:16 +08:00
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2002-10-02 21:12:16 +08:00
{
if ( _indices ) _colors - > accept ( _indices - > index ( pos ) , * this ) ;
else _colors - > accept ( pos , * this ) ;
}
2003-05-07 21:13:13 +08:00
virtual void apply ( const UByte4 & v ) { _extensions - > glSecondaryColor3ubv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec3 & v ) { _extensions - > glSecondaryColor3fv ( v . ptr ( ) ) ; }
virtual void apply ( const Vec4 & v ) { _extensions - > glSecondaryColor3fv ( v . ptr ( ) ) ; }
2002-10-02 21:12:16 +08:00
const Array * _colors ;
const IndexArray * _indices ;
2003-06-30 05:41:57 +08:00
const Drawable : : Extensions * _extensions ;
2002-10-02 21:12:16 +08:00
} ;
class DrawFogCoord : public osg : : ConstValueVisitor
{
public :
2003-06-30 05:41:57 +08:00
DrawFogCoord ( const Array * fogcoords , const IndexArray * indices , const Drawable : : Extensions * extensions ) :
2002-10-02 21:12:16 +08:00
_fogcoords ( fogcoords ) ,
_indices ( indices ) ,
2003-05-07 21:13:13 +08:00
_extensions ( extensions ) { }
2002-10-02 21:12:16 +08:00
2003-08-09 08:46:48 +08:00
inline void operator ( ) ( unsigned int pos )
2002-10-02 21:12:16 +08:00
{
2003-01-05 04:45:53 +08:00
if ( _indices ) _fogcoords - > accept ( _indices - > index ( pos ) , * this ) ;
else _fogcoords - > accept ( pos , * this ) ;
2002-10-02 21:12:16 +08:00
}
2003-05-07 21:13:13 +08:00
virtual void apply ( const GLfloat & v ) { _extensions - > glFogCoordfv ( & v ) ; }
2003-01-05 04:45:53 +08:00
const Array * _fogcoords ;
2002-10-02 21:12:16 +08:00
const IndexArray * _indices ;
2003-06-30 05:41:57 +08:00
const Drawable : : Extensions * _extensions ;
2002-10-02 21:12:16 +08:00
} ;
2002-06-21 03:54:08 +08:00
Geometry : : Geometry ( )
{
2002-06-24 05:43:46 +08:00
_normalBinding = BIND_OFF ;
_colorBinding = BIND_OFF ;
2002-08-16 04:27:33 +08:00
_secondaryColorBinding = BIND_OFF ;
_fogCoordBinding = BIND_OFF ;
2002-10-02 21:12:16 +08:00
_fastPath = false ;
2003-08-09 08:46:48 +08:00
_fastPathHint = true ;
2002-06-21 03:54:08 +08:00
}
Geometry : : Geometry ( const Geometry & geometry , const CopyOp & copyop ) :
Drawable ( geometry , copyop ) ,
2003-05-09 21:07:06 +08:00
# ifdef COMPILE_POSSIBLE_NEW_ARRAY_METHODS
_attributeList ( geometry . _attributeList ) ,
# endif
2003-08-08 08:21:30 +08:00
_vertexArray ( ( copyop ( geometry . _vertexArray . get ( ) ) ) ) ,
_vertexIndices ( dynamic_cast < IndexArray * > ( copyop ( geometry . _vertexIndices . get ( ) ) ) ) ,
2002-06-22 00:45:45 +08:00
_normalBinding ( geometry . _normalBinding ) ,
2002-07-26 05:50:08 +08:00
_normalArray ( dynamic_cast < Vec3Array * > ( copyop ( geometry . _normalArray . get ( ) ) ) ) ,
2003-08-08 08:21:30 +08:00
_normalIndices ( dynamic_cast < IndexArray * > ( copyop ( geometry . _normalIndices . get ( ) ) ) ) ,
2002-06-22 00:45:45 +08:00
_colorBinding ( geometry . _colorBinding ) ,
2002-08-16 04:27:33 +08:00
_colorArray ( copyop ( geometry . _colorArray . get ( ) ) ) ,
2003-08-08 08:21:30 +08:00
_colorIndices ( dynamic_cast < IndexArray * > ( copyop ( geometry . _colorIndices . get ( ) ) ) ) ,
2002-08-16 04:27:33 +08:00
_secondaryColorBinding ( geometry . _secondaryColorBinding ) ,
_secondaryColorArray ( copyop ( geometry . _secondaryColorArray . get ( ) ) ) ,
2003-08-08 08:21:30 +08:00
_secondaryColorIndices ( dynamic_cast < IndexArray * > ( copyop ( geometry . _secondaryColorIndices . get ( ) ) ) ) ,
2002-08-16 04:27:33 +08:00
_fogCoordBinding ( geometry . _fogCoordBinding ) ,
2002-10-02 21:12:16 +08:00
_fogCoordArray ( dynamic_cast < FloatArray * > ( copyop ( geometry . _fogCoordArray . get ( ) ) ) ) ,
2003-08-08 08:21:30 +08:00
_fogCoordIndices ( dynamic_cast < IndexArray * > ( copyop ( geometry . _fogCoordIndices . get ( ) ) ) ) ,
_fastPath ( geometry . _fastPath ) ,
2003-08-09 08:46:48 +08:00
_fastPathHint ( geometry . _fastPathHint )
2002-06-21 03:54:08 +08:00
{
2002-10-02 21:12:16 +08:00
for ( PrimitiveSetList : : const_iterator pitr = geometry . _primitives . begin ( ) ;
2002-07-26 05:50:08 +08:00
pitr ! = geometry . _primitives . end ( ) ;
+ + pitr )
{
2002-09-20 22:51:59 +08:00
PrimitiveSet * primitive = copyop ( pitr - > get ( ) ) ;
2002-07-26 05:50:08 +08:00
if ( primitive ) _primitives . push_back ( primitive ) ;
}
for ( TexCoordArrayList : : const_iterator titr = geometry . _texCoordList . begin ( ) ;
titr ! = geometry . _texCoordList . end ( ) ;
+ + titr )
{
2002-10-02 21:12:16 +08:00
_texCoordList . push_back ( * titr ) ;
2002-07-26 05:50:08 +08:00
}
2003-05-07 21:13:13 +08:00
for ( VertexAttribArrayList : : const_iterator vitr = geometry . _vertexAttribList . begin ( ) ;
vitr ! = geometry . _vertexAttribList . end ( ) ;
+ + vitr )
{
_vertexAttribList . push_back ( * vitr ) ;
}
2002-06-21 03:54:08 +08:00
}
Geometry : : ~ Geometry ( )
{
// no need to delete, all automatically handled by ref_ptr :-)
}
2002-06-27 21:15:34 +08:00
void Geometry : : setTexCoordArray ( unsigned int unit , Array * array )
2002-06-21 03:54:08 +08:00
{
2002-06-22 00:45:45 +08:00
if ( _texCoordList . size ( ) < = unit )
2002-10-02 21:12:16 +08:00
_texCoordList . resize ( unit + 1 ) ;
2002-06-21 03:54:08 +08:00
2002-10-02 21:12:16 +08:00
_texCoordList [ unit ] . first = array ;
2002-06-26 04:27:51 +08:00
dirtyDisplayList ( ) ;
2002-06-21 03:54:08 +08:00
}
2002-06-27 21:15:34 +08:00
Array * Geometry : : getTexCoordArray ( unsigned int unit )
2002-06-21 03:54:08 +08:00
{
2002-10-02 21:12:16 +08:00
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . first . get ( ) ;
2002-06-21 03:54:08 +08:00
else return 0 ;
}
2002-07-18 08:53:03 +08:00
const Array * Geometry : : getTexCoordArray ( unsigned int unit ) const
{
2002-10-02 21:12:16 +08:00
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . first . get ( ) ;
2002-07-18 08:53:03 +08:00
else return 0 ;
}
2002-10-02 21:12:16 +08:00
void Geometry : : setTexCoordIndices ( unsigned int unit , IndexArray * array )
2002-06-21 03:54:08 +08:00
{
2002-10-02 21:12:16 +08:00
if ( _texCoordList . size ( ) < = unit )
_texCoordList . resize ( unit + 1 ) ;
_texCoordList [ unit ] . second = array ;
dirtyDisplayList ( ) ;
}
IndexArray * Geometry : : getTexCoordIndices ( unsigned int unit )
{
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . second . get ( ) ;
else return 0 ;
}
const IndexArray * Geometry : : getTexCoordIndices ( unsigned int unit ) const
{
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . second . get ( ) ;
else return 0 ;
}
2003-05-09 21:07:06 +08:00
# 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
2003-08-21 22:26:40 +08:00
void Geometry : : setVertexAttribArray ( unsigned int index , GLboolean normalize , Array * array , AttributeBinding ab )
2003-05-07 21:13:13 +08:00
{
if ( _vertexAttribList . size ( ) < = index )
{
_vertexAttribList . resize ( index + 1 ) ;
_vertexAttribBindingList . resize ( index + 1 ) ;
}
_vertexAttribList [ index ] . first = normalize ;
_vertexAttribList [ index ] . second . first = array ;
2003-05-09 21:07:06 +08:00
if ( index = = 0 )
{
// Force bind per vertex
_vertexAttribBindingList [ index ] = BIND_PER_VERTEX ;
}
else
{
_vertexAttribBindingList [ index ] = ab ;
}
2003-05-07 21:13:13 +08:00
2003-06-30 05:41:57 +08:00
computeFastPathsUsed ( ) ;
2003-05-07 21:13:13 +08:00
dirtyDisplayList ( ) ;
}
Array * Geometry : : getVertexAttribArray ( unsigned int index )
{
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . second . first . get ( ) ;
else return 0 ;
}
const Array * Geometry : : getVertexAttribArray ( unsigned int index ) const
{
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . second . first . get ( ) ;
else return 0 ;
}
bool Geometry : : getVertexAttribBinding ( unsigned int index , AttributeBinding & ab ) const
{
// AttributeBinding value goes in ab
// return true if index is valid, false otherwise
if ( index < _vertexAttribBindingList . size ( ) )
{
ab = _vertexAttribBindingList [ index ] ;
return true ;
}
else
{
return false ;
}
}
bool Geometry : : getVertexAttribNormalize ( unsigned int index , GLboolean & ret ) const
{
// normalized value goes in ret
// return true if index is valid, false otherwise
if ( index < _vertexAttribList . size ( ) )
{
ret = _vertexAttribList [ index ] . first ;
return true ;
}
else
{
return false ;
}
}
void Geometry : : setVertexAttribIndices ( unsigned int index , IndexArray * array )
{
if ( _vertexAttribList . size ( ) < = index )
_vertexAttribList . resize ( index + 1 ) ;
_vertexAttribList [ index ] . second . second = array ;
dirtyDisplayList ( ) ;
}
IndexArray * Geometry : : getVertexAttribIndices ( unsigned int index )
{
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . second . second . get ( ) ;
else return 0 ;
}
const IndexArray * Geometry : : getVertexAttribIndices ( unsigned int index ) const
{
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . second . second . get ( ) ;
else return 0 ;
}
2002-11-21 17:07:11 +08:00
bool Geometry : : addPrimitiveSet ( PrimitiveSet * primitiveset )
{
if ( primitiveset )
{
_primitives . push_back ( primitiveset ) ;
dirtyDisplayList ( ) ;
dirtyBound ( ) ;
return true ;
}
notify ( WARN ) < < " Warning: invalid index i or primitiveset passed to osg::Geometry::addPrimitiveSet(i,primitiveset), ignoring call. " < < std : : endl ;
return false ;
}
bool Geometry : : setPrimitiveSet ( unsigned int i , PrimitiveSet * primitiveset )
{
if ( i < _primitives . size ( ) & & primitiveset )
{
_primitives [ i ] = primitiveset ;
dirtyDisplayList ( ) ;
dirtyBound ( ) ;
return true ;
}
notify ( WARN ) < < " Warning: invalid index i or primitiveset passed to osg::Geometry::setPrimitiveSet(i,primitiveset), ignoring call. " < < std : : endl ;
return false ;
}
bool Geometry : : insertPrimitiveSet ( unsigned int i , PrimitiveSet * primitiveset )
{
if ( primitiveset )
{
if ( i < _primitives . size ( ) )
{
_primitives . insert ( _primitives . begin ( ) + i , primitiveset ) ;
dirtyDisplayList ( ) ;
dirtyBound ( ) ;
return true ;
}
else if ( i = = _primitives . size ( ) )
{
return addPrimitiveSet ( primitiveset ) ;
}
}
notify ( WARN ) < < " Warning: invalid index i or primitiveset passed to osg::Geometry::insertPrimitiveSet(i,primitiveset), ignoring call. " < < std : : endl ;
return false ;
}
bool Geometry : : removePrimitiveSet ( unsigned int i , unsigned int numElementsToRemove )
{
if ( i < _primitives . size ( ) & & numElementsToRemove > 0 )
{
2003-04-01 23:08:30 +08:00
if ( i + numElementsToRemove < = _primitives . size ( ) )
2002-11-21 17:07:11 +08:00
{
_primitives . erase ( _primitives . begin ( ) + i , _primitives . begin ( ) + i + numElementsToRemove ) ;
}
else
{
// asking to delete too many elements, report a warning, and delete to
// the end of the primitive list.
notify ( WARN ) < < " Warning: osg::Geometry::removePrimitiveSet(i,numElementsToRemove) has been asked to remove more elements than are available, " < < std : : endl ;
2002-11-22 04:28:28 +08:00
notify ( WARN ) < < " removing on from i to the end of the list of primitive sets. " < < std : : endl ;
2002-11-21 17:07:11 +08:00
_primitives . erase ( _primitives . begin ( ) + i , _primitives . end ( ) ) ;
}
dirtyDisplayList ( ) ;
dirtyBound ( ) ;
return true ;
}
notify ( WARN ) < < " Warning: invalid index i passed to osg::Geometry::removePrimitiveSet(i,numElementsToRemove), ignoring call. " < < std : : endl ;
return false ;
}
unsigned int Geometry : : getPrimitiveSetIndex ( const PrimitiveSet * primitiveset ) const
{
for ( unsigned int primitiveSetIndex = 0 ; primitiveSetIndex < _primitives . size ( ) ; + + primitiveSetIndex )
{
if ( _primitives [ primitiveSetIndex ] = = primitiveset ) return primitiveSetIndex ;
}
return _primitives . size ( ) ; // node not found.
}
2003-06-30 05:41:57 +08:00
bool Geometry : : computeFastPathsUsed ( )
2002-10-02 21:12:16 +08:00
{
2002-08-16 04:27:33 +08:00
2003-06-30 05:41:57 +08:00
/*
2002-08-16 04:27:33 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
2002-10-02 21:12:16 +08:00
// set up normals if required.
2002-08-16 04:27:33 +08:00
//
2002-10-02 21:12:16 +08:00
if ( ! _normalArray . valid ( ) | |
_normalArray - > empty ( ) | |
( _normalIndices . valid ( ) & & _normalIndices - > getNumElements ( ) = = 0 ) )
2002-06-21 03:54:08 +08:00
{
2002-10-02 21:12:16 +08:00
// switch off if not supported or have a valid data.
_normalBinding = BIND_OFF ;
2002-06-21 03:54:08 +08:00
}
2002-10-02 21:12:16 +08:00
2002-08-16 04:27:33 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
2002-10-02 21:12:16 +08:00
// set up colours..
2002-08-16 04:27:33 +08:00
//
2002-10-02 21:12:16 +08:00
if ( ! _colorArray . valid ( ) | |
_colorArray - > getNumElements ( ) = = 0 | |
( _colorIndices . valid ( ) & & _colorIndices - > getNumElements ( ) = = 0 ) )
2002-08-16 04:27:33 +08:00
{
// switch off if not supported or have a valid data.
2002-10-02 21:12:16 +08:00
_colorBinding = BIND_OFF ;
2002-08-16 04:27:33 +08:00
}
2002-06-21 03:54:08 +08:00
2002-08-16 04:27:33 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
2002-10-02 21:12:16 +08:00
// Set up secondary color if required.
2002-08-16 04:27:33 +08:00
//
2002-10-02 21:12:16 +08:00
if ( ! _secondaryColorArray . valid ( ) | |
_secondaryColorArray - > getNumElements ( ) = = 0 | |
( _secondaryColorIndices . valid ( ) & & _secondaryColorIndices - > getNumElements ( ) = = 0 ) )
2002-06-21 03:54:08 +08:00
{
2002-10-02 21:12:16 +08:00
// switch off if not supported or have a valid data.
_secondaryColorBinding = BIND_OFF ;
2002-06-21 03:54:08 +08:00
}
2002-10-02 21:12:16 +08:00
2002-08-16 04:27:33 +08:00
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set up fog coord if required.
//
if ( ! _fogCoordArray . valid ( ) | |
_fogCoordArray - > getNumElements ( ) = = 0 | |
( _fogCoordIndices . valid ( ) & & _fogCoordIndices - > getNumElements ( ) = = 0 ) )
2002-08-16 04:27:33 +08:00
{
// switch off if not supported or have a valid data.
2002-10-02 21:12:16 +08:00
_fogCoordBinding = BIND_OFF ;
2002-08-16 04:27:33 +08:00
}
2002-06-21 03:54:08 +08:00
2003-05-07 21:13:13 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set up vertex attrib if required.
//
for ( unsigned int va = 0 ; va < _vertexAttribList . size ( ) ; + + va )
{
const Array * array = _vertexAttribList [ va ] . second . first . get ( ) ;
const IndexArray * idxArray = _vertexAttribList [ va ] . second . second . get ( ) ;
if ( ! array | |
array - > getNumElements ( ) = = 0 | |
( idxArray & & idxArray - > getNumElements ( ) = = 0 ) )
{
// switch off if not supported or have a valid data.
_vertexAttribBindingList [ va ] = BIND_OFF ;
}
}
2003-06-30 05:41:57 +08:00
*/
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// check to see if fast path can be used.
//
_fastPath = true ;
2003-08-05 06:03:55 +08:00
if ( _vertexIndices . valid ( ) ) _fastPath = false ;
else if ( _normalBinding = = BIND_PER_PRIMITIVE | | ( _normalBinding = = BIND_PER_VERTEX & & _normalIndices . valid ( ) ) ) _fastPath = false ;
2002-10-02 21:12:16 +08:00
else if ( _colorBinding = = BIND_PER_PRIMITIVE | | ( _colorBinding = = BIND_PER_VERTEX & & _colorIndices . valid ( ) ) ) _fastPath = false ;
else if ( _secondaryColorBinding = = BIND_PER_PRIMITIVE | | ( _secondaryColorBinding = = BIND_PER_VERTEX & & _secondaryColorIndices . valid ( ) ) ) _fastPath = false ;
else if ( _fogCoordBinding = = BIND_PER_PRIMITIVE | | ( _fogCoordBinding = = BIND_PER_VERTEX & & _fogCoordIndices . valid ( ) ) ) _fastPath = false ;
2003-05-07 21:13:13 +08:00
else
{
for ( unsigned int va = 0 ; va < _vertexAttribBindingList . size ( ) ; + + va )
{
if ( _vertexAttribBindingList [ va ] = = BIND_PER_PRIMITIVE )
{
_fastPath = false ;
break ;
}
else
{
const Array * array = _vertexAttribList [ va ] . second . first . get ( ) ;
const IndexArray * idxArray = _vertexAttribList [ va ] . second . second . get ( ) ;
if ( _vertexAttribBindingList [ va ] = = BIND_PER_VERTEX & &
array & & array - > getNumElements ( ) > 0 & &
idxArray & & idxArray - > getNumElements ( ) > 0 )
{
_fastPath = false ;
break ;
}
}
}
}
2002-06-21 03:54:08 +08:00
2002-08-16 04:27:33 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
2002-10-02 21:12:16 +08:00
// Set up tex coords if required.
2002-08-16 04:27:33 +08:00
//
2002-10-02 21:12:16 +08:00
for ( unsigned int unit = 0 ; unit ! = _texCoordList . size ( ) ; + + unit )
2002-08-16 04:27:33 +08:00
{
2003-06-30 05:41:57 +08:00
const ArrayPair & texcoordPair = _texCoordList [ unit ] ;
2002-10-02 21:12:16 +08:00
if ( texcoordPair . first . valid ( ) & & texcoordPair . first - > getNumElements ( ) > 0 )
2002-08-16 04:27:33 +08:00
{
2002-10-02 21:12:16 +08:00
if ( texcoordPair . second . valid ( ) )
2002-08-16 04:27:33 +08:00
{
2002-10-02 21:12:16 +08:00
if ( texcoordPair . second - > getNumElements ( ) > 0 )
{
2003-05-07 21:13:13 +08:00
_fastPath = false ;
break ;
2002-10-02 21:12:16 +08:00
}
2002-08-16 04:27:33 +08:00
}
}
}
2003-06-30 05:41:57 +08:00
_supportsVertexBufferObjects = _fastPath ;
//_supportsVertexBufferObjects = false;
//_useVertexBufferObjects = false;
2002-10-02 21:12:16 +08:00
return _fastPath ;
}
2002-11-06 23:43:11 +08:00
void Geometry : : drawImplementation ( State & state ) const
2002-10-02 21:12:16 +08:00
{
2003-08-08 08:21:30 +08:00
if ( _internalOptimizedGeometry . valid ( ) )
{
_internalOptimizedGeometry - > drawImplementation ( state ) ;
return ;
}
2003-05-07 21:13:13 +08:00
const Extensions * extensions = getExtensions ( state . getContextID ( ) , true ) ;
if ( ! ( ( _vertexArray . valid ( ) & & _vertexArray - > getNumElements ( ) ! = 0 ) | |
( _vertexAttribList . size ( ) > 0 & &
_vertexAttribList [ 0 ] . second . first . valid ( ) & &
_vertexAttribList [ 0 ] . second . first - > getNumElements ( ) ! = 0 ) ) )
{
return ;
}
2002-08-18 19:16:31 +08:00
2003-05-07 21:13:13 +08:00
if ( ( _vertexIndices . valid ( ) & & _vertexIndices - > getNumElements ( ) = = 0 ) | |
( _vertexAttribList . size ( ) > 0 & &
_vertexAttribList [ 0 ] . second . second . valid ( ) & &
_vertexAttribList [ 0 ] . second . second - > getNumElements ( ) = = 0 ) )
{
return ;
}
2002-10-02 21:12:16 +08:00
DrawNormal drawNormal ( _normalArray . get ( ) , _normalIndices . get ( ) ) ;
DrawColor drawColor ( _colorArray . get ( ) , _colorIndices . get ( ) ) ;
2003-05-07 21:13:13 +08:00
DrawSecondaryColor drawSecondaryColor ( _secondaryColorArray . get ( ) , _secondaryColorIndices . get ( ) , extensions ) ;
2002-10-02 21:12:16 +08:00
2003-05-07 21:13:13 +08:00
DrawFogCoord drawFogCoord ( _fogCoordArray . get ( ) , _fogCoordIndices . get ( ) , extensions ) ;
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set up secondary color if required.
//
2002-08-16 04:27:33 +08:00
AttributeBinding secondaryColorBinding = _secondaryColorBinding ;
2003-05-07 21:13:13 +08:00
if ( secondaryColorBinding ! = BIND_OFF & & ! extensions - > isSecondaryColorSupported ( ) )
2002-08-16 04:27:33 +08:00
{
// switch off if not supported or have a valid data.
secondaryColorBinding = BIND_OFF ;
}
2002-10-02 21:12:16 +08:00
2002-08-16 04:27:33 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set up fog coord if required.
//
AttributeBinding fogCoordBinding = _fogCoordBinding ;
2003-05-07 21:13:13 +08:00
if ( fogCoordBinding ! = BIND_OFF & & ! extensions - > isFogCoordSupported ( ) )
2002-08-16 04:27:33 +08:00
{
2002-10-02 21:12:16 +08:00
// switch off if not supported or have a valid data.
2002-08-16 04:27:33 +08:00
fogCoordBinding = BIND_OFF ;
}
2002-10-02 21:12:16 +08:00
2003-05-07 21:13:13 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set up vertex attrib if required.
//
if ( ! extensions - > isVertexProgramSupported ( ) )
{
for ( unsigned int va = 0 ; va < _vertexAttribBindingList . size ( ) ; + + va )
{
if ( _vertexAttribBindingList [ va ] ! = BIND_OFF )
{
_vertexAttribBindingList [ va ] = BIND_OFF ;
}
}
}
2002-10-02 21:12:16 +08:00
unsigned int normalIndex = 0 ;
unsigned int colorIndex = 0 ;
unsigned int secondaryColorIndex = 0 ;
unsigned int fogCoordIndex = 0 ;
2003-05-07 21:13:13 +08:00
unsigned int vertexAttribIndex = 0 ;
2002-10-02 21:12:16 +08:00
2003-01-20 19:02:27 +08:00
# if USE_DEFAULT_NORMAL
2002-10-18 20:26:23 +08:00
// if no values are defined for normal and color provide some defaults...
if ( _normalBinding = = BIND_OFF ) glNormal3f ( 0.0f , 0.0f , 1.0f ) ;
2003-01-20 19:02:27 +08:00
# endif
2003-02-10 21:58:39 +08:00
# if USE_DEFAULT_COLOUR
2002-10-18 20:26:23 +08:00
if ( _colorBinding = = BIND_OFF ) glColor4f ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
2003-01-20 19:02:27 +08:00
# endif
2002-10-18 20:26:23 +08:00
2003-05-07 21:13:13 +08:00
typedef std : : vector < ref_ptr < DrawVertexAttrib > > DrawVertexAttribList ;
typedef std : : map < Geometry : : AttributeBinding , DrawVertexAttribList > DrawVertexAttribMap ;
DrawVertexAttribMap drawVertexAttribMap ;
2003-06-30 05:41:57 +08:00
bool handleVertexAttributes = ( ! _vertexAttribList . empty ( ) & & extensions - > isVertexProgramSupported ( ) ) ;
2003-07-07 16:01:09 +08:00
bool usingVertexBufferObjects = _useVertexBufferObjects & & state . isVertexBufferObjectSupported ( ) ;
2003-06-30 05:41:57 +08:00
2002-10-02 21:12:16 +08:00
if ( areFastPathsUsed ( ) )
2002-08-16 04:27:33 +08:00
{
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// fast path.
//
2003-07-07 16:01:09 +08:00
if ( usingVertexBufferObjects )
2003-06-30 05:41:57 +08:00
{
//
// Vertex Buffer Object path for defining vertex arrays.
//
2002-10-02 21:12:16 +08:00
2003-06-30 05:41:57 +08:00
GLuint & buffer = _vboList [ state . getContextID ( ) ] ;
if ( ! buffer )
{
2002-10-02 21:12:16 +08:00
2003-06-30 05:41:57 +08:00
//std::cout << "creating VertexBuffer "<<buffer<<std::endl;
2002-10-02 21:12:16 +08:00
2003-06-30 05:41:57 +08:00
extensions - > glGenBuffers ( 1 , & buffer ) ;
extensions - > glBindBuffer ( GL_ARRAY_BUFFER_ARB , buffer ) ;
//std::cout << " gen VertexBuffer "<<buffer<<std::endl;
2002-10-02 21:12:16 +08:00
2003-06-30 05:41:57 +08:00
// compute total size and offsets required.
unsigned int totalSize = 0 ;
_vertexOffset = 0 ;
if ( _vertexArray . valid ( ) ) totalSize + = _vertexArray - > getTotalDataSize ( ) ;
_normalOffset = totalSize ;
if ( _normalArray . valid ( ) ) totalSize + = _normalArray - > getTotalDataSize ( ) ;
_colorOffset = totalSize ;
if ( _colorArray . valid ( ) ) totalSize + = _colorArray - > getTotalDataSize ( ) ;
_secondaryColorOffset = totalSize ;
if ( _secondaryColorArray . valid ( ) ) totalSize + = _secondaryColorArray - > getTotalDataSize ( ) ;
_fogCoordOffset = totalSize ;
if ( _fogCoordArray . valid ( ) ) totalSize + = _fogCoordArray - > getTotalDataSize ( ) ;
2003-05-07 21:13:13 +08:00
2003-06-30 05:41:57 +08:00
unsigned int unit ;
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
2003-05-07 21:13:13 +08:00
{
2003-06-30 05:41:57 +08:00
_texCoordList [ unit ] . offset = totalSize ;
const Array * array = _texCoordList [ unit ] . first . get ( ) ;
if ( array )
totalSize + = array - > getTotalDataSize ( ) ;
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
2003-06-30 05:41:57 +08:00
unsigned int index ;
for ( index = 0 ; index < _vertexAttribList . size ( ) ; + + index )
2003-05-07 21:13:13 +08:00
{
2003-06-30 05:41:57 +08:00
_texCoordList [ unit ] . offset = totalSize ;
const Array * array = _vertexAttribList [ index ] . second . first . get ( ) ;
const AttributeBinding ab = _vertexAttribBindingList [ index ] ;
if ( ab = = BIND_PER_VERTEX & & array )
2003-05-07 21:13:13 +08:00
{
2003-06-30 05:41:57 +08:00
totalSize + = array - > getTotalDataSize ( ) ;
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
}
}
// allocated the buffer space, but leave the copy to be done per vertex array below
extensions - > glBufferData ( GL_ARRAY_BUFFER_ARB , totalSize , 0 , GL_STATIC_DRAW_ARB ) ;
//std::cout << " Created VertexBuffer "<<buffer<<" size="<<totalSize<<std::endl;
//
// copy the data
//
if ( _vertexArray . valid ( ) )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _vertexOffset , _vertexArray - > getTotalDataSize ( ) , _vertexArray - > getDataPointer ( ) ) ;
if ( _normalBinding = = BIND_PER_VERTEX )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _normalOffset , _normalArray - > getTotalDataSize ( ) , _normalArray - > getDataPointer ( ) ) ;
if ( _colorBinding = = BIND_PER_VERTEX )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _colorOffset , _colorArray - > getTotalDataSize ( ) , _colorArray - > getDataPointer ( ) ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _secondaryColorOffset , _secondaryColorArray - > getTotalDataSize ( ) , _secondaryColorArray - > getDataPointer ( ) ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _fogCoordOffset , _fogCoordArray - > getTotalDataSize ( ) , _fogCoordArray - > getDataPointer ( ) ) ;
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
{
const Array * array = _texCoordList [ unit ] . first . get ( ) ;
if ( array )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _texCoordList [ unit ] . offset , array - > getTotalDataSize ( ) , array - > getDataPointer ( ) ) ;
}
if ( handleVertexAttributes )
{
unsigned int index ;
for ( index = 0 ; index < _vertexAttribList . size ( ) ; + + index )
{
const Array * array = _vertexAttribList [ index ] . second . first . get ( ) ;
const AttributeBinding ab = _vertexAttribBindingList [ index ] ;
if ( ab = = BIND_PER_VERTEX & & array )
2003-05-09 21:07:06 +08:00
{
2003-06-30 05:41:57 +08:00
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _vertexAttribList [ index ] . second . offset , array - > getTotalDataSize ( ) , array - > getDataPointer ( ) ) ;
2003-05-09 21:07:06 +08:00
}
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
}
}
//std::cout << "binding VertexBuffer "<<buffer<<std::endl;
2003-05-07 21:13:13 +08:00
2003-07-02 09:56:12 +08:00
extensions - > glBindBuffer ( GL_ARRAY_BUFFER_ARB , buffer ) ;
2003-06-30 05:41:57 +08:00
if ( _vertexArray . valid ( ) )
state . setVertexPointer ( _vertexArray - > getDataSize ( ) , _vertexArray - > getDataType ( ) , 0 , ( const GLvoid * ) _vertexOffset ) ;
else
state . disableVertexPointer ( ) ;
if ( _normalBinding = = BIND_PER_VERTEX )
state . setNormalPointer ( GL_FLOAT , 0 , ( const GLvoid * ) _normalOffset ) ;
else
state . disableNormalPointer ( ) ;
if ( _colorBinding = = BIND_PER_VERTEX )
state . setColorPointer ( _colorArray - > getDataSize ( ) , _colorArray - > getDataType ( ) , 0 , ( const GLvoid * ) _colorOffset ) ;
else
state . disableColorPointer ( ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX )
state . setSecondaryColorPointer ( _secondaryColorArray - > getDataSize ( ) , _secondaryColorArray - > getDataType ( ) , 0 , ( const GLvoid * ) _secondaryColorOffset ) ;
else
state . disableSecondaryColorPointer ( ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX )
state . setFogCoordPointer ( GL_FLOAT , 0 , ( const GLvoid * ) _fogCoordOffset ) ;
else
state . disableFogCoordPointer ( ) ;
unsigned int unit ;
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
{
const Array * array = _texCoordList [ unit ] . first . get ( ) ;
if ( array )
state . setTexCoordPointer ( unit , array - > getDataSize ( ) , array - > getDataType ( ) , 0 , ( const GLvoid * ) _texCoordList [ unit ] . offset ) ;
else
state . disableTexCoordPointer ( unit ) ;
}
state . disableTexCoordPointersAboveAndIncluding ( unit ) ;
if ( handleVertexAttributes )
{
unsigned int index ;
for ( index = 0 ; index < _vertexAttribList . size ( ) ; + + index )
{
const Array * array = _vertexAttribList [ index ] . second . first . get ( ) ;
const AttributeBinding ab = _vertexAttribBindingList [ index ] ;
if ( ab = = BIND_PER_VERTEX & & array )
{
state . setVertexAttribPointer ( index , array - > getDataSize ( ) , array - > getDataType ( ) ,
_vertexAttribList [ index ] . first , 0 , ( const GLvoid * ) _vertexAttribList [ index ] . second . offset ) ;
}
else
{
if ( array )
{
const IndexArray * indexArray = _vertexAttribList [ index ] . second . second . get ( ) ;
if ( indexArray & & indexArray - > getNumElements ( ) > 0 )
{
drawVertexAttribMap [ ab ] . push_back (
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . first , array , indexArray ) ) ;
}
else
{
drawVertexAttribMap [ ab ] . push_back (
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . first , array , 0 ) ) ;
}
}
state . disableVertexAttribPointer ( index ) ;
}
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
state . disableVertexAttribPointersAboveAndIncluding ( index ) ;
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
else
{
//std::cout << "none VertexBuffer path"<<std::endl;
//
// None Vertex Buffer Object path for defining vertex arrays.
//
if ( _vertexArray . valid ( ) )
state . setVertexPointer ( _vertexArray - > getDataSize ( ) , _vertexArray - > getDataType ( ) , 0 , _vertexArray - > getDataPointer ( ) ) ;
else
state . disableVertexPointer ( ) ;
if ( _normalBinding = = BIND_PER_VERTEX )
state . setNormalPointer ( GL_FLOAT , 0 , _normalArray - > getDataPointer ( ) ) ;
else
state . disableNormalPointer ( ) ;
if ( _colorBinding = = BIND_PER_VERTEX )
state . setColorPointer ( _colorArray - > getDataSize ( ) , _colorArray - > getDataType ( ) , 0 , _colorArray - > getDataPointer ( ) ) ;
else
state . disableColorPointer ( ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX )
state . setSecondaryColorPointer ( _secondaryColorArray - > getDataSize ( ) , _secondaryColorArray - > getDataType ( ) , 0 , _secondaryColorArray - > getDataPointer ( ) ) ;
else
state . disableSecondaryColorPointer ( ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX )
state . setFogCoordPointer ( GL_FLOAT , 0 , _fogCoordArray - > getDataPointer ( ) ) ;
else
state . disableFogCoordPointer ( ) ;
unsigned int unit ;
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
{
const Array * array = _texCoordList [ unit ] . first . get ( ) ;
if ( array )
state . setTexCoordPointer ( unit , array - > getDataSize ( ) , array - > getDataType ( ) , 0 , array - > getDataPointer ( ) ) ;
else
state . disableTexCoordPointer ( unit ) ;
}
state . disableTexCoordPointersAboveAndIncluding ( unit ) ;
if ( handleVertexAttributes )
{
unsigned int index ;
for ( index = 0 ; index < _vertexAttribList . size ( ) ; + + index )
{
const Array * array = _vertexAttribList [ index ] . second . first . get ( ) ;
const AttributeBinding ab = _vertexAttribBindingList [ index ] ;
if ( ab = = BIND_PER_VERTEX & & array )
{
state . setVertexAttribPointer ( index , array - > getDataSize ( ) , array - > getDataType ( ) ,
_vertexAttribList [ index ] . first , 0 , array - > getDataPointer ( ) ) ;
}
else
{
if ( array )
{
const IndexArray * indexArray = _vertexAttribList [ index ] . second . second . get ( ) ;
if ( indexArray & & indexArray - > getNumElements ( ) > 0 )
{
drawVertexAttribMap [ ab ] . push_back (
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . first , array , indexArray ) ) ;
}
else
{
drawVertexAttribMap [ ab ] . push_back (
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . first , array , 0 ) ) ;
}
}
2002-10-02 21:12:16 +08:00
2003-06-30 05:41:57 +08:00
state . disableVertexAttribPointer ( index ) ;
}
}
state . disableVertexAttribPointersAboveAndIncluding ( index ) ;
}
}
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// pass the overall binding values onto OpenGL.
//
if ( _normalBinding = = BIND_OVERALL ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_OVERALL ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_OVERALL ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_OVERALL ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_OVERALL ] ;
2002-10-02 21:12:16 +08:00
2003-05-07 21:13:13 +08:00
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// draw the primitives themselves.
//
2002-11-06 23:43:11 +08:00
for ( PrimitiveSetList : : const_iterator itr = _primitives . begin ( ) ;
2002-10-02 21:12:16 +08:00
itr ! = _primitives . end ( ) ;
+ + itr )
2002-06-22 00:45:45 +08:00
{
2002-10-02 21:12:16 +08:00
if ( _normalBinding = = BIND_PER_PRIMITIVE_SET ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE_SET ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE_SET ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE_SET ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE_SET ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
( * itr ) - > draw ( ) ;
}
2003-07-07 16:01:09 +08:00
if ( usingVertexBufferObjects )
2003-06-30 05:41:57 +08:00
{
2003-07-02 09:56:12 +08:00
extensions - > glBindBuffer ( GL_ARRAY_BUFFER_ARB , 0 ) ;
2003-06-30 05:41:57 +08:00
}
2002-10-02 21:12:16 +08:00
}
else
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// slow path.
//
typedef std : : vector < ref_ptr < DrawMultiTexCoord > > DrawTexCoordList ;
DrawTexCoordList drawTexCoordList ;
drawTexCoordList . reserve ( _texCoordList . size ( ) ) ;
// fallback if multitexturing not supported.
ref_ptr < DrawTexCoord > drawTextCoord ;
2003-05-07 21:13:13 +08:00
if ( extensions - > isMultiTexSupported ( ) )
2002-10-02 21:12:16 +08:00
{
// multitexture supported..
for ( unsigned int unit = 0 ; unit ! = _texCoordList . size ( ) ; + + unit )
2002-06-22 00:45:45 +08:00
{
2003-06-30 05:41:57 +08:00
const ArrayPair & texcoordPair = _texCoordList [ unit ] ;
2002-10-02 21:12:16 +08:00
if ( texcoordPair . first . valid ( ) & & texcoordPair . first - > getNumElements ( ) > 0 )
{
if ( texcoordPair . second . valid ( ) )
{
if ( texcoordPair . second - > getNumElements ( ) > 0 )
{
drawTexCoordList . push_back ( new DrawMultiTexCoord ( GL_TEXTURE0 + unit , texcoordPair . first . get ( ) , texcoordPair . second . get ( ) ,
2003-05-07 21:13:13 +08:00
extensions ) ) ;
2002-10-02 21:12:16 +08:00
}
}
else
{
drawTexCoordList . push_back ( new DrawMultiTexCoord ( GL_TEXTURE0 + unit , texcoordPair . first . get ( ) , 0 ,
2003-05-07 21:13:13 +08:00
extensions ) ) ;
2002-10-02 21:12:16 +08:00
}
}
}
}
else
{
if ( ! _texCoordList . empty ( ) )
{
2003-06-30 05:41:57 +08:00
const ArrayPair & texcoordPair = _texCoordList [ 0 ] ;
2002-10-02 21:12:16 +08:00
if ( texcoordPair . first . valid ( ) & & texcoordPair . first - > getNumElements ( ) > 0 )
{
if ( texcoordPair . second . valid ( ) )
{
if ( texcoordPair . second - > getNumElements ( ) > 0 )
{
drawTextCoord = new DrawTexCoord ( texcoordPair . first . get ( ) , texcoordPair . second . get ( ) ) ;
}
}
else
{
drawTextCoord = new DrawTexCoord ( texcoordPair . first . get ( ) , 0 ) ;
}
}
2002-06-22 00:45:45 +08:00
}
2002-06-21 03:54:08 +08:00
}
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
unsigned int index ;
2003-05-09 21:07:06 +08:00
for ( index = 1 ; index < _vertexAttribList . size ( ) ; + + index )
2003-05-07 21:13:13 +08:00
{
const Array * array = _vertexAttribList [ index ] . second . first . get ( ) ;
2003-05-09 21:07:06 +08:00
if ( array & & array - > getNumElements ( ) > 0 )
2003-05-07 21:13:13 +08:00
{
2003-05-09 21:07:06 +08:00
const IndexArray * indexArray = _vertexAttribList [ index ] . second . second . get ( ) ;
if ( indexArray & & indexArray - > getNumElements ( ) > 0 )
2003-05-07 21:13:13 +08:00
{
drawVertexAttribMap [ _vertexAttribBindingList [ index ] ] . push_back (
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . first , array , indexArray ) ) ;
}
2003-05-09 21:07:06 +08:00
else
{
drawVertexAttribMap [ _vertexAttribBindingList [ index ] ] . push_back (
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . first , array , 0 ) ) ;
}
2003-05-07 21:13:13 +08:00
}
}
}
2002-10-02 21:12:16 +08:00
// disable all the vertex arrays in the slow path as we are
// sending everything using glVertex etc.
state . disableAllVertexArrays ( ) ;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// pass the overall binding values onto OpenGL.
//
if ( _normalBinding = = BIND_OVERALL ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_OVERALL ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_OVERALL ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_OVERALL ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_OVERALL ] ;
2002-10-02 21:12:16 +08:00
2003-05-07 21:13:13 +08:00
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
// set up vertex functor.
DrawVertex drawVertex ( _vertexArray . get ( ) , _vertexIndices . get ( ) ) ;
2003-05-09 21:07:06 +08:00
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 ( ) ) ;
}
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// draw the primitives themselves.
//
2002-11-06 23:43:11 +08:00
for ( PrimitiveSetList : : const_iterator itr = _primitives . begin ( ) ;
2002-10-02 21:12:16 +08:00
itr ! = _primitives . end ( ) ;
+ + itr )
2002-08-16 04:27:33 +08:00
{
2002-10-02 21:12:16 +08:00
if ( _normalBinding = = BIND_PER_PRIMITIVE_SET ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE_SET ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE_SET ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE_SET ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE_SET ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-11-06 23:43:11 +08:00
const PrimitiveSet * primitiveset = itr - > get ( ) ;
2002-10-02 21:12:16 +08:00
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 primtives by the more flexible "slow" path,
// sending OpenGL glBegin/glVertex.../glEnd().
switch ( primitiveset - > getType ( ) )
2002-08-16 04:27:33 +08:00
{
2002-10-02 21:12:16 +08:00
case ( PrimitiveSet : : DrawArraysPrimitiveType ) :
{
if ( primLength = = 0 ) primLength = primitiveset - > getNumIndices ( ) ;
const DrawArrays * drawArray = static_cast < const DrawArrays * > ( primitiveset ) ;
glBegin ( 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 )
{
if ( _normalBinding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
}
if ( _normalBinding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorBinding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX ) drawSecondaryColor ( vindex ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX ) drawFogCoord ( vindex ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_VERTEX ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
for ( DrawTexCoordList : : iterator texItr = drawTexCoordList . begin ( ) ;
texItr ! = drawTexCoordList . end ( ) ;
+ + texItr )
{
( * ( * texItr ) ) ( vindex ) ;
}
if ( drawTextCoord . valid ( ) ) ( * drawTextCoord ) ( vindex ) ;
2003-05-09 21:07:06 +08:00
if ( useVertexAttrib )
{
( * drawVertexAttribZero ) ( vindex ) ;
}
else
{
drawVertex ( vindex ) ;
}
2002-10-02 21:12:16 +08:00
}
glEnd ( ) ;
2002-08-16 04:27:33 +08:00
break ;
2002-10-02 21:12:16 +08:00
}
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 ;
glBegin ( mode ) ;
for ( GLsizei primCount = 0 ; primCount < * primItr ; + + primCount )
{
if ( ( primCount % localPrimLength ) = = 0 )
{
if ( _normalBinding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
}
if ( _normalBinding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorBinding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX ) drawSecondaryColor ( vindex ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX ) drawFogCoord ( vindex ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_VERTEX ] ;
2002-10-02 21:12:16 +08:00
2003-05-07 21:13:13 +08:00
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
for ( DrawTexCoordList : : iterator texItr = drawTexCoordList . begin ( ) ;
texItr ! = drawTexCoordList . end ( ) ;
+ + texItr )
{
( * ( * texItr ) ) ( vindex ) ;
}
if ( drawTextCoord . valid ( ) ) ( * drawTextCoord ) ( vindex ) ;
2003-05-09 21:07:06 +08:00
if ( useVertexAttrib )
{
( * drawVertexAttribZero ) ( vindex ) ;
}
else
{
drawVertex ( vindex ) ;
}
2002-10-02 21:12:16 +08:00
+ + vindex ;
}
glEnd ( ) ;
}
2002-08-16 04:27:33 +08:00
break ;
2002-10-02 21:12:16 +08:00
}
case ( PrimitiveSet : : DrawElementsUBytePrimitiveType ) :
{
if ( primLength = = 0 ) primLength = primitiveset - > getNumIndices ( ) ;
const DrawElementsUByte * drawElements = static_cast < const DrawElementsUByte * > ( primitiveset ) ;
glBegin ( mode ) ;
unsigned int primCount = 0 ;
for ( DrawElementsUByte : : const_iterator primItr = drawElements - > begin ( ) ;
primItr ! = drawElements - > end ( ) ;
+ + primCount , + + primItr )
{
if ( ( primCount % primLength ) = = 0 )
{
if ( _normalBinding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
}
unsigned int vindex = * primItr ;
if ( _normalBinding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorBinding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX ) drawSecondaryColor ( vindex ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX ) drawFogCoord ( vindex ) ;
2003-05-07 21:13:13 +08:00
if ( extensions - > isVertexProgramSupported ( ) )
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_VERTEX ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
for ( DrawTexCoordList : : iterator texItr = drawTexCoordList . begin ( ) ;
texItr ! = drawTexCoordList . end ( ) ;
+ + texItr )
{
( * ( * texItr ) ) ( vindex ) ;
}
if ( drawTextCoord . valid ( ) ) ( * drawTextCoord ) ( vindex ) ;
2003-05-09 21:07:06 +08:00
if ( useVertexAttrib )
{
( * drawVertexAttribZero ) ( vindex ) ;
}
else
{
drawVertex ( vindex ) ;
}
2002-10-02 21:12:16 +08:00
}
glEnd ( ) ;
break ;
}
case ( PrimitiveSet : : DrawElementsUShortPrimitiveType ) :
{
if ( primLength = = 0 ) primLength = primitiveset - > getNumIndices ( ) ;
const DrawElementsUShort * drawElements = static_cast < const DrawElementsUShort * > ( primitiveset ) ;
glBegin ( mode ) ;
unsigned int primCount = 0 ;
for ( DrawElementsUShort : : const_iterator primItr = drawElements - > begin ( ) ;
primItr ! = drawElements - > end ( ) ;
+ + primCount , + + primItr )
{
if ( ( primCount % primLength ) = = 0 )
{
if ( _normalBinding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE ) drawFogCoord ( fogCoordIndex + + ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
}
unsigned int vindex = * primItr ;
if ( _normalBinding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorBinding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX ) drawSecondaryColor ( vindex ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX ) drawFogCoord ( vindex ) ;
2003-06-30 05:41:57 +08:00
if ( handleVertexAttributes )
2003-05-07 21:13:13 +08:00
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_VERTEX ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
for ( DrawTexCoordList : : iterator texItr = drawTexCoordList . begin ( ) ;
texItr ! = drawTexCoordList . end ( ) ;
+ + texItr )
{
( * ( * texItr ) ) ( vindex ) ;
}
if ( drawTextCoord . valid ( ) ) ( * drawTextCoord ) ( vindex ) ;
2003-05-09 21:07:06 +08:00
if ( useVertexAttrib )
{
( * drawVertexAttribZero ) ( vindex ) ;
}
else
{
drawVertex ( vindex ) ;
}
2002-10-02 21:12:16 +08:00
}
glEnd ( ) ;
break ;
}
case ( PrimitiveSet : : DrawElementsUIntPrimitiveType ) :
{
if ( primLength = = 0 ) primLength = primitiveset - > getNumIndices ( ) ;
const DrawElementsUInt * drawElements = static_cast < const DrawElementsUInt * > ( primitiveset ) ;
glBegin ( mode ) ;
unsigned int primCount = 0 ;
for ( DrawElementsUInt : : const_iterator primItr = drawElements - > begin ( ) ;
primItr ! = drawElements - > end ( ) ;
+ + primCount , + + primItr )
{
if ( ( primCount % primLength ) = = 0 )
{
if ( _normalBinding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorBinding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
if ( secondaryColorBinding = = BIND_PER_PRIMITIVE ) drawSecondaryColor ( secondaryColorIndex + + ) ;
if ( fogCoordBinding = = BIND_PER_PRIMITIVE ) drawFogCoord ( fogCoordIndex + + ) ;
2003-05-07 21:13:13 +08:00
if ( extensions - > isVertexProgramSupported ( ) )
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_PRIMITIVE ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
}
unsigned int vindex = * primItr ;
if ( _normalBinding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorBinding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX ) drawSecondaryColor ( vindex ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX ) drawFogCoord ( vindex ) ;
2003-05-07 21:13:13 +08:00
if ( extensions - > isVertexProgramSupported ( ) )
{
DrawVertexAttribList & list = drawVertexAttribMap [ BIND_PER_VERTEX ] ;
for ( unsigned int i = 0 ; i < list . size ( ) ; + + i )
{
( * ( list [ i ] ) ) ( vertexAttribIndex + + ) ;
}
}
2002-10-02 21:12:16 +08:00
for ( DrawTexCoordList : : iterator texItr = drawTexCoordList . begin ( ) ;
texItr ! = drawTexCoordList . end ( ) ;
+ + texItr )
{
( * ( * texItr ) ) ( vindex ) ;
}
if ( drawTextCoord . valid ( ) ) ( * drawTextCoord ) ( vindex ) ;
2003-05-09 21:07:06 +08:00
if ( useVertexAttrib )
{
( * drawVertexAttribZero ) ( vindex ) ;
}
else
{
drawVertex ( vindex ) ;
}
2002-10-02 21:12:16 +08:00
}
glEnd ( ) ;
break ;
}
2002-08-16 04:27:33 +08:00
default :
2002-10-02 21:12:16 +08:00
{
2002-08-16 04:27:33 +08:00
break ;
2002-10-02 21:12:16 +08:00
}
2002-08-16 04:27:33 +08:00
}
}
2002-06-22 00:45:45 +08:00
}
2002-06-21 03:54:08 +08:00
}
2002-11-06 18:24:33 +08:00
class AttrbuteFunctorArrayVisitor : public ArrayVisitor
{
public :
AttrbuteFunctorArrayVisitor ( Drawable : : AttributeFunctor & af ) :
_af ( af ) { }
virtual ~ AttrbuteFunctorArrayVisitor ( ) { }
virtual void apply ( ByteArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( ShortArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( IntArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( UByteArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( UShortArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( UIntArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( UByte4Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( FloatArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( Vec2Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( Vec3Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( Vec4Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
2002-11-22 17:46:25 +08:00
inline void applyArray ( Drawable : : AttributeType type , Array * array )
2002-11-06 18:24:33 +08:00
{
if ( array )
{
_type = type ;
array - > accept ( * this ) ;
}
}
Drawable : : AttributeFunctor & _af ;
Drawable : : AttributeType _type ;
} ;
2002-06-21 03:54:08 +08:00
2002-07-18 23:36:14 +08:00
void Geometry : : accept ( AttributeFunctor & af )
2002-06-21 03:54:08 +08:00
{
2002-11-06 18:24:33 +08:00
AttrbuteFunctorArrayVisitor afav ( af ) ;
2002-11-22 17:46:25 +08:00
afav . applyArray ( VERTICES , _vertexArray . get ( ) ) ;
afav . applyArray ( NORMALS , _normalArray . get ( ) ) ;
afav . applyArray ( COLORS , _colorArray . get ( ) ) ;
2002-11-06 18:24:33 +08:00
for ( unsigned unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
2002-06-28 04:29:32 +08:00
{
2002-11-22 17:46:25 +08:00
afav . applyArray ( ( AttributeType ) ( TEXTURE_COORDS_0 + unit ) , _texCoordList [ unit ] . first . get ( ) ) ;
2002-06-28 04:29:32 +08:00
}
2002-11-06 18:24:33 +08:00
}
class ConstAttrbuteFunctorArrayVisitor : public ConstArrayVisitor
{
public :
2002-06-28 04:29:32 +08:00
2002-11-06 18:24:33 +08:00
ConstAttrbuteFunctorArrayVisitor ( Drawable : : ConstAttributeFunctor & af ) :
_af ( af ) { }
virtual ~ ConstAttrbuteFunctorArrayVisitor ( ) { }
virtual void apply ( const ByteArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const ShortArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const IntArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const UByteArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const UShortArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const UIntArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const UByte4Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const FloatArray & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const Vec2Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const Vec3Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
virtual void apply ( const Vec4Array & array ) { if ( ! array . empty ( ) ) _af . apply ( _type , array . size ( ) , & ( array . front ( ) ) ) ; }
2002-11-22 17:46:25 +08:00
inline void applyArray ( Drawable : : AttributeType type , const Array * array )
2002-11-06 18:24:33 +08:00
{
if ( array )
{
_type = type ;
array - > accept ( * this ) ;
}
}
Drawable : : ConstAttributeFunctor & _af ;
Drawable : : AttributeType _type ;
} ;
void Geometry : : accept ( ConstAttributeFunctor & af ) const
{
ConstAttrbuteFunctorArrayVisitor afav ( af ) ;
2002-11-22 17:46:25 +08:00
afav . applyArray ( VERTICES , _vertexArray . get ( ) ) ;
afav . applyArray ( NORMALS , _normalArray . get ( ) ) ;
afav . applyArray ( COLORS , _colorArray . get ( ) ) ;
2002-11-06 18:24:33 +08:00
for ( unsigned unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
2002-06-28 04:29:32 +08:00
{
2002-11-22 17:46:25 +08:00
afav . applyArray ( ( AttributeType ) ( TEXTURE_COORDS_0 + unit ) , _texCoordList [ unit ] . first . get ( ) ) ;
2002-06-28 04:29:32 +08:00
}
2002-06-21 03:54:08 +08:00
}
2002-11-06 18:24:33 +08:00
void Geometry : : accept ( PrimitiveFunctor & functor ) const
2002-06-26 04:27:51 +08:00
{
2003-06-24 23:40:09 +08:00
if ( ! _vertexArray . valid ( ) | | _vertexArray - > getNumElements ( ) = = 0 ) return ;
2002-10-08 22:10:55 +08:00
if ( ! _vertexIndices . valid ( ) )
2002-06-26 04:27:51 +08:00
{
2003-06-24 23:40:09 +08:00
switch ( _vertexArray - > getType ( ) )
{
case ( Array : : Vec2ArrayType ) :
functor . setVertexArray ( _vertexArray - > getNumElements ( ) , static_cast < const Vec2 * > ( _vertexArray - > getDataPointer ( ) ) ) ;
break ;
case ( Array : : Vec3ArrayType ) :
functor . setVertexArray ( _vertexArray - > getNumElements ( ) , static_cast < const Vec3 * > ( _vertexArray - > getDataPointer ( ) ) ) ;
break ;
case ( Array : : Vec4ArrayType ) :
functor . setVertexArray ( _vertexArray - > getNumElements ( ) , static_cast < const Vec4 * > ( _vertexArray - > getDataPointer ( ) ) ) ;
break ;
default :
notify ( WARN ) < < " Warning: Geometry::accept(PrimtiveFunctor&) cannot handle Vertex Array type " < < _vertexArray - > getType ( ) < < std : : endl ;
return ;
}
2002-11-06 18:24:33 +08:00
for ( PrimitiveSetList : : const_iterator itr = _primitives . begin ( ) ;
2002-10-08 22:10:55 +08:00
itr ! = _primitives . end ( ) ;
+ + itr )
{
( * itr ) - > accept ( functor ) ;
}
2002-06-26 04:27:51 +08:00
}
2002-10-08 22:10:55 +08:00
else
{
2003-06-24 23:40:09 +08:00
const Vec2Array * vec2Array = 0 ;
const Vec3Array * vec3Array = 0 ;
const Vec4Array * vec4Array = 0 ;
Array : : Type type = _vertexArray - > getType ( ) ;
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
vec2Array = static_cast < const Vec2Array * > ( _vertexArray . get ( ) ) ;
break ;
case ( Array : : Vec3ArrayType ) :
vec3Array = static_cast < const Vec3Array * > ( _vertexArray . get ( ) ) ;
break ;
case ( Array : : Vec4ArrayType ) :
vec4Array = static_cast < const Vec4Array * > ( _vertexArray . get ( ) ) ;
break ;
default :
notify ( WARN ) < < " Warning: Geometry::accept(PrimtiveFunctor&) cannot handle Vertex Array type " < < _vertexArray - > getType ( ) < < std : : endl ;
return ;
}
2002-11-06 18:24:33 +08:00
for ( PrimitiveSetList : : const_iterator itr = _primitives . begin ( ) ;
2002-10-08 22:10:55 +08:00
itr ! = _primitives . end ( ) ;
+ + itr )
{
2002-11-06 18:24:33 +08:00
const PrimitiveSet * primitiveset = itr - > get ( ) ;
2002-10-08 22:10:55 +08:00
GLenum mode = primitiveset - > getMode ( ) ;
switch ( primitiveset - > getType ( ) )
{
case ( PrimitiveSet : : DrawArraysPrimitiveType ) :
{
const DrawArrays * drawArray = static_cast < const DrawArrays * > ( primitiveset ) ;
functor . begin ( mode ) ;
unsigned int indexEnd = drawArray - > getFirst ( ) + drawArray - > getCount ( ) ;
for ( unsigned int vindex = drawArray - > getFirst ( ) ;
vindex < indexEnd ;
+ + vindex )
{
2003-06-24 23:40:09 +08:00
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
functor . vertex ( ( * vec2Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec3ArrayType ) :
functor . vertex ( ( * vec3Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec4ArrayType ) :
functor . vertex ( ( * vec4Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
default :
break ;
}
2002-10-08 22:10:55 +08:00
}
functor . 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 )
{
functor . begin ( mode ) ;
for ( GLsizei primCount = 0 ; primCount < * primItr ; + + primCount )
{
2003-06-24 23:40:09 +08:00
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
functor . vertex ( ( * vec2Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec3ArrayType ) :
functor . vertex ( ( * vec3Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec4ArrayType ) :
functor . vertex ( ( * vec4Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
default :
break ;
}
2002-10-08 22:10:55 +08:00
+ + vindex ;
}
functor . end ( ) ;
}
break ;
}
case ( PrimitiveSet : : DrawElementsUBytePrimitiveType ) :
{
const DrawElementsUByte * drawElements = static_cast < const DrawElementsUByte * > ( primitiveset ) ;
functor . begin ( mode ) ;
unsigned int primCount = 0 ;
for ( DrawElementsUByte : : const_iterator primItr = drawElements - > begin ( ) ;
primItr ! = drawElements - > end ( ) ;
+ + primCount , + + primItr )
{
unsigned int vindex = * primItr ;
2003-06-24 23:40:09 +08:00
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
functor . vertex ( ( * vec2Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec3ArrayType ) :
functor . vertex ( ( * vec3Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec4ArrayType ) :
functor . vertex ( ( * vec4Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
default :
break ;
}
2002-10-08 22:10:55 +08:00
}
functor . end ( ) ;
break ;
}
case ( PrimitiveSet : : DrawElementsUShortPrimitiveType ) :
{
const DrawElementsUShort * drawElements = static_cast < const DrawElementsUShort * > ( primitiveset ) ;
functor . begin ( mode ) ;
for ( DrawElementsUShort : : const_iterator primItr = drawElements - > begin ( ) ;
primItr ! = drawElements - > end ( ) ;
+ + primItr )
{
unsigned int vindex = * primItr ;
2003-06-24 23:40:09 +08:00
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
functor . vertex ( ( * vec2Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec3ArrayType ) :
functor . vertex ( ( * vec3Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec4ArrayType ) :
functor . vertex ( ( * vec4Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
default :
break ;
}
2002-10-08 22:10:55 +08:00
}
functor . end ( ) ;
break ;
}
case ( PrimitiveSet : : DrawElementsUIntPrimitiveType ) :
{
const DrawElementsUInt * drawElements = static_cast < const DrawElementsUInt * > ( primitiveset ) ;
functor . begin ( mode ) ;
for ( DrawElementsUInt : : const_iterator primItr = drawElements - > begin ( ) ;
primItr ! = drawElements - > end ( ) ;
+ + primItr )
{
unsigned int vindex = * primItr ;
2003-06-24 23:40:09 +08:00
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
functor . vertex ( ( * vec2Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec3ArrayType ) :
functor . vertex ( ( * vec3Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
case ( Array : : Vec4ArrayType ) :
functor . vertex ( ( * vec4Array ) [ _vertexIndices - > index ( vindex ) ] ) ;
break ;
default :
break ;
}
2002-10-08 22:10:55 +08:00
}
functor . end ( ) ;
break ;
}
default :
{
break ;
}
}
}
2002-11-06 18:24:33 +08:00
}
return ;
2002-06-26 04:27:51 +08:00
}
2002-07-18 08:53:03 +08:00
bool Geometry : : verifyBindings ( ) const
{
switch ( _normalBinding )
{
case ( BIND_OFF ) :
if ( _normalArray . valid ( ) & & _normalArray - > getNumElements ( ) > 0 ) return false ;
break ;
case ( BIND_OVERALL ) :
if ( ! _normalArray . valid ( ) ) return false ;
if ( _normalArray - > getNumElements ( ) ! = 1 ) return false ;
break ;
2002-10-02 21:12:16 +08:00
case ( BIND_PER_PRIMITIVE_SET ) :
2002-07-18 08:53:03 +08:00
if ( ! _normalArray . valid ( ) ) return false ;
if ( _normalArray - > getNumElements ( ) ! = _primitives . size ( ) ) return false ;
break ;
2003-05-22 23:29:20 +08:00
case ( BIND_PER_PRIMITIVE ) :
if ( ! _normalArray . valid ( ) ) return false ;
break ;
2002-07-18 08:53:03 +08:00
case ( BIND_PER_VERTEX ) :
if ( _vertexArray . valid ( ) )
{
if ( ! _normalArray . valid ( ) ) return false ;
if ( _normalArray - > getNumElements ( ) ! = _vertexArray - > getNumElements ( ) ) return false ;
}
2002-10-02 21:12:16 +08:00
else if ( _normalArray . valid ( ) & & _normalArray - > getNumElements ( ) = = 0 ) return false ;
2002-07-18 08:53:03 +08:00
break ;
}
switch ( _colorBinding )
{
case ( BIND_OFF ) :
if ( _colorArray . valid ( ) & & _colorArray - > getNumElements ( ) > 0 ) return false ;
break ;
case ( BIND_OVERALL ) :
if ( ! _colorArray . valid ( ) ) return false ;
if ( _colorArray - > getNumElements ( ) ! = 1 ) return false ;
break ;
2002-10-02 21:12:16 +08:00
case ( BIND_PER_PRIMITIVE_SET ) :
2002-07-18 08:53:03 +08:00
if ( ! _colorArray . valid ( ) ) return false ;
if ( _colorArray - > getNumElements ( ) ! = _primitives . size ( ) ) return false ;
break ;
2003-05-22 23:29:20 +08:00
case ( BIND_PER_PRIMITIVE ) :
if ( ! _colorArray . valid ( ) ) return false ;
break ;
2002-07-18 08:53:03 +08:00
case ( BIND_PER_VERTEX ) :
if ( _vertexArray . valid ( ) )
{
if ( ! _colorArray . valid ( ) ) return false ;
if ( _colorArray - > getNumElements ( ) ! = _vertexArray - > getNumElements ( ) ) return false ;
}
2002-10-02 21:12:16 +08:00
else if ( _colorArray . valid ( ) & & _colorArray - > getNumElements ( ) = = 0 ) return false ;
2002-07-18 08:53:03 +08:00
break ;
}
for ( TexCoordArrayList : : const_iterator itr = _texCoordList . begin ( ) ;
itr ! = _texCoordList . end ( ) ;
+ + itr )
{
2002-10-02 21:12:16 +08:00
const Array * array = itr - > first . get ( ) ;
2002-07-18 08:53:03 +08:00
if ( _vertexArray . valid ( ) )
{
if ( array & & array - > getNumElements ( ) ! = _vertexArray - > getNumElements ( ) ) return false ;
}
2002-10-02 21:12:16 +08:00
else if ( array & & array - > getNumElements ( ) = = 0 ) return false ;
2002-07-18 08:53:03 +08:00
}
return true ;
}
void Geometry : : computeCorrectBindingsAndArraySizes ( )
{
if ( verifyBindings ( ) ) return ;
2003-06-24 23:40:09 +08:00
if ( ! _vertexArray . valid ( ) | | _vertexArray - > getNumElements ( ) = = 0 )
2002-07-18 08:53:03 +08:00
{
// no vertex array so switch everything off.
_vertexArray = 0 ;
_colorArray = 0 ;
_colorBinding = BIND_OFF ;
_normalArray = 0 ;
_normalBinding = BIND_OFF ;
_texCoordList . clear ( ) ;
notify ( INFO ) < < " Info: remove redundent attribute arrays from empty osg::Geometry " < < std : : endl ;
return ;
}
switch ( _normalBinding )
{
case ( BIND_OFF ) :
if ( _normalArray . valid ( ) ) _normalArray = 0 ;
break ;
case ( BIND_OVERALL ) :
if ( ! _normalArray . valid ( ) )
{
_normalBinding = BIND_OFF ;
}
else if ( _normalArray - > getNumElements ( ) = = 0 )
{
_normalArray = 0 ;
_normalBinding = BIND_OFF ;
}
else if ( _normalArray - > getNumElements ( ) > 1 )
{
// trim the array down to 1 element long.
_normalArray - > erase ( _normalArray - > begin ( ) + 1 , _normalArray - > end ( ) ) ;
}
break ;
2002-10-02 21:12:16 +08:00
case ( BIND_PER_PRIMITIVE_SET ) :
2002-07-18 08:53:03 +08:00
if ( ! _normalArray . valid ( ) )
{
_normalBinding = BIND_OFF ;
}
else if ( _normalArray - > getNumElements ( ) < _primitives . size ( ) )
{
_normalArray = 0 ;
_normalBinding = BIND_OFF ;
}
else if ( _normalArray - > getNumElements ( ) > _primitives . size ( ) )
{
// trim the array down to size of the number of primitives.
_normalArray - > erase ( _normalArray - > begin ( ) + _primitives . size ( ) , _normalArray - > end ( ) ) ;
}
break ;
2003-05-22 23:29:20 +08:00
case ( BIND_PER_PRIMITIVE ) :
break ;
2002-07-18 08:53:03 +08:00
case ( BIND_PER_VERTEX ) :
if ( ! _normalArray . valid ( ) )
{
_normalBinding = BIND_OFF ;
}
else if ( _normalArray - > getNumElements ( ) < _vertexArray - > getNumElements ( ) )
{
_normalArray = 0 ;
_normalBinding = BIND_OFF ;
}
else if ( _normalArray - > getNumElements ( ) > _vertexArray - > getNumElements ( ) )
{
// trim the array down to size of the number of primitives.
_normalArray - > erase ( _normalArray - > begin ( ) + _vertexArray - > getNumElements ( ) , _normalArray - > end ( ) ) ;
}
break ;
}
// TODO colours and tex coords.
}
2003-05-07 21:13:13 +08:00
2003-08-08 08:21:30 +08:00
class ExpandIndexedArray : public osg : : ConstArrayVisitor
{
public :
ExpandIndexedArray ( const osg : : IndexArray & indices , Array * targetArray ) :
_indices ( indices ) ,
_targetArray ( targetArray ) { }
template < class T , class I >
T * create ( const T & array , const I & indices )
{
T * newArray = 0 ;
// if source array type and target array type are equal
if ( _targetArray & & _targetArray - > getType ( ) = = array . getType ( ) )
{
// reuse exisiting target array
newArray = static_cast < T * > ( _targetArray ) ;
if ( newArray - > size ( ) ! = indices . size ( ) )
{
// make sure its the right size
newArray - > resize ( indices . size ( ) ) ;
}
}
else
{
// else create a new array.
newArray = new T ( indices . size ( ) ) ;
}
for ( unsigned int i = 0 ; i < indices . size ( ) ; + + i )
{
( * newArray ) [ i ] = array [ indices [ i ] ] ;
}
return newArray ;
}
template < class T >
T * create ( const T & array )
{
switch ( _indices . getType ( ) )
{
case ( osg : : Array : : ByteArrayType ) : return create ( array , static_cast < const osg : : ByteArray & > ( _indices ) ) ;
case ( osg : : Array : : ShortArrayType ) : return create ( array , static_cast < const osg : : ShortArray & > ( _indices ) ) ;
case ( osg : : Array : : IntArrayType ) : return create ( array , static_cast < const osg : : IntArray & > ( _indices ) ) ;
case ( osg : : Array : : UByteArrayType ) : return create ( array , static_cast < const osg : : UByteArray & > ( _indices ) ) ;
case ( osg : : Array : : UShortArrayType ) : return create ( array , static_cast < const osg : : UShortArray & > ( _indices ) ) ;
case ( osg : : Array : : UIntArrayType ) : return create ( array , static_cast < const osg : : UIntArray & > ( _indices ) ) ;
default : return 0 ;
}
}
virtual void apply ( const osg : : ByteArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : ShortArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : IntArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : UByteArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : UShortArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : UIntArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : UByte4Array & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : FloatArray & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : Vec2Array & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : Vec3Array & array ) { _targetArray = create ( array ) ; }
virtual void apply ( const osg : : Vec4Array & array ) { _targetArray = create ( array ) ; }
const osg : : IndexArray & _indices ;
osg : : Array * _targetArray ;
} ;
bool Geometry : : suitableForOptimization ( ) const
{
bool hasIndices = false ;
if ( getVertexIndices ( ) ) hasIndices = true ;
if ( getNormalIndices ( ) ) hasIndices = true ;
if ( getColorIndices ( ) ) hasIndices = true ;
if ( getSecondaryColorIndices ( ) ) hasIndices = true ;
if ( getFogCoordIndices ( ) ) hasIndices = true ;
for ( unsigned int ti = 0 ; ti < getNumTexCoordArrays ( ) ; + + ti )
{
if ( getTexCoordIndices ( ti ) ) hasIndices = true ;
}
for ( unsigned int vi = 0 ; vi < getNumVertexAttribArrays ( ) ; + + vi )
{
if ( getVertexAttribIndices ( vi ) ) hasIndices = true ;
}
return hasIndices ;
}
void Geometry : : copyToAndOptimize ( Geometry & target )
{
// copy over primitive sets.
target . getPrimitiveSetList ( ) = getPrimitiveSetList ( ) ;
// copy over attribute arrays.
if ( getVertexIndices ( ) )
{
ExpandIndexedArray eia ( * ( getVertexIndices ( ) ) , target . getVertexArray ( ) ) ;
getVertexArray ( ) - > accept ( eia ) ;
target . setVertexArray ( eia . _targetArray ) ;
target . setVertexIndices ( 0 ) ;
}
else if ( getVertexArray ( ) )
{
target . setVertexArray ( getVertexArray ( ) ) ;
}
target . setNormalBinding ( getNormalBinding ( ) ) ;
if ( getNormalIndices ( ) )
{
ExpandIndexedArray eia ( * ( getNormalIndices ( ) ) , target . getNormalArray ( ) ) ;
getNormalArray ( ) - > accept ( eia ) ;
target . setNormalArray ( dynamic_cast < osg : : Vec3Array * > ( eia . _targetArray ) ) ;
target . setNormalIndices ( 0 ) ;
}
else if ( getNormalArray ( ) )
{
target . setNormalArray ( getNormalArray ( ) ) ;
}
target . setColorBinding ( getColorBinding ( ) ) ;
if ( getColorIndices ( ) )
{
ExpandIndexedArray eia ( * ( getColorIndices ( ) ) , target . getColorArray ( ) ) ;
getColorArray ( ) - > accept ( eia ) ;
target . setColorArray ( eia . _targetArray ) ;
target . setColorIndices ( 0 ) ;
}
else if ( getColorArray ( ) )
{
target . setColorArray ( getColorArray ( ) ) ;
}
target . setSecondaryColorBinding ( getSecondaryColorBinding ( ) ) ;
if ( getSecondaryColorIndices ( ) )
{
ExpandIndexedArray eia ( * ( getSecondaryColorIndices ( ) ) , target . getSecondaryColorArray ( ) ) ;
getSecondaryColorArray ( ) - > accept ( eia ) ;
target . setSecondaryColorArray ( eia . _targetArray ) ;
target . setSecondaryColorIndices ( 0 ) ;
}
else if ( getSecondaryColorArray ( ) )
{
target . setSecondaryColorArray ( getSecondaryColorArray ( ) ) ;
}
target . setFogCoordBinding ( getFogCoordBinding ( ) ) ;
if ( getFogCoordIndices ( ) )
{
ExpandIndexedArray eia ( * ( getFogCoordIndices ( ) ) , target . getFogCoordArray ( ) ) ;
getFogCoordArray ( ) - > accept ( eia ) ;
target . setFogCoordArray ( eia . _targetArray ) ;
target . setFogCoordIndices ( 0 ) ;
}
else if ( getFogCoordArray ( ) )
{
target . setFogCoordArray ( getFogCoordArray ( ) ) ;
}
for ( unsigned int ti = 0 ; ti < getNumTexCoordArrays ( ) ; + + ti )
{
if ( getTexCoordIndices ( ti ) )
{
ExpandIndexedArray eia ( * ( getTexCoordIndices ( ti ) ) , target . getTexCoordArray ( ti ) ) ;
getTexCoordArray ( ti ) - > accept ( eia ) ;
target . setTexCoordArray ( ti , eia . _targetArray ) ;
target . setTexCoordIndices ( ti , 0 ) ;
}
else if ( getTexCoordArray ( ti ) )
{
target . setTexCoordArray ( ti , getTexCoordArray ( ti ) ) ;
}
}
for ( unsigned int vi = 0 ; vi < getNumVertexAttribArrays ( ) ; + + vi )
{
AttributeBinding vab ;
getVertexAttribBinding ( vi , vab ) ;
if ( getVertexAttribIndices ( vi ) )
{
GLboolean normalize ;
ExpandIndexedArray eia ( * ( getVertexAttribIndices ( vi ) ) , target . getVertexAttribArray ( vi ) ) ;
getVertexAttribArray ( vi ) - > accept ( eia ) ;
getVertexAttribNormalize ( vi , normalize ) ;
target . setVertexAttribArray ( vi , normalize , eia . _targetArray , vab ) ;
target . setVertexAttribIndices ( vi , 0 ) ;
}
else if ( getVertexAttribArray ( vi ) )
{
GLboolean normalize ;
getVertexAttribNormalize ( vi , normalize ) ;
target . setVertexAttribArray ( vi , normalize , getVertexAttribArray ( vi ) , vab ) ;
}
}
}
void Geometry : : computeInternalOptimizedGeometry ( )
{
if ( suitableForOptimization ( ) )
{
if ( ! _internalOptimizedGeometry ) _internalOptimizedGeometry = new Geometry ;
copyToAndOptimize ( * _internalOptimizedGeometry ) ;
}
}
2003-06-25 05:57:13 +08:00
Geometry * osg : : createTexturedQuadGeometry ( const osg : : Vec3 & corner , const osg : : Vec3 & widthVec , const osg : : Vec3 & heightVec )
{
Geometry * geom = new Geometry ;
Vec3Array * coords = new Vec3Array ( 4 ) ;
( * coords ) [ 0 ] = corner + heightVec ;
( * coords ) [ 1 ] = corner ;
( * coords ) [ 2 ] = corner + widthVec ;
( * coords ) [ 3 ] = corner + widthVec + heightVec ;
geom - > setVertexArray ( coords ) ;
Vec2Array * tcoords = new Vec2Array ( 4 ) ;
( * tcoords ) [ 0 ] . set ( 0.0f , 1.0f ) ;
( * tcoords ) [ 1 ] . set ( 0.0f , 0.0f ) ;
( * tcoords ) [ 2 ] . set ( 1.0f , 0.0f ) ;
( * tcoords ) [ 3 ] . set ( 1.0f , 1.0f ) ;
geom - > setTexCoordArray ( 0 , tcoords ) ;
osg : : Vec4Array * colours = new osg : : Vec4Array ( 1 ) ;
( * colours ) [ 0 ] . set ( 1.0f , 1.0f , 1.0 , 1.0f ) ;
geom - > setColorArray ( colours ) ;
geom - > setColorBinding ( Geometry : : BIND_OVERALL ) ;
osg : : Vec3Array * normals = new osg : : Vec3Array ( 1 ) ;
( * normals ) [ 0 ] = widthVec ^ heightVec ;
( * normals ) [ 0 ] . normalize ( ) ;
geom - > setNormalArray ( normals ) ;
geom - > setNormalBinding ( Geometry : : BIND_OVERALL ) ;
geom - > addPrimitiveSet ( new DrawArrays ( PrimitiveSet : : QUADS , 0 , 4 ) ) ;
return geom ;
}
2003-09-01 06:08:22 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
// experimental templated rendering code, please ignore...
// will move to osg::Geometry once complete.
// Robert Osfield, August 2003.
#if 0
struct DrawAttributeArrays
{
virtual bool valid ( ) const = 0 ;
virtual void set ( osg : : Geometry * geometry ) = 0 ;
virtual unsigned int draw ( unsigned int index , unsigned int count ) const = 0 ;
} ;
struct V3
{
V3 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getVertexArray ( ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec3ArrayType )
{
osg : : Vec3Array * vec3array = static_cast < osg : : Vec3Array * > ( array ) ;
if ( ! vec3array - > empty ( ) ) _array = & ( vec3array - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glVertex3fv ( _array [ index ] . ptr ( ) ) ;
}
osg : : Vec3 * _array ;
} ;
struct V3USI
{
V3USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getVertexArray ( ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec3ArrayType )
{
osg : : Vec3Array * vec3array = static_cast < osg : : Vec3Array * > ( array ) ;
if ( ! vec3array - > empty ( ) ) _array = & ( vec3array - > front ( ) ) ;
}
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getVertexIndices ( ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushort3array = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushort3array - > empty ( ) ) _indices = & ( ushort3array - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glVertex3fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
}
osg : : Vec3 * _array ;
unsigned short * _indices ;
} ;
//////////////////////////////
struct N3
{
N3 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getVertexArray ( ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec3ArrayType )
{
osg : : Vec3Array * vec3array = static_cast < osg : : Vec3Array * > ( array ) ;
if ( ! vec3array - > empty ( ) ) _array = & ( vec3array - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glNormal3fv ( _array [ index ] . ptr ( ) ) ;
}
osg : : Vec3 * _array ;
} ;
struct N3USI
{
N3USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getVertexArray ( ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec3ArrayType )
{
osg : : Vec3Array * vec3array = static_cast < osg : : Vec3Array * > ( array ) ;
if ( ! vec3array - > empty ( ) ) _array = & ( vec3array - > front ( ) ) ;
}
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getVertexIndices ( ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushortarray = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushortarray - > empty ( ) ) _indices = & ( ushortarray - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glNormal3fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
}
osg : : Vec3 * _array ;
unsigned short * _indices ;
} ;
//////////////////////////////
struct C4
{
C4 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getColorArray ( ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec4ArrayType )
{
osg : : Vec4Array * vec4array = static_cast < osg : : Vec4Array * > ( array ) ;
if ( ! vec4array - > empty ( ) ) _array = & ( vec4array - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glVertex3fv ( _array [ index ] . ptr ( ) ) ;
}
osg : : Vec4 * _array ;
} ;
struct C4USI
{
C4USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getColorArray ( ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec4ArrayType )
{
osg : : Vec4Array * vec4array = static_cast < osg : : Vec4Array * > ( array ) ;
if ( ! vec4array - > empty ( ) ) _array = & ( vec4array - > front ( ) ) ;
}
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getColorIndices ( ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushortarray = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushortarray - > empty ( ) ) _indices = & ( ushortarray - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glColor4fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
}
osg : : Vec4 * _array ;
unsigned short * _indices ;
} ;
//////////////////////////////
struct T2
{
T2 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getTexCoordArray ( 0 ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec2ArrayType )
{
osg : : Vec2Array * vec2array = static_cast < osg : : Vec2Array * > ( array ) ;
if ( ! vec2array - > empty ( ) ) _array = & ( vec2array - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glTexCoord2fv ( _array [ index ] . ptr ( ) ) ;
}
osg : : Vec2 * _array ;
} ;
struct T2USI
{
T2USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
{
_array = 0 ;
osg : : Array * array = geometry - > getTexCoordArray ( 0 ) ;
if ( array & & array - > getType ( ) = = osg : : Array : : Vec2ArrayType )
{
osg : : Vec2Array * vec2array = static_cast < osg : : Vec2Array * > ( array ) ;
if ( ! vec2array - > empty ( ) ) _array = & ( vec2array - > front ( ) ) ;
}
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getTexCoordIndices ( 0 ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushortarray = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushortarray - > empty ( ) ) _indices = & ( ushortarray - > front ( ) ) ;
}
}
inline void draw ( unsigned int index ) const
{
glTexCoord2fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
}
osg : : Vec2 * _array ;
unsigned short * _indices ;
} ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template < class T1 >
struct DrawAttributeArrays_T : public DrawAttributeArrays
{
DrawAttributeArrays_T ( osg : : Geometry * geometry )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
_t1 . draw ( index ) ;
}
return index ;
}
T1 _t1 ;
} ;
template < class T1 , class T2 >
struct DrawAttributeArrays_TT : public DrawAttributeArrays
{
DrawAttributeArrays_TT ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
_t1 . draw ( index ) ;
_t2 . draw ( index ) ;
}
return index ;
}
T1 _t1 ;
T1 _t2 ;
} ;
template < class T1 , class T2 , class T3 >
struct DrawAttributeArrays_TTT : public DrawAttributeArrays
{
DrawAttributeArrays_TTT ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_t3 . set ( geometry ) ;
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
_t1 . draw ( index ) ;
_t2 . draw ( index ) ;
_t3 . draw ( index ) ;
}
return index ;
}
T1 _t1 ;
T2 _t2 ;
T3 _t3 ;
} ;
template < class T1 , class T2 , class T3 , class T4 >
struct DrawAttributeArrays_TTTT : public DrawAttributeArrays
{
DrawAttributeArrays_TTTT ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) & & _t4 . valid ( ) ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_t3 . set ( geometry ) ;
_t4 . set ( geometry ) ;
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
_t1 . draw ( index ) ;
_t2 . draw ( index ) ;
_t3 . draw ( index ) ;
_t4 . draw ( index ) ;
}
return index ;
}
T1 _t1 ;
T2 _t2 ;
T3 _t3 ;
T4 _t4 ;
} ;
template < class T1 , class T2 >
struct DrawAttributeArrays_TT_USI : public DrawAttributeArrays
{
DrawAttributeArrays_TT_USI ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _indices ! = 0 ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getVertexIndices ( ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushort3array = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushort3array - > empty ( ) ) _indices = & ( ushort3array - > front ( ) ) ;
}
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
unsigned int ivalue = _indices [ index ] ;
_t1 . draw ( ivalue ) ;
_t2 . draw ( ivalue ) ;
}
return index ;
}
T1 _t1 ;
T2 _t2 ;
} ;
template < class T1 , class T2 , class T3 >
struct DrawAttributeArrays_TTT_USI : public DrawAttributeArrays
{
DrawAttributeArrays_TTT_USI ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) & & _indices ! = 0 ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_t3 . set ( geometry ) ;
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getVertexIndices ( ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushort3array = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushort3array - > empty ( ) ) _indices = & ( ushort3array - > front ( ) ) ;
}
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
unsigned int ivalue = _indices [ index ] ;
_t1 . draw ( ivalue ) ;
_t2 . draw ( ivalue ) ;
_t3 . draw ( ivalue ) ;
}
return index ;
}
T1 _t1 ;
T2 _t2 ;
T3 _t3 ;
} ;
template < class T1 , class T2 , class T3 , class T4 >
struct DrawAttributeArrays_TTTT_USI : public DrawAttributeArrays
{
DrawAttributeArrays_TTTT_USI ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) & & _t4 . valid ( ) & & _indices ! = 0 ; }
virtual void set ( osg : : Geometry * geometry )
{
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_t3 . set ( geometry ) ;
_t4 . set ( geometry ) ;
_indices = 0 ;
osg : : IndexArray * indices = geometry - > getVertexIndices ( ) ;
if ( indices & & indices - > getType ( ) = = osg : : Array : : UShortArrayType )
{
osg : : UShortArray * ushort3array = static_cast < osg : : UShortArray * > ( array ) ;
if ( ! ushort3array - > empty ( ) ) _indices = & ( ushort3array - > front ( ) ) ;
}
}
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
{
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
unsigned int ivalue = _indices [ index ] ;
_t1 . draw ( ivalue ) ;
_t2 . draw ( ivalue ) ;
_t3 . draw ( ivalue ) ;
_t4 . draw ( ivalue ) ;
}
return index ;
}
T1 _t1 ;
T2 _t2 ;
T3 _t3 ;
T4 _t4 ;
} ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// One attribute x 2
typedef DrawAttributeArrays_T < V3 > DrawAttributeArrays_V3 ;
typedef DrawAttributeArrays_T < V3USI > DrawAttributeArrays_V3i ;
// Two attributes x 15
typedef DrawAttributeArrays_TT < N3 , V3 > DrawAttributeArrays_N3V3 ;
typedef DrawAttributeArrays_TT < N3USI , V3 > DrawAttributeArrays_N3iV3 ;
typedef DrawAttributeArrays_TT < N3 , V3USI > DrawAttributeArrays_N3V3i ;
typedef DrawAttributeArrays_TT < N3USI , V3USI > DrawAttributeArrays_N3iV3i ;
typedef DrawAttributeArrays_TT_USI < N3 , V3 > DrawAttributeArrays_N3V3_i ;
typedef DrawAttributeArrays_TT < C4 , V3 > DrawAttributeArrays_C4V3 ;
typedef DrawAttributeArrays_TT < C4USI , V3 > DrawAttributeArrays_C4iV3 ;
typedef DrawAttributeArrays_TT < C4 , V3USI > DrawAttributeArrays_C4V3i ;
typedef DrawAttributeArrays_TT < C4USI , V3USI > DrawAttributeArrays_C4iV3i ;
typedef DrawAttributeArrays_TT_USI < C4 , V3 > DrawAttributeArrays_C4V3_i ;
typedef DrawAttributeArrays_TT < T2 , V3 > DrawAttributeArrays_T2V3 ;
typedef DrawAttributeArrays_TT < T2USI , V3 > DrawAttributeArrays_T2iV3 ;
typedef DrawAttributeArrays_TT < T2 , V3USI > DrawAttributeArrays_T2V3i ;
typedef DrawAttributeArrays_TT < T2USI , V3USI > DrawAttributeArrays_T2iV3i ;
typedef DrawAttributeArrays_TT_USI < T2 , V3 > DrawAttributeArrays_T2V3_i ;
// Three attributes x 27
typedef DrawAttributeArrays_TTT < C4 , N3 , V3 > DrawAttributeArrays_C4N3V3 ;
typedef DrawAttributeArrays_TTT < C4USI , N3 , V3 > DrawAttributeArrays_C4iN3V3 ;
typedef DrawAttributeArrays_TTT < C4 , N3USI , V3 > DrawAttributeArrays_C4N3iV3 ;
typedef DrawAttributeArrays_TTT < C4USI , N3USI , V3 > DrawAttributeArrays_C4iN3iV3 ;
typedef DrawAttributeArrays_TTT < C4 , N3 , V3USI > DrawAttributeArrays_C4N3V3i ;
typedef DrawAttributeArrays_TTT < C4USI , N3 , V3USI > DrawAttributeArrays_C4iN3V3i ;
typedef DrawAttributeArrays_TTT < C4 , N3USI , V3USI > DrawAttributeArrays_C4N3iV3i ;
typedef DrawAttributeArrays_TTT < C4USI , N3USI , V3USI > DrawAttributeArrays_C4iN3iV3i ;
typedef DrawAttributeArrays_TTT_USI < C4 , N3 , V3 > DrawAttributeArrays_C4N3V3_i ;
typedef DrawAttributeArrays_TTT < T2 , N3 , V3 > DrawAttributeArrays_T2N3V3 ;
typedef DrawAttributeArrays_TTT < T2USI , N3 , V3 > DrawAttributeArrays_T2iN3V3 ;
typedef DrawAttributeArrays_TTT < T2 , N3USI , V3 > DrawAttributeArrays_T2iN3iV3 ;
typedef DrawAttributeArrays_TTT < T2USI , N3USI , V3 > DrawAttributeArrays_T2N3iV3 ;
typedef DrawAttributeArrays_TTT < T2 , N3 , V3USI > DrawAttributeArrays_T2N3V3i ;
typedef DrawAttributeArrays_TTT < T2USI , N3 , V3USI > DrawAttributeArrays_T2iN3V3i ;
typedef DrawAttributeArrays_TTT < T2 , N3USI , V3USI > DrawAttributeArrays_T2iN3iV3i ;
typedef DrawAttributeArrays_TTT < T2USI , N3USI , V3USI > DrawAttributeArrays_T2N3iV3i ;
typedef DrawAttributeArrays_TTT_USI < T2 , N3 , V3 > DrawAttributeArrays_T2N3V3_i ;
typedef DrawAttributeArrays_TTT < T2 , C4 , V3 > DrawAttributeArrays_T2C4V3 ;
typedef DrawAttributeArrays_TTT < T2USI , C4 , V3 > DrawAttributeArrays_T2iC4V3 ;
typedef DrawAttributeArrays_TTT < T2 , C4USI , V3 > DrawAttributeArrays_T2C4iV3 ;
typedef DrawAttributeArrays_TTT < T2USI , C4USI , V3 > DrawAttributeArrays_T2iC4iV3 ;
typedef DrawAttributeArrays_TTT < T2 , C4 , V3USI > DrawAttributeArrays_T2C4V3i ;
typedef DrawAttributeArrays_TTT < T2USI , C4 , V3USI > DrawAttributeArrays_T2iC4V3i ;
typedef DrawAttributeArrays_TTT < T2 , C4USI , V3USI > DrawAttributeArrays_T2C4iV3i ;
typedef DrawAttributeArrays_TTT < T2USI , C4USI , V3USI > DrawAttributeArrays_T2iC4iV3i ;
typedef DrawAttributeArrays_TTT_USI < T2 , C4 , V3 > DrawAttributeArrays_T2C4V3_t ;
// Four attributes x 17
typedef DrawAttributeArrays_TTTT < T2 , C4 , N3 , V3 > DrawAttributeArrays_T2C4N3V3 ;
typedef DrawAttributeArrays_TTTT < T2USI , C4 , N3 , V3 > DrawAttributeArrays_T2iC4N3V3 ;
typedef DrawAttributeArrays_TTTT < T2 , C4USI , N3 , V3 > DrawAttributeArrays_T2C4iN3V3 ;
typedef DrawAttributeArrays_TTTT < T2USI , C4USI , N3 , V3 > DrawAttributeArrays_T2iC4iN3V3 ;
typedef DrawAttributeArrays_TTTT < T2 , C4 , N3USI , V3 > DrawAttributeArrays_T2C4N3iV3 ;
typedef DrawAttributeArrays_TTTT < T2USI , C4 , N3USI , V3 > DrawAttributeArrays_T2iC4N3iV3 ;
typedef DrawAttributeArrays_TTTT < T2 , C4USI , N3USI , V3 > DrawAttributeArrays_T2C4iN3iV3 ;
typedef DrawAttributeArrays_TTTT < T2USI , C4USI , N3USI , V3 > DrawAttributeArrays_T2iC4iN3iV3 ;
typedef DrawAttributeArrays_TTTT < T2 , C4 , N3 , V3USI > DrawAttributeArrays_T2C4N3V3i ;
typedef DrawAttributeArrays_TTTT < T2USI , C4 , N3 , V3USI > DrawAttributeArrays_T2iC4N3V3i ;
typedef DrawAttributeArrays_TTTT < T2 , C4USI , N3 , V3USI > DrawAttributeArrays_T2C4iN3V3i ;
typedef DrawAttributeArrays_TTTT < T2USI , C4USI , N3 , V3USI > DrawAttributeArrays_T2iC4iN3V3i ;
typedef DrawAttributeArrays_TTTT < T2 , C4 , N3USI , V3USI > DrawAttributeArrays_T2C4N3iV3i ;
typedef DrawAttributeArrays_TTTT < T2USI , C4 , N3USI , V3USI > DrawAttributeArrays_T2iC4N3iV3i ;
typedef DrawAttributeArrays_TTTT < T2 , C4USI , N3USI , V3USI > DrawAttributeArrays_T2C4iN3iV3i ;
typedef DrawAttributeArrays_TTTT < T2USI , C4USI , N3USI , V3USI > DrawAttributeArrays_T2iC4iN3iV3i ;
typedef DrawAttributeArrays_TTTT_USI < T2 , C4 , N3 , V3 > DrawAttributeArrays_T2C4N3V3_i ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
# endif