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-09-10 06:18:35 +08:00
const Geometry : : ArrayData Geometry : : s_InvalidArrayData ;
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-10-22 21:39:16 +08:00
DrawVertexAttrib ( const Drawable : : Extensions * extensions , unsigned int vertAttribIndex , GLboolean normalized , const Array * attribcoords , const IndexArray * indices ) :
_vertAttribIndex ( vertAttribIndex ) ,
2003-05-07 21:13:13 +08:00
_normalized ( normalized ) ,
_extensions ( extensions ) ,
_attribcoords ( attribcoords ) ,
2003-10-22 21:39:16 +08:00
_indices ( indices ) ,
_index ( 0 ) { ; }
inline void applyAndIncrement ( ) { operator ( ) ( _index + + ) ; }
2003-05-09 21:07:06 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib1s ( _vertAttribIndex , s ) ;
2003-05-09 21:07:06 +08:00
}
virtual void apply ( const GLfloat & f )
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib1f ( _vertAttribIndex , f ) ;
2003-05-09 21:07:06 +08:00
}
virtual void apply ( const UByte4 & v )
{
if ( _normalized )
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib4Nubv ( _vertAttribIndex , v . ptr ( ) ) ;
2003-05-09 21:07:06 +08:00
}
else
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib4ubv ( _vertAttribIndex , v . ptr ( ) ) ;
2003-05-09 21:07:06 +08:00
}
}
virtual void apply ( const Vec2 & v )
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib2fv ( _vertAttribIndex , v . ptr ( ) ) ;
2003-05-09 21:07:06 +08:00
}
virtual void apply ( const Vec3 & v )
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib3fv ( _vertAttribIndex , v . ptr ( ) ) ;
2003-05-09 21:07:06 +08:00
}
virtual void apply ( const Vec4 & v )
{
2003-10-22 21:39:16 +08:00
_extensions - > glVertexAttrib4fv ( _vertAttribIndex , v . ptr ( ) ) ;
2003-05-09 21:07:06 +08:00
}
2003-05-07 21:13:13 +08:00
2003-10-22 21:39:16 +08:00
unsigned int _vertAttribIndex ;
2003-05-22 23:29:20 +08:00
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-10-22 21:39:16 +08:00
unsigned int _index ;
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
} ;
2003-12-04 05:45:32 +08:00
Geometry : : ArrayData : : ArrayData ( const ArrayData & data , const CopyOp & copyop ) :
array ( data . array . valid ( ) ? dynamic_cast < osg : : Array * > ( data . array - > clone ( copyop ) ) : 0 ) ,
indices ( data . indices . valid ( ) ? dynamic_cast < osg : : IndexArray * > ( data . indices - > clone ( copyop ) ) : 0 ) ,
binding ( data . binding ) ,
normalize ( data . normalize ) ,
offset ( data . offset )
{
}
Geometry : : Vec3ArrayData : : Vec3ArrayData ( const Vec3ArrayData & data , const CopyOp & copyop ) :
array ( data . array . valid ( ) ? dynamic_cast < osg : : Vec3Array * > ( data . array - > clone ( copyop ) ) : 0 ) ,
indices ( data . indices . valid ( ) ? dynamic_cast < osg : : IndexArray * > ( data . indices - > clone ( copyop ) ) : 0 ) ,
binding ( data . binding ) ,
normalize ( data . normalize ) ,
offset ( data . offset )
{
}
2002-10-02 21:12:16 +08:00
2002-06-21 03:54:08 +08:00
Geometry : : Geometry ( )
{
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-12-04 05:45:32 +08:00
_vertexData ( geometry . _vertexData , copyop ) ,
_normalData ( geometry . _normalData , copyop ) ,
_colorData ( geometry . _colorData , copyop ) ,
_secondaryColorData ( geometry . _secondaryColorData , copyop ) ,
_fogCoordData ( geometry . _fogCoordData , copyop ) ,
2003-08-08 08:21:30 +08:00
_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 ) ;
}
2003-09-10 06:18:35 +08:00
for ( ArrayList : : const_iterator titr = geometry . _texCoordList . begin ( ) ;
2002-07-26 05:50:08 +08:00
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
2003-09-10 06:18:35 +08:00
for ( ArrayList : : const_iterator vitr = geometry . _vertexAttribList . begin ( ) ;
2003-05-07 21:13:13 +08:00
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 :-)
}
2003-10-01 17:18:24 +08:00
void Geometry : : setTexCoordData ( unsigned int unit , const ArrayData & arrayData )
{
if ( _texCoordList . size ( ) < = unit )
_texCoordList . resize ( unit + 1 ) ;
_texCoordList [ unit ] = arrayData ;
}
2003-09-10 06:18:35 +08:00
Geometry : : ArrayData & Geometry : : getTexCoordData ( unsigned int unit )
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
2003-09-10 06:18:35 +08:00
return _texCoordList [ unit ] ;
}
2002-06-26 04:27:51 +08:00
2003-09-10 06:18:35 +08:00
const Geometry : : ArrayData & Geometry : : getTexCoordData ( unsigned int unit ) const
{
if ( _texCoordList . size ( ) < = unit )
return s_InvalidArrayData ;
return _texCoordList [ unit ] ;
}
void Geometry : : setTexCoordArray ( unsigned int unit , Array * array )
{
2003-09-24 23:54:22 +08:00
getTexCoordData ( unit ) . binding = BIND_PER_VERTEX ;
2003-09-10 06:18:35 +08:00
getTexCoordData ( unit ) . array = array ;
computeFastPathsUsed ( ) ;
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
{
2003-09-10 06:18:35 +08:00
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . array . 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
{
2003-09-10 06:18:35 +08:00
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . array . 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
{
2003-09-10 06:18:35 +08:00
getTexCoordData ( unit ) . indices = array ;
2002-10-02 21:12:16 +08:00
2003-09-10 06:18:35 +08:00
computeFastPathsUsed ( ) ;
2002-10-02 21:12:16 +08:00
dirtyDisplayList ( ) ;
}
IndexArray * Geometry : : getTexCoordIndices ( unsigned int unit )
{
2003-09-10 06:18:35 +08:00
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . indices . get ( ) ;
2002-10-02 21:12:16 +08:00
else return 0 ;
}
const IndexArray * Geometry : : getTexCoordIndices ( unsigned int unit ) const
{
2003-09-10 06:18:35 +08:00
if ( unit < _texCoordList . size ( ) ) return _texCoordList [ unit ] . indices . get ( ) ;
2002-10-02 21:12:16 +08:00
else return 0 ;
}
2003-05-09 21:07:06 +08:00
2003-09-10 06:18:35 +08:00
void Geometry : : setVertexAttribData ( unsigned int index , const Geometry : : ArrayData & attrData )
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
if ( _vertexAttribList . size ( ) < = index )
_vertexAttribList . resize ( index + 1 ) ;
2003-05-09 21:07:06 +08:00
2003-09-10 06:18:35 +08:00
_vertexAttribList [ index ] = attrData ;
2003-05-09 21:07:06 +08:00
}
2003-09-10 06:18:35 +08:00
Geometry : : ArrayData & Geometry : : getVertexAttribData ( unsigned int index )
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
if ( _vertexAttribList . size ( ) < = index )
_vertexAttribList . resize ( index + 1 ) ;
return _vertexAttribList [ index ] ;
2003-05-09 21:07:06 +08:00
}
2003-09-10 06:18:35 +08:00
const Geometry : : ArrayData & Geometry : : getVertexAttribData ( unsigned int index ) const
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
if ( _vertexAttribList . size ( ) < = _vertexAttribList . size ( ) )
return s_InvalidArrayData ;
return _vertexAttribList [ index ] ;
2003-05-09 21:07:06 +08:00
}
2003-09-10 06:18:35 +08:00
void Geometry : : setVertexAttribArray ( unsigned int index , Array * array )
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
getVertexAttribData ( index ) . array = array ;
2003-05-09 21:07:06 +08:00
2003-09-10 06:18:35 +08:00
computeFastPathsUsed ( ) ;
2003-05-09 21:07:06 +08:00
dirtyDisplayList ( ) ;
}
2003-09-10 06:18:35 +08:00
Array * Geometry : : getVertexAttribArray ( unsigned int index )
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . array . get ( ) ;
2003-05-09 21:07:06 +08:00
else return 0 ;
}
2003-09-10 06:18:35 +08:00
const Array * Geometry : : getVertexAttribArray ( unsigned int index ) const
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . array . get ( ) ;
2003-05-09 21:07:06 +08:00
else return 0 ;
}
2003-09-10 06:18:35 +08:00
void Geometry : : setVertexAttribIndices ( unsigned int index , IndexArray * array )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
getVertexAttribData ( index ) . indices = array ;
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 ( ) ;
}
2003-09-10 06:18:35 +08:00
IndexArray * Geometry : : getVertexAttribIndices ( unsigned int index )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . indices . get ( ) ;
2003-05-07 21:13:13 +08:00
else return 0 ;
}
2003-09-10 06:18:35 +08:00
const IndexArray * Geometry : : getVertexAttribIndices ( unsigned int index ) const
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . indices . get ( ) ;
2003-05-07 21:13:13 +08:00
else return 0 ;
}
2003-09-10 06:18:35 +08:00
void Geometry : : setVertexAttribBinding ( unsigned int index , AttributeBinding ab )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
getVertexAttribData ( index ) . binding = ab ;
2003-05-07 21:13:13 +08:00
2003-09-10 06:18:35 +08:00
computeFastPathsUsed ( ) ;
dirtyDisplayList ( ) ;
2003-05-07 21:13:13 +08:00
}
2003-09-10 06:18:35 +08:00
Geometry : : AttributeBinding Geometry : : getVertexAttribBinding ( unsigned int index ) const
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . binding ;
else return BIND_OFF ;
2003-05-07 21:13:13 +08:00
}
2003-09-10 06:18:35 +08:00
void Geometry : : setVertexAttribNormalize ( unsigned int index , GLboolean norm )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
getVertexAttribData ( index ) . normalize = norm ;
2003-05-07 21:13:13 +08:00
dirtyDisplayList ( ) ;
}
2003-09-10 06:18:35 +08:00
GLboolean Geometry : : getVertexAttribNormalize ( unsigned int index ) const
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
if ( index < _vertexAttribList . size ( ) ) return _vertexAttribList [ index ] . normalize ;
else return GL_FALSE ;
2003-05-07 21:13:13 +08:00
}
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
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// check to see if fast path can be used.
//
_fastPath = true ;
2003-09-10 06:18:35 +08:00
if ( _vertexData . indices . valid ( ) ) _fastPath = false ;
else if ( _normalData . binding = = BIND_PER_PRIMITIVE | | ( _normalData . binding = = BIND_PER_VERTEX & & _normalData . indices . valid ( ) ) ) _fastPath = false ;
else if ( _colorData . binding = = BIND_PER_PRIMITIVE | | ( _colorData . binding = = BIND_PER_VERTEX & & _colorData . indices . valid ( ) ) ) _fastPath = false ;
else if ( _secondaryColorData . binding = = BIND_PER_PRIMITIVE | | ( _secondaryColorData . binding = = BIND_PER_VERTEX & & _secondaryColorData . indices . valid ( ) ) ) _fastPath = false ;
else if ( _fogCoordData . binding = = BIND_PER_PRIMITIVE | | ( _fogCoordData . binding = = BIND_PER_VERTEX & & _fogCoordData . indices . valid ( ) ) ) _fastPath = false ;
2003-05-07 21:13:13 +08:00
else
{
2003-09-10 06:18:35 +08:00
for ( unsigned int va = 0 ; va < _vertexAttribList . size ( ) ; + + va )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
if ( _vertexAttribList [ va ] . binding = = BIND_PER_PRIMITIVE )
2003-05-07 21:13:13 +08:00
{
_fastPath = false ;
break ;
}
else
{
2003-09-10 06:18:35 +08:00
const Array * array = _vertexAttribList [ va ] . array . get ( ) ;
const IndexArray * idxArray = _vertexAttribList [ va ] . indices . get ( ) ;
2003-05-07 21:13:13 +08:00
2003-09-10 06:18:35 +08:00
if ( _vertexAttribList [ va ] . binding = = BIND_PER_VERTEX & &
2003-05-07 21:13:13 +08:00
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-09-10 06:18:35 +08:00
const ArrayData & texcoordData = _texCoordList [ unit ] ;
if ( texcoordData . array . valid ( ) & & texcoordData . array - > getNumElements ( ) > 0 )
2002-08-16 04:27:33 +08:00
{
2003-09-10 06:18:35 +08:00
if ( texcoordData . indices . valid ( ) )
2002-08-16 04:27:33 +08:00
{
2003-09-10 06:18:35 +08:00
if ( texcoordData . indices - > getNumElements ( ) > 0 )
2002-10-02 21:12:16 +08:00
{
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 ) ;
2003-09-10 06:18:35 +08:00
if ( ! ( ( _vertexData . array . valid ( ) & & _vertexData . array - > getNumElements ( ) ! = 0 ) | |
2003-05-07 21:13:13 +08:00
( _vertexAttribList . size ( ) > 0 & &
2003-09-10 06:18:35 +08:00
_vertexAttribList [ 0 ] . array . valid ( ) & &
_vertexAttribList [ 0 ] . array - > getNumElements ( ) ! = 0 ) ) )
2003-05-07 21:13:13 +08:00
{
return ;
}
2002-08-18 19:16:31 +08:00
2003-09-10 06:18:35 +08:00
if ( ( _vertexData . indices . valid ( ) & & _vertexData . indices - > getNumElements ( ) = = 0 ) | |
2003-05-07 21:13:13 +08:00
( _vertexAttribList . size ( ) > 0 & &
2003-09-10 06:18:35 +08:00
_vertexAttribList [ 0 ] . indices . valid ( ) & &
_vertexAttribList [ 0 ] . indices - > getNumElements ( ) = = 0 ) )
2003-05-07 21:13:13 +08:00
{
return ;
}
2002-10-02 21:12:16 +08:00
2003-09-10 06:18:35 +08:00
DrawNormal drawNormal ( _normalData . array . get ( ) , _normalData . indices . get ( ) ) ;
DrawColor drawColor ( _colorData . array . get ( ) , _colorData . indices . get ( ) ) ;
DrawSecondaryColor drawSecondaryColor ( _secondaryColorData . array . get ( ) , _secondaryColorData . indices . get ( ) , extensions ) ;
2002-10-02 21:12:16 +08:00
2003-09-10 06:18:35 +08:00
DrawFogCoord drawFogCoord ( _fogCoordData . array . get ( ) , _fogCoordData . indices . get ( ) , extensions ) ;
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set up secondary color if required.
//
2003-09-10 06:18:35 +08:00
AttributeBinding secondaryColorBinding = _secondaryColorData . binding ;
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.
//
2003-09-10 06:18:35 +08:00
AttributeBinding fogCoordBinding = _fogCoordData . binding ;
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
unsigned int normalIndex = 0 ;
unsigned int colorIndex = 0 ;
unsigned int secondaryColorIndex = 0 ;
unsigned int fogCoordIndex = 0 ;
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...
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = 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
2003-09-10 06:18:35 +08:00
if ( _colorData . binding = = 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-09-01 19:23:29 +08:00
bool vertexVertexAttributesSupported = extensions - > isVertexProgramSupported ( ) ;
bool handleVertexAttributes = ( ! _vertexAttribList . empty ( ) & & vertexVertexAttributesSupported ) ;
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 ;
2003-09-10 06:18:35 +08:00
_vertexData . offset = 0 ;
if ( _vertexData . array . valid ( ) ) totalSize + = _vertexData . array - > getTotalDataSize ( ) ;
2003-06-30 05:41:57 +08:00
2003-09-10 06:18:35 +08:00
_normalData . offset = totalSize ;
if ( _normalData . array . valid ( ) ) totalSize + = _normalData . array - > getTotalDataSize ( ) ;
2003-06-30 05:41:57 +08:00
2003-09-10 06:18:35 +08:00
_colorData . offset = totalSize ;
if ( _colorData . array . valid ( ) ) totalSize + = _colorData . array - > getTotalDataSize ( ) ;
2003-06-30 05:41:57 +08:00
2003-09-10 06:18:35 +08:00
_secondaryColorData . offset = totalSize ;
if ( _secondaryColorData . array . valid ( ) ) totalSize + = _secondaryColorData . array - > getTotalDataSize ( ) ;
2003-06-30 05:41:57 +08:00
2003-09-10 06:18:35 +08:00
_fogCoordData . offset = totalSize ;
if ( _fogCoordData . array . valid ( ) ) totalSize + = _fogCoordData . array - > 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 ;
2003-09-10 06:18:35 +08:00
const Array * array = _texCoordList [ unit ] . array . get ( ) ;
2003-06-30 05:41:57 +08:00
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 ;
2003-09-10 06:18:35 +08:00
const Array * array = _vertexAttribList [ index ] . array . get ( ) ;
const AttributeBinding ab = _vertexAttribList [ index ] . binding ;
2003-06-30 05:41:57 +08:00
if ( ab = = BIND_PER_VERTEX & & array )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +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
//
2003-09-10 06:18:35 +08:00
if ( _vertexData . array . valid ( ) )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _vertexData . offset , _vertexData . array - > getTotalDataSize ( ) , _vertexData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _normalData . offset , _normalData . array - > getTotalDataSize ( ) , _normalData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
2003-09-10 06:18:35 +08:00
if ( _colorData . binding = = BIND_PER_VERTEX )
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _colorData . offset , _colorData . array - > getTotalDataSize ( ) , _colorData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
if ( secondaryColorBinding = = BIND_PER_VERTEX )
2003-09-10 06:18:35 +08:00
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _secondaryColorData . offset , _secondaryColorData . array - > getTotalDataSize ( ) , _secondaryColorData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
if ( fogCoordBinding = = BIND_PER_VERTEX )
2003-09-10 06:18:35 +08:00
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _fogCoordData . offset , _fogCoordData . array - > getTotalDataSize ( ) , _fogCoordData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
{
2003-09-10 06:18:35 +08:00
const Array * array = _texCoordList [ unit ] . array . get ( ) ;
2003-06-30 05:41:57 +08:00
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 )
{
2003-09-10 06:18:35 +08:00
const Array * array = _vertexAttribList [ index ] . array . get ( ) ;
const AttributeBinding ab = _vertexAttribList [ index ] . binding ;
2003-06-30 05:41:57 +08:00
if ( ab = = BIND_PER_VERTEX & & array )
2003-05-09 21:07:06 +08:00
{
2003-09-10 06:18:35 +08:00
extensions - > glBufferSubData ( GL_ARRAY_BUFFER_ARB , _vertexAttribList [ index ] . 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
2003-09-10 06:18:35 +08:00
if ( _vertexData . array . valid ( ) )
state . setVertexPointer ( _vertexData . array - > getDataSize ( ) , _vertexData . array - > getDataType ( ) , 0 , ( const GLvoid * ) _vertexData . offset ) ;
2003-06-30 05:41:57 +08:00
else
state . disableVertexPointer ( ) ;
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX )
state . setNormalPointer ( GL_FLOAT , 0 , ( const GLvoid * ) _normalData . offset ) ;
2003-06-30 05:41:57 +08:00
else
state . disableNormalPointer ( ) ;
2003-09-10 06:18:35 +08:00
if ( _colorData . binding = = BIND_PER_VERTEX )
state . setColorPointer ( _colorData . array - > getDataSize ( ) , _colorData . array - > getDataType ( ) , 0 , ( const GLvoid * ) _colorData . offset ) ;
2003-06-30 05:41:57 +08:00
else
state . disableColorPointer ( ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX )
2003-09-10 06:18:35 +08:00
state . setSecondaryColorPointer ( _secondaryColorData . array - > getDataSize ( ) , _secondaryColorData . array - > getDataType ( ) , 0 , ( const GLvoid * ) _secondaryColorData . offset ) ;
2003-06-30 05:41:57 +08:00
else
state . disableSecondaryColorPointer ( ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX )
2003-09-10 06:18:35 +08:00
state . setFogCoordPointer ( GL_FLOAT , 0 , ( const GLvoid * ) _fogCoordData . offset ) ;
2003-06-30 05:41:57 +08:00
else
state . disableFogCoordPointer ( ) ;
unsigned int unit ;
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
{
2003-09-10 06:18:35 +08:00
const Array * array = _texCoordList [ unit ] . array . get ( ) ;
2003-06-30 05:41:57 +08:00
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 )
{
2003-09-10 06:18:35 +08:00
const Array * array = _vertexAttribList [ index ] . array . get ( ) ;
const AttributeBinding ab = _vertexAttribList [ index ] . binding ;
2003-06-30 05:41:57 +08:00
if ( ab = = BIND_PER_VERTEX & & array )
{
state . setVertexAttribPointer ( index , array - > getDataSize ( ) , array - > getDataType ( ) ,
2003-09-10 06:18:35 +08:00
_vertexAttribList [ index ] . normalize , 0 , ( const GLvoid * ) _vertexAttribList [ index ] . offset ) ;
2003-06-30 05:41:57 +08:00
}
else
{
if ( array )
{
2003-09-10 06:18:35 +08:00
const IndexArray * indexArray = _vertexAttribList [ index ] . indices . get ( ) ;
2003-06-30 05:41:57 +08:00
if ( indexArray & & indexArray - > getNumElements ( ) > 0 )
{
drawVertexAttribMap [ ab ] . push_back (
2003-09-10 06:18:35 +08:00
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . normalize , array , indexArray ) ) ;
2003-06-30 05:41:57 +08:00
}
else
{
drawVertexAttribMap [ ab ] . push_back (
2003-09-10 06:18:35 +08:00
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . normalize , array , 0 ) ) ;
2003-06-30 05:41:57 +08:00
}
}
state . disableVertexAttribPointer ( index ) ;
}
2003-05-07 21:13:13 +08:00
}
2003-06-30 05:41:57 +08:00
state . disableVertexAttribPointersAboveAndIncluding ( index ) ;
2003-09-01 19:23:29 +08:00
}
else if ( vertexVertexAttributesSupported )
{
state . disableVertexAttribPointersAboveAndIncluding ( 0 ) ;
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.
//
2003-09-10 06:18:35 +08:00
if ( _vertexData . array . valid ( ) )
state . setVertexPointer ( _vertexData . array - > getDataSize ( ) , _vertexData . array - > getDataType ( ) , 0 , _vertexData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
else
state . disableVertexPointer ( ) ;
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX )
state . setNormalPointer ( GL_FLOAT , 0 , _normalData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
else
state . disableNormalPointer ( ) ;
2003-09-10 06:18:35 +08:00
if ( _colorData . binding = = BIND_PER_VERTEX )
state . setColorPointer ( _colorData . array - > getDataSize ( ) , _colorData . array - > getDataType ( ) , 0 , _colorData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
else
state . disableColorPointer ( ) ;
if ( secondaryColorBinding = = BIND_PER_VERTEX )
2003-09-10 06:18:35 +08:00
state . setSecondaryColorPointer ( _secondaryColorData . array - > getDataSize ( ) , _secondaryColorData . array - > getDataType ( ) , 0 , _secondaryColorData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
else
state . disableSecondaryColorPointer ( ) ;
if ( fogCoordBinding = = BIND_PER_VERTEX )
2003-09-10 06:18:35 +08:00
state . setFogCoordPointer ( GL_FLOAT , 0 , _fogCoordData . array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
else
state . disableFogCoordPointer ( ) ;
unsigned int unit ;
for ( unit = 0 ; unit < _texCoordList . size ( ) ; + + unit )
{
2003-09-10 06:18:35 +08:00
const Array * array = _texCoordList [ unit ] . array . get ( ) ;
2003-06-30 05:41:57 +08:00
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 )
{
2003-09-10 06:18:35 +08:00
const Array * array = _vertexAttribList [ index ] . array . get ( ) ;
const AttributeBinding ab = _vertexAttribList [ index ] . binding ;
2003-06-30 05:41:57 +08:00
if ( ab = = BIND_PER_VERTEX & & array )
{
state . setVertexAttribPointer ( index , array - > getDataSize ( ) , array - > getDataType ( ) ,
2003-09-10 06:18:35 +08:00
_vertexAttribList [ index ] . normalize , 0 , array - > getDataPointer ( ) ) ;
2003-06-30 05:41:57 +08:00
}
else
{
if ( array )
{
2003-09-10 06:18:35 +08:00
const IndexArray * indexArray = _vertexAttribList [ index ] . indices . get ( ) ;
2003-06-30 05:41:57 +08:00
if ( indexArray & & indexArray - > getNumElements ( ) > 0 )
{
drawVertexAttribMap [ ab ] . push_back (
2003-09-10 06:18:35 +08:00
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . normalize , array , indexArray ) ) ;
2003-06-30 05:41:57 +08:00
}
else
{
drawVertexAttribMap [ ab ] . push_back (
2003-09-10 06:18:35 +08:00
new DrawVertexAttrib ( extensions , index , _vertexAttribList [ index ] . normalize , array , 0 ) ) ;
2003-06-30 05:41:57 +08:00
}
}
2002-10-02 21:12:16 +08:00
2003-06-30 05:41:57 +08:00
state . disableVertexAttribPointer ( index ) ;
}
}
state . disableVertexAttribPointersAboveAndIncluding ( index ) ;
2003-09-01 19:23:29 +08:00
}
else if ( vertexVertexAttributesSupported )
{
state . disableVertexAttribPointersAboveAndIncluding ( 0 ) ;
2003-06-30 05:41:57 +08:00
}
}
2002-10-02 21:12:16 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// pass the overall binding values onto OpenGL.
//
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_OVERALL ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_OVERALL ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE_SET ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE_SET ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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-09-10 06:18:35 +08:00
if ( extensions - > isMultiTexSupported ( ) & & _texCoordList . size ( ) > 1 )
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-09-10 06:18:35 +08:00
const ArrayData & texcoordData = _texCoordList [ unit ] ;
if ( texcoordData . array . valid ( ) & & texcoordData . array - > getNumElements ( ) > 0 )
2002-10-02 21:12:16 +08:00
{
2003-09-10 06:18:35 +08:00
if ( texcoordData . indices . valid ( ) & & texcoordData . indices - > getNumElements ( ) > 0 )
2002-10-02 21:12:16 +08:00
{
2003-09-10 06:18:35 +08:00
drawTexCoordList . push_back ( new DrawMultiTexCoord ( GL_TEXTURE0 + unit , texcoordData . array . get ( ) , texcoordData . indices . get ( ) ,
extensions ) ) ;
2002-10-02 21:12:16 +08:00
}
else
{
2003-09-10 06:18:35 +08:00
drawTexCoordList . push_back ( new DrawMultiTexCoord ( GL_TEXTURE0 + unit , texcoordData . array . get ( ) , 0 ,
2003-05-07 21:13:13 +08:00
extensions ) ) ;
2002-10-02 21:12:16 +08:00
}
}
}
}
else
{
if ( ! _texCoordList . empty ( ) )
{
2003-09-10 06:18:35 +08:00
const ArrayData & texcoordData = _texCoordList [ 0 ] ;
if ( texcoordData . array . valid ( ) & & texcoordData . array - > getNumElements ( ) > 0 )
2002-10-02 21:12:16 +08:00
{
2003-09-10 06:18:35 +08:00
if ( texcoordData . indices . valid ( ) )
2002-10-02 21:12:16 +08:00
{
2003-09-10 06:18:35 +08:00
if ( texcoordData . indices - > getNumElements ( ) > 0 )
2002-10-02 21:12:16 +08:00
{
2003-09-10 06:18:35 +08:00
drawTextCoord = new DrawTexCoord ( texcoordData . array . get ( ) , texcoordData . indices . get ( ) ) ;
2002-10-02 21:12:16 +08:00
}
}
else
{
2003-09-10 06:18:35 +08:00
drawTextCoord = new DrawTexCoord ( texcoordData . array . get ( ) , 0 ) ;
2002-10-02 21:12:16 +08:00
}
}
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
{
2003-09-10 06:18:35 +08:00
const ArrayData & vertAttribData = _vertexAttribList [ index ] ;
if ( vertAttribData . array . valid ( ) & & vertAttribData . array - > getNumElements ( ) > 0 )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
if ( vertAttribData . indices . valid ( ) & & vertAttribData . indices - > getNumElements ( ) > 0 )
2003-05-07 21:13:13 +08:00
{
2003-09-10 06:18:35 +08:00
drawVertexAttribMap [ vertAttribData . binding ] . push_back (
new DrawVertexAttrib ( extensions , index , vertAttribData . normalize , vertAttribData . array . get ( ) , vertAttribData . indices . get ( ) ) ) ;
2003-05-07 21:13:13 +08:00
}
2003-05-09 21:07:06 +08:00
else
{
2003-09-10 06:18:35 +08:00
drawVertexAttribMap [ vertAttribData . binding ] . push_back (
new DrawVertexAttrib ( extensions , index , vertAttribData . normalize , vertAttribData . array . get ( ) , 0 ) ) ;
2003-05-09 21:07:06 +08:00
}
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.
//
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_OVERALL ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_OVERALL ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
2002-10-02 21:12:16 +08:00
// set up vertex functor.
2003-09-10 06:18:35 +08:00
DrawVertex drawVertex ( _vertexData . array . get ( ) , _vertexData . indices . get ( ) ) ;
2002-10-02 21:12:16 +08:00
2003-05-09 21:07:06 +08:00
bool useVertexAttrib = _vertexAttribList . size ( ) > 0 & &
2003-09-10 06:18:35 +08:00
_vertexAttribList [ 0 ] . array . valid ( ) & &
_vertexAttribList [ 0 ] . indices - > getNumElements ( ) ;
2003-05-09 21:07:06 +08:00
ref_ptr < DrawVertexAttrib > drawVertexAttribZero ;
if ( useVertexAttrib )
{
drawVertexAttribZero = new DrawVertexAttrib ( extensions , 0 ,
2003-09-10 06:18:35 +08:00
_vertexAttribList [ 0 ] . normalize , _vertexAttribList [ 0 ] . array . get ( ) ,
_vertexAttribList [ 0 ] . indices . get ( ) ) ;
2003-05-09 21:07:06 +08:00
}
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
{
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE_SET ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE_SET ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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 )
{
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
2002-10-02 21:12:16 +08:00
}
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorData . binding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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 )
{
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
2002-10-02 21:12:16 +08:00
}
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorData . binding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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 )
{
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
2002-10-02 21:12:16 +08:00
}
unsigned int vindex = * primItr ;
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorData . binding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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 )
{
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
2002-10-02 21:12:16 +08:00
}
unsigned int vindex = * primItr ;
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorData . binding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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 )
{
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_PRIMITIVE ) drawNormal ( normalIndex + + ) ;
if ( _colorData . binding = = BIND_PER_PRIMITIVE ) drawColor ( colorIndex + + ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
2002-10-02 21:12:16 +08:00
}
unsigned int vindex = * primItr ;
2003-09-10 06:18:35 +08:00
if ( _normalData . binding = = BIND_PER_VERTEX ) drawNormal ( vindex ) ;
if ( _colorData . binding = = BIND_PER_VERTEX ) drawColor ( vindex ) ;
2002-10-02 21:12:16 +08:00
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 )
{
2003-10-22 21:39:16 +08:00
list [ i ] - > applyAndIncrement ( ) ;
2003-05-07 21:13:13 +08:00
}
}
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 ) ;
2003-09-10 06:18:35 +08:00
afav . applyArray ( VERTICES , _vertexData . array . get ( ) ) ;
afav . applyArray ( NORMALS , _normalData . array . get ( ) ) ;
afav . applyArray ( COLORS , _colorData . array . 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
{
2003-09-10 06:18:35 +08:00
afav . applyArray ( ( AttributeType ) ( TEXTURE_COORDS_0 + unit ) , _texCoordList [ unit ] . array . 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 ) ;
2003-09-10 06:18:35 +08:00
afav . applyArray ( VERTICES , _vertexData . array . get ( ) ) ;
afav . applyArray ( NORMALS , _normalData . array . get ( ) ) ;
afav . applyArray ( COLORS , _colorData . array . 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
{
2003-09-10 06:18:35 +08:00
afav . applyArray ( ( AttributeType ) ( TEXTURE_COORDS_0 + unit ) , _texCoordList [ unit ] . array . 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-09-10 06:18:35 +08:00
if ( ! _vertexData . array . valid ( ) | | _vertexData . array - > getNumElements ( ) = = 0 ) return ;
2003-06-24 23:40:09 +08:00
2003-09-10 06:18:35 +08:00
if ( ! _vertexData . indices . valid ( ) )
2002-06-26 04:27:51 +08:00
{
2003-09-10 06:18:35 +08:00
switch ( _vertexData . array - > getType ( ) )
2003-06-24 23:40:09 +08:00
{
case ( Array : : Vec2ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . setVertexArray ( _vertexData . array - > getNumElements ( ) , static_cast < const Vec2 * > ( _vertexData . array - > getDataPointer ( ) ) ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . setVertexArray ( _vertexData . array - > getNumElements ( ) , static_cast < const Vec3 * > ( _vertexData . array - > getDataPointer ( ) ) ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . setVertexArray ( _vertexData . array - > getNumElements ( ) , static_cast < const Vec4 * > ( _vertexData . array - > getDataPointer ( ) ) ) ;
2003-06-24 23:40:09 +08:00
break ;
default :
2003-09-10 06:18:35 +08:00
notify ( WARN ) < < " Warning: Geometry::accept(PrimtiveFunctor&) cannot handle Vertex Array type " < < _vertexData . array - > getType ( ) < < std : : endl ;
2003-06-24 23:40:09 +08:00
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 ;
2003-09-10 06:18:35 +08:00
Array : : Type type = _vertexData . array - > getType ( ) ;
2003-06-24 23:40:09 +08:00
switch ( type )
{
case ( Array : : Vec2ArrayType ) :
2003-09-10 06:18:35 +08:00
vec2Array = static_cast < const Vec2Array * > ( _vertexData . array . get ( ) ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
vec3Array = static_cast < const Vec3Array * > ( _vertexData . array . get ( ) ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
vec4Array = static_cast < const Vec4Array * > ( _vertexData . array . get ( ) ) ;
2003-06-24 23:40:09 +08:00
break ;
default :
2003-09-10 06:18:35 +08:00
notify ( WARN ) < < " Warning: Geometry::accept(PrimtiveFunctor&) cannot handle Vertex Array type " < < _vertexData . array - > getType ( ) < < std : : endl ;
2003-06-24 23:40:09 +08:00
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 ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec2Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec3Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec4Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
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 ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec2Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec3Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec4Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
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 ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec2Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec3Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec4Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
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 ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec2Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec3Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec4Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
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 ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec2Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec3ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec3Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
break ;
case ( Array : : Vec4ArrayType ) :
2003-09-10 06:18:35 +08:00
functor . vertex ( ( * vec4Array ) [ _vertexData . indices - > index ( vindex ) ] ) ;
2003-06-24 23:40:09 +08:00
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
}
2003-09-24 23:54:22 +08:00
unsigned int _computeNumberOfPrimtives ( const osg : : Geometry & geom )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
unsigned int totalNumberOfPrimitives = 0 ;
for ( Geometry : : PrimitiveSetList : : const_iterator itr = geom . getPrimitiveSetList ( ) . begin ( ) ;
itr ! = geom . getPrimitiveSetList ( ) . end ( ) ;
+ + itr )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
const PrimitiveSet * primitiveset = itr - > get ( ) ;
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 ( ) )
{
case ( PrimitiveSet : : DrawArrayLengthsPrimitiveType ) :
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
const DrawArrayLengths * drawArrayLengths = static_cast < const DrawArrayLengths * > ( primitiveset ) ;
for ( DrawArrayLengths : : const_iterator primItr = drawArrayLengths - > begin ( ) ;
primItr ! = drawArrayLengths - > end ( ) ;
+ + primItr )
{
if ( primLength = = 0 ) totalNumberOfPrimitives + = 1 ;
else totalNumberOfPrimitives = * primItr / primLength ;
}
break ;
2002-07-18 08:53:03 +08:00
}
2003-09-24 23:54:22 +08:00
default :
{
if ( primLength = = 0 ) totalNumberOfPrimitives + = 1 ;
else totalNumberOfPrimitives = primitiveset - > getNumIndices ( ) / primLength ;
}
}
}
return totalNumberOfPrimitives ;
}
template < class A >
bool _verifyBindings ( const osg : : Geometry & geom , const A & arrayData )
{
2003-09-29 22:07:46 +08:00
unsigned int numElements = arrayData . indices . valid ( ) ? arrayData . indices - > getNumElements ( ) :
arrayData . array . valid ( ) ? arrayData . array - > getNumElements ( ) : 0 ;
2003-09-24 23:54:22 +08:00
switch ( arrayData . binding )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_OFF ) :
2003-09-29 22:07:46 +08:00
if ( numElements > 0 ) return false ;
2002-07-18 08:53:03 +08:00
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_OVERALL ) :
2003-09-29 22:07:46 +08:00
if ( numElements ! = 1 ) return false ;
2002-07-18 08:53:03 +08:00
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_PER_PRIMITIVE_SET ) :
2003-09-29 22:07:46 +08:00
if ( numElements ! = geom . getPrimitiveSetList ( ) . size ( ) ) return false ;
2002-07-18 08:53:03 +08:00
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_PER_PRIMITIVE ) :
2003-09-29 22:07:46 +08:00
if ( numElements ! = _computeNumberOfPrimtives ( geom ) ) return false ;
2003-05-22 23:29:20 +08:00
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_PER_VERTEX ) :
2003-09-29 22:07:46 +08:00
{
unsigned int numVertices = geom . getVertexIndices ( ) ? geom . getVertexIndices ( ) - > getNumElements ( ) :
geom . getVertexArray ( ) ? geom . getVertexArray ( ) - > getNumElements ( ) : 0 ;
if ( numElements ! = numVertices ) return false ;
2002-07-18 08:53:03 +08:00
break ;
2003-09-29 22:07:46 +08:00
}
2002-07-18 08:53:03 +08:00
}
return true ;
}
2003-09-24 23:54:22 +08:00
template < class A >
2003-09-26 19:20:43 +08:00
void _computeCorrectBindingsAndArraySizes ( const osg : : Geometry & geom , A & arrayData , const char * arrayName )
2002-07-18 08:53:03 +08:00
{
2003-09-29 22:07:46 +08:00
unsigned int numVertices = geom . getVertexIndices ( ) ? geom . getVertexIndices ( ) - > getNumElements ( ) :
geom . getVertexArray ( ) ? geom . getVertexArray ( ) - > getNumElements ( ) : 0 ;
if ( numVertices = = 0 )
2002-07-18 08:53:03 +08:00
{
2003-09-29 22:07:46 +08:00
if ( arrayData . binding ! = osg : : Geometry : : BIND_OFF )
2003-09-24 23:54:22 +08:00
{
arrayData . array = 0 ;
arrayData . indices = 0 ;
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() vertex array is empty but " < < std : : endl
< < " vertex array is empty but " < < arrayName < < " is set " < < std : : endl
< < " reseting " < < arrayName < < " binding to BIND_OFF and array & indices to 0. " < < std : : endl ;
}
2002-07-18 08:53:03 +08:00
}
2003-09-24 23:54:22 +08:00
2003-09-29 22:07:46 +08:00
unsigned int numElements = arrayData . indices . valid ( ) ? arrayData . indices - > getNumElements ( ) :
arrayData . array . valid ( ) ? arrayData . array - > getNumElements ( ) : 0 ;
2003-09-24 23:54:22 +08:00
switch ( arrayData . binding )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_OFF ) :
2003-09-29 22:07:46 +08:00
if ( numElements ! = 0 )
2003-09-24 23:54:22 +08:00
{
arrayData . array = 0 ;
2003-09-29 22:07:46 +08:00
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_OFF but " < < arrayName < < " array is attached " < < std : : endl
< < " reseting array to 0. " < < std : : endl ;
}
2002-07-18 08:53:03 +08:00
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_OVERALL ) :
2003-09-29 22:07:46 +08:00
if ( numElements = = 0 )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
arrayData . array = 0 ;
2003-09-29 22:07:46 +08:00
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_OVERALL but " < < arrayName < < " array is empty " < < std : : endl
< < " reseting binding to BIND_OFF " < < arrayName < < " array to 0. " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
2003-09-29 22:07:46 +08:00
else if ( numElements > 1 )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_OVERALL but " < < std : : endl
< < " " < < arrayName < < " contains more than one entry " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_PER_PRIMITIVE_SET ) :
2003-09-29 22:07:46 +08:00
if ( numElements = = 0 )
2002-07-18 08:53:03 +08:00
{
2003-09-29 22:07:46 +08:00
arrayData . array = 0 ;
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_PRIMITIVE_SET but " < < std : : endl
< < " " < < arrayName < < " array is not attached " < < std : : endl
< < " reseting binding to BIND_OFF. " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
2003-09-29 22:07:46 +08:00
else if ( numElements < geom . getPrimitiveSetList ( ) . size ( ) )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
arrayData . array = 0 ;
2003-09-29 22:07:46 +08:00
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_PRIMITIVE_SET but " < < std : : endl
< < " " < < arrayName < < " array contains too few entries " < < std : : endl
< < " reseting binding to BIND_OFF " < < arrayName < < " array to 0. " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
2003-09-29 22:07:46 +08:00
else if ( numElements > geom . getPrimitiveSetList ( ) . size ( ) )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_PRIMITIVE_SET but " < < std : : endl
< < " " < < arrayName < < " array contains too many entries " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
break ;
2003-09-24 23:54:22 +08:00
case ( osg : : Geometry : : BIND_PER_PRIMITIVE ) :
{
unsigned int numPrimitives = _computeNumberOfPrimtives ( geom ) ;
2003-09-29 22:07:46 +08:00
if ( numElements = = 0 )
2003-09-24 23:54:22 +08:00
{
2003-09-29 22:07:46 +08:00
arrayData . array = 0 ;
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_PRIMITIVE but " < < std : : endl
< < " " < < arrayName < < " array is not attached " < < std : : endl
< < " reseting binding to BIND_OFF. " < < std : : endl ;
}
2003-09-29 22:07:46 +08:00
else if ( numElements < numPrimitives )
2003-09-24 23:54:22 +08:00
{
2003-09-29 22:07:46 +08:00
arrayData . array = 0 ;
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_PRIMITIVE but " < < std : : endl
< < " " < < arrayName < < " array contains too few entries " < < std : : endl
< < " reseting binding to BIND_OFF " < < arrayName < < " array to 0. " < < std : : endl ;
}
2003-09-29 22:07:46 +08:00
else if ( numElements > numPrimitives )
2003-09-24 23:54:22 +08:00
{
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_PRIMITIVE but " < < std : : endl
< < " " < < arrayName < < " array contains too many entries " < < std : : endl ;
}
2003-05-22 23:29:20 +08:00
break ;
2003-09-24 23:54:22 +08:00
}
case ( osg : : Geometry : : BIND_PER_VERTEX ) :
2003-09-29 22:07:46 +08:00
if ( numElements = = 0 )
2002-07-18 08:53:03 +08:00
{
2003-09-29 22:07:46 +08:00
arrayData . array = 0 ;
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_VERTEX but " < < std : : endl
< < " " < < arrayName < < " array is not attached " < < std : : endl
< < " reseting binding to BIND_OFF. " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
2003-09-29 22:07:46 +08:00
else if ( numElements < numVertices )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
arrayData . array = 0 ;
2003-09-29 22:07:46 +08:00
arrayData . indices = 0 ;
2003-09-24 23:54:22 +08:00
arrayData . binding = osg : : Geometry : : BIND_OFF ;
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_VERTEX but " < < std : : endl
< < " " < < arrayName < < " array contains too few entries " < < std : : endl
< < " reseting binding to BIND_OFF " < < arrayName < < " array to 0. " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
2003-09-29 22:07:46 +08:00
else if ( numElements > numVertices )
2002-07-18 08:53:03 +08:00
{
2003-09-24 23:54:22 +08:00
notify ( WARN ) < < " Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() " < < std : : endl
< < " " < < arrayName < < " binding is BIND_PER_VERTEX but " < < std : : endl
< < " " < < arrayName < < " array contains too many entries " < < std : : endl ;
2002-07-18 08:53:03 +08:00
}
break ;
}
2003-09-24 23:54:22 +08:00
}
bool Geometry : : verifyBindings ( const ArrayData & arrayData ) const
{
return _verifyBindings ( * this , arrayData ) ;
}
bool Geometry : : verifyBindings ( const Vec3ArrayData & arrayData ) const
{
return _verifyBindings ( * this , arrayData ) ;
}
void Geometry : : computeCorrectBindingsAndArraySizes ( ArrayData & arrayData , const char * arrayName )
{
_computeCorrectBindingsAndArraySizes ( * this , arrayData , arrayName ) ;
}
void Geometry : : computeCorrectBindingsAndArraySizes ( Vec3ArrayData & arrayData , const char * arrayName )
{
_computeCorrectBindingsAndArraySizes ( * this , arrayData , arrayName ) ;
}
bool Geometry : : verifyBindings ( ) const
{
if ( ! verifyBindings ( _normalData ) ) return false ;
if ( ! verifyBindings ( _colorData ) ) return false ;
if ( ! verifyBindings ( _secondaryColorData ) ) return false ;
if ( ! verifyBindings ( _fogCoordData ) ) return false ;
for ( ArrayList : : const_iterator titr = _texCoordList . begin ( ) ;
titr ! = _texCoordList . end ( ) ;
+ + titr )
{
if ( ! verifyBindings ( * titr ) ) return false ;
}
for ( ArrayList : : const_iterator vitr = _vertexAttribList . begin ( ) ;
vitr ! = _vertexAttribList . end ( ) ;
+ + vitr )
{
if ( ! verifyBindings ( * vitr ) ) return false ;
}
return true ;
}
void Geometry : : computeCorrectBindingsAndArraySizes ( )
{
if ( verifyBindings ( ) ) return ;
2002-07-18 08:53:03 +08:00
2003-09-24 23:54:22 +08:00
computeCorrectBindingsAndArraySizes ( _normalData , " _normalData " ) ;
computeCorrectBindingsAndArraySizes ( _colorData , " _colorData " ) ;
computeCorrectBindingsAndArraySizes ( _secondaryColorData , " _secondaryColorData " ) ;
computeCorrectBindingsAndArraySizes ( _fogCoordData , " _fogCoordData " ) ;
for ( ArrayList : : iterator titr = _texCoordList . begin ( ) ;
titr ! = _texCoordList . end ( ) ;
+ + titr )
{
computeCorrectBindingsAndArraySizes ( * titr , " _texCoordList[] " ) ;
}
for ( ArrayList : : iterator vitr = _vertexAttribList . begin ( ) ;
vitr ! = _vertexAttribList . end ( ) ;
+ + vitr )
{
computeCorrectBindingsAndArraySizes ( * vitr , " _vertAttribList[] " ) ;
}
2002-07-18 08:53:03 +08:00
}
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 ) { }
2003-12-05 01:14:06 +08:00
virtual ~ ExpandIndexedArray ( ) { }
2003-08-08 08:21:30 +08:00
template < class T , class I >
T * create ( const T & array , const I & indices )
{
T * newArray = 0 ;
2003-12-05 01:14:06 +08:00
// if source array type and target array type are equal but arrays arn't equal
if ( _targetArray & & _targetArray - > getType ( ) = = array . getType ( ) & & _targetArray ! = & array )
2003-08-08 08:21:30 +08:00
{
// 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 )
{
2003-12-05 01:14:06 +08:00
bool copyToSelf = ( this = = & target ) ;
2003-08-08 08:21:30 +08:00
// copy over primitive sets.
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . getPrimitiveSetList ( ) = getPrimitiveSetList ( ) ;
2003-08-08 08:21:30 +08:00
// copy over attribute arrays.
if ( getVertexIndices ( ) )
{
ExpandIndexedArray eia ( * ( getVertexIndices ( ) ) , target . getVertexArray ( ) ) ;
getVertexArray ( ) - > accept ( eia ) ;
target . setVertexArray ( eia . _targetArray ) ;
target . setVertexIndices ( 0 ) ;
}
else if ( getVertexArray ( ) )
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setVertexArray ( getVertexArray ( ) ) ;
2003-08-08 08:21:30 +08:00
}
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 ( ) )
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setNormalArray ( getNormalArray ( ) ) ;
2003-08-08 08:21:30 +08:00
}
target . setColorBinding ( getColorBinding ( ) ) ;
if ( getColorIndices ( ) )
{
ExpandIndexedArray eia ( * ( getColorIndices ( ) ) , target . getColorArray ( ) ) ;
getColorArray ( ) - > accept ( eia ) ;
target . setColorArray ( eia . _targetArray ) ;
target . setColorIndices ( 0 ) ;
}
else if ( getColorArray ( ) )
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setColorArray ( getColorArray ( ) ) ;
2003-08-08 08:21:30 +08:00
}
target . setSecondaryColorBinding ( getSecondaryColorBinding ( ) ) ;
if ( getSecondaryColorIndices ( ) )
{
ExpandIndexedArray eia ( * ( getSecondaryColorIndices ( ) ) , target . getSecondaryColorArray ( ) ) ;
getSecondaryColorArray ( ) - > accept ( eia ) ;
target . setSecondaryColorArray ( eia . _targetArray ) ;
target . setSecondaryColorIndices ( 0 ) ;
}
else if ( getSecondaryColorArray ( ) )
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setSecondaryColorArray ( getSecondaryColorArray ( ) ) ;
2003-08-08 08:21:30 +08:00
}
target . setFogCoordBinding ( getFogCoordBinding ( ) ) ;
if ( getFogCoordIndices ( ) )
{
ExpandIndexedArray eia ( * ( getFogCoordIndices ( ) ) , target . getFogCoordArray ( ) ) ;
getFogCoordArray ( ) - > accept ( eia ) ;
target . setFogCoordArray ( eia . _targetArray ) ;
target . setFogCoordIndices ( 0 ) ;
}
else if ( getFogCoordArray ( ) )
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setFogCoordArray ( getFogCoordArray ( ) ) ;
2003-08-08 08:21:30 +08:00
}
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 ) )
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setTexCoordArray ( ti , getTexCoordArray ( ti ) ) ;
2003-08-08 08:21:30 +08:00
}
}
2003-09-10 06:18:35 +08:00
for ( unsigned int vi = 0 ; vi < _vertexAttribList . size ( ) ; + + vi )
2003-08-08 08:21:30 +08:00
{
2003-09-10 06:18:35 +08:00
ArrayData & arrayData = _vertexAttribList [ vi ] ;
if ( arrayData . indices . valid ( ) )
2003-08-08 08:21:30 +08:00
{
2003-09-10 06:18:35 +08:00
ExpandIndexedArray eia ( * arrayData . indices , target . getVertexAttribArray ( vi ) ) ;
arrayData . array - > accept ( eia ) ;
target . setVertexAttribData ( vi , ArrayData ( eia . _targetArray , 0 , arrayData . binding , arrayData . normalize ) ) ;
2003-08-08 08:21:30 +08:00
}
2003-09-10 06:18:35 +08:00
else if ( arrayData . array . valid ( ) )
2003-08-08 08:21:30 +08:00
{
2003-12-05 01:14:06 +08:00
if ( ! copyToSelf ) target . setVertexAttribData ( vi , arrayData ) ;
2003-08-08 08:21:30 +08:00
}
}
}
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
2003-09-24 23:54:22 +08:00
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 ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
struct V3
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
V3 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
{
glVertex3fv ( _array [ index ] . ptr ( ) ) ;
}
osg : : Vec3 * _array ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
struct V3USI
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
V3USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
glVertex3fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
osg : : Vec3 * _array ;
unsigned short * _indices ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
//////////////////////////////
struct N3
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
N3 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
{
glNormal3fv ( _array [ index ] . ptr ( ) ) ;
}
osg : : Vec3 * _array ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
struct N3USI
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
N3USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
glNormal3fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
osg : : Vec3 * _array ;
unsigned short * _indices ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
//////////////////////////////
struct C4
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
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
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
glVertex3fv ( _array [ index ] . ptr ( ) ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
osg : : Vec4 * _array ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
struct C4USI
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
C4USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
glColor4fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
osg : : Vec4 * _array ;
unsigned short * _indices ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
//////////////////////////////
struct T2
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
T2 ( ) : _array ( 0 ) { }
bool valid ( ) const { return _array ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
{
glTexCoord2fv ( _array [ index ] . ptr ( ) ) ;
}
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
osg : : Vec2 * _array ;
} ;
struct T2USI
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
T2USI ( ) : _array ( 0 ) , _indices ( 0 ) { }
bool valid ( ) const { return _array ! = 0 & & _indices ! = 0 ; }
void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
inline void draw ( unsigned int index ) const
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
glTexCoord2fv ( _array [ _indices [ index ] ] . ptr ( ) ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
osg : : Vec2 * _array ;
unsigned short * _indices ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
template < class T1 >
struct DrawAttributeArrays_T : public DrawAttributeArrays
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
DrawAttributeArrays_T ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
virtual bool valid ( ) const { return _t1 . valid ( ) ; }
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
virtual void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_t1 . set ( geometry ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
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 ;
}
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
T1 _t1 ;
} ;
template < class T1 , class T2 >
struct DrawAttributeArrays_TT : public DrawAttributeArrays
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
DrawAttributeArrays_TT ( )
2003-09-01 06:08:22 +08:00
{
}
2003-09-24 23:54:22 +08:00
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) ; }
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
virtual void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
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 ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
template < class T1 , class T2 , class T3 >
struct DrawAttributeArrays_TTT : public DrawAttributeArrays
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
DrawAttributeArrays_TTT ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) ; }
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
virtual void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_t3 . set ( geometry ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
_t1 . draw ( index ) ;
_t2 . draw ( index ) ;
_t3 . draw ( index ) ;
}
return index ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
T1 _t1 ;
T2 _t2 ;
T3 _t3 ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
template < class T1 , class T2 , class T3 , class T4 >
struct DrawAttributeArrays_TTTT : public DrawAttributeArrays
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
DrawAttributeArrays_TTTT ( )
{
}
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) & & _t4 . valid ( ) ; }
virtual void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_t1 . set ( geometry ) ;
_t2 . set ( geometry ) ;
_t3 . set ( geometry ) ;
_t4 . set ( geometry ) ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
virtual unsigned int draw ( unsigned int index , unsigned int count ) const
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
for ( unsigned int i = 0 ; i < count ; + + i , + + index )
{
_t1 . draw ( index ) ;
_t2 . draw ( index ) ;
_t3 . draw ( index ) ;
_t4 . draw ( index ) ;
}
return index ;
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
T1 _t1 ;
T2 _t2 ;
T3 _t3 ;
T4 _t4 ;
} ;
template < class T1 , class T2 >
struct DrawAttributeArrays_TT_USI : public DrawAttributeArrays
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
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 ;
} ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
template < class T1 , class T2 , class T3 >
struct DrawAttributeArrays_TTT_USI : public DrawAttributeArrays
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
DrawAttributeArrays_TTT_USI ( )
{
}
virtual bool valid ( ) const { return _t1 . valid ( ) & & _t2 . valid ( ) & & _t3 . valid ( ) & & _indices ! = 0 ; }
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
virtual void set ( osg : : Geometry * geometry )
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
_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 ( ) ) ;
}
2003-09-01 06:08:22 +08:00
}
2003-09-24 23:54:22 +08:00
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
2003-09-01 06:08:22 +08:00
{
2003-09-24 23:54:22 +08:00
DrawAttributeArrays_TTTT_USI ( )
2003-09-01 06:08:22 +08:00
{
}
2003-09-24 23:54:22 +08:00
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 ;
} ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
// One attribute x 2
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_T < V3 > DrawAttributeArrays_V3 ;
typedef DrawAttributeArrays_T < V3USI > DrawAttributeArrays_V3i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
// Two attributes x 15
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TT_USI < N3 , V3 > DrawAttributeArrays_N3V3_i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TT_USI < C4 , V3 > DrawAttributeArrays_C4V3_i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TT_USI < T2 , V3 > DrawAttributeArrays_T2V3_i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
// Three attributes x 27
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TTT_USI < C4 , N3 , V3 > DrawAttributeArrays_C4N3V3_i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TTT_USI < T2 , N3 , V3 > DrawAttributeArrays_T2N3V3_i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TTT_USI < T2 , C4 , V3 > DrawAttributeArrays_T2C4V3_t ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
// Four attributes x 17
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
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 ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
typedef DrawAttributeArrays_TTTT_USI < T2 , C4 , N3 , V3 > DrawAttributeArrays_T2C4N3V3_i ;
2003-09-01 06:08:22 +08:00
2003-09-24 23:54:22 +08:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2003-09-01 06:08:22 +08:00
# endif