Show
Ignore:
Timestamp:
10/22/09 12:29:43 (5 years ago)
Author:
robert
Message:

Removed old and now redundent code paths

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osg/Geometry.cpp

    r10654 r10670  
    2121const Geometry::ArrayData Geometry::s_InvalidArrayData; 
    2222 
    23 // #define USE_OLD_DRAW_IMPLEMENTATOIN 
    24  
    25 #ifdef USE_OLD_DRAW_IMPLEMENTATOIN 
    26 class DrawVertex 
    27 { 
    28     public: 
    29      
    30         DrawVertex(const Array* vertices,const IndexArray* indices): 
    31             _vertices(vertices), 
    32             _indices(indices) 
    33         { 
    34             _verticesType = _vertices?_vertices->getType():Array::ArrayType; 
    35             _indicesType = _indices?_indices->getType():Array::ArrayType; 
    36         } 
    37      
    38         inline unsigned int index(unsigned int pos) 
    39         { 
    40             if (_indices)  
    41             { 
    42                 return _indices->index(pos); 
    43             } 
    44             else  
    45             { 
    46                 return 0; 
    47             } 
    48         } 
    49  
    50         inline void operator () (unsigned int pos) 
    51         { 
    52             if (_indices) pos = index(pos); 
    53  
    54             switch(_verticesType) 
    55             { 
    56             case(Array::Vec3ArrayType):  
    57                 apply(static_cast<const Vec3*>(_vertices->getDataPointer())[pos]); 
    58                 break; 
    59             case(Array::Vec2ArrayType):  
    60                 apply(static_cast<const Vec2*>(_vertices->getDataPointer())[pos]); 
    61                 break; 
    62             case(Array::Vec4ArrayType):  
    63                 apply(static_cast<const Vec4*>(_vertices->getDataPointer())[pos]); 
    64                 break; 
    65             case(Array::Vec3dArrayType):  
    66                 apply(static_cast<const Vec3d*>(_vertices->getDataPointer())[pos]); 
    67                 break; 
    68             case(Array::Vec2dArrayType):  
    69                 apply(static_cast<const Vec2d*>(_vertices->getDataPointer())[pos]); 
    70                 break; 
    71             case(Array::Vec4dArrayType):  
    72                 apply(static_cast<const Vec4d*>(_vertices->getDataPointer())[pos]); 
    73                 break; 
    74             default: 
    75                 break; 
    76             } 
    77              
    78         } 
    79          
    80         inline void apply(const Vec2& v)   { glVertex2fv(v.ptr()); } 
    81         inline void apply(const Vec3& v)   { glVertex3fv(v.ptr()); } 
    82         inline void apply(const Vec4& v)   { glVertex4fv(v.ptr()); } 
    83         inline void apply(const Vec2d& v)   { glVertex2dv(v.ptr()); } 
    84         inline void apply(const Vec3d& v)   { glVertex3dv(v.ptr()); } 
    85         inline void apply(const Vec4d& v)   { glVertex4dv(v.ptr()); } 
    86  
    87         const Array*        _vertices; 
    88         const IndexArray*   _indices; 
    89         Array::Type         _verticesType; 
    90         Array::Type         _indicesType; 
    91 }; 
    92  
    93 class DrawNormal 
    94 { 
    95     public: 
    96      
    97         DrawNormal(const Array* normals,const IndexArray* indices): 
    98             _normals(normals), 
    99             _indices(indices)  
    100         { 
    101             _normalsType = normals?normals->getType():Array::ArrayType; 
    102         } 
    103      
    104         void operator () (unsigned int pos) 
    105         { 
    106             switch(_normalsType) 
    107             { 
    108                 case (Array::Vec3ArrayType): 
    109                     { 
    110                         const Vec3* normals(static_cast<const Vec3*>(_normals->getDataPointer())); 
    111                         if (_indices) glNormal3fv(normals[_indices->index(pos)].ptr()); 
    112                         else glNormal3fv(normals[pos].ptr()); 
    113                     } 
    114                     break; 
    115                 case (Array::Vec3sArrayType): 
    116                     { 
    117                         const Vec3s* normals(static_cast<const Vec3s*>(_normals->getDataPointer())); 
    118                         if (_indices) glNormal3sv(normals[_indices->index(pos)].ptr()); 
    119                         else glNormal3sv(normals[pos].ptr()); 
    120                     } 
    121                     break; 
    122                 case (Array::Vec4sArrayType): 
    123                     { 
    124                         const Vec4s* normals(static_cast<const Vec4s*>(_normals->getDataPointer())); 
    125                         if (_indices) glNormal3sv(normals[_indices->index(pos)].ptr()); 
    126                         else glNormal3sv(normals[pos].ptr()); 
    127                     } 
    128                     break; 
    129                 case (Array::Vec3bArrayType): 
    130                     { 
    131                         const Vec3b* normals(static_cast<const Vec3b*>(_normals->getDataPointer())); 
    132                         if (_indices) glNormal3bv((const GLbyte*)normals[_indices->index(pos)].ptr()); 
    133                         else glNormal3bv((const GLbyte*)normals[pos].ptr()); 
    134                     } 
    135                     break; 
    136                 case (Array::Vec4bArrayType): 
    137                     { 
    138                         const Vec4b* normals(static_cast<const Vec4b*>(_normals->getDataPointer())); 
    139                         if (_indices) glNormal3bv((const GLbyte*)normals[_indices->index(pos)].ptr()); 
    140                         else glNormal3bv((const GLbyte*)normals[pos].ptr()); 
    141                     } 
    142                     break; 
    143                 case (Array::Vec3dArrayType): 
    144                     { 
    145                         const Vec3d* normals(static_cast<const Vec3d*>(_normals->getDataPointer())); 
    146                         if (_indices) glNormal3dv(normals[_indices->index(pos)].ptr()); 
    147                         else glNormal3dv(normals[pos].ptr()); 
    148                     } 
    149                     break; 
    150                 case (Array::Vec4dArrayType): 
    151                     { 
    152                         const Vec4d* normals(static_cast<const Vec4d*>(_normals->getDataPointer())); 
    153                         if (_indices) glNormal3dv(normals[_indices->index(pos)].ptr()); 
    154                         else glNormal3dv(normals[pos].ptr()); 
    155                     } 
    156                     break; 
    157                 default: 
    158                     break; 
    159                      
    160             } 
    161         } 
    162          
    163         const Array*       _normals; 
    164         const IndexArray*  _indices; 
    165         Array::Type        _normalsType; 
    166 }; 
    167  
    168 class DrawColor 
    169 { 
    170     public: 
    171  
    172         DrawColor(const Array* colors,const IndexArray* indices): 
    173             _colors(colors), 
    174             _indices(indices) 
    175         { 
    176             _colorsType = _colors?_colors->getType():Array::ArrayType; 
    177             _indicesType = _indices?_indices->getType():Array::ArrayType; 
    178         } 
    179  
    180         inline unsigned int index(unsigned int pos) 
    181         { 
    182             if (_indices) { 
    183                 return _indices->index(pos); 
    184             } 
    185             else { 
    186                 return 0; 
    187             } 
    188         } 
    189  
    190         inline void operator () (unsigned int pos) 
    191         { 
    192             if (_indices) pos = index(pos); 
    193  
    194             switch(_colorsType) 
    195             { 
    196             case(Array::Vec4ArrayType): 
    197                 apply(static_cast<const Vec4*>(_colors->getDataPointer())[pos]); 
    198                 break; 
    199             case(Array::Vec4ubArrayType): 
    200                 apply(static_cast<const Vec4ub*>(_colors->getDataPointer())[pos]); 
    201                 break; 
    202             case(Array::Vec3ArrayType): 
    203                 apply(static_cast<const Vec3*>(_colors->getDataPointer())[pos]); 
    204                 break; 
    205             case(Array::Vec3dArrayType): 
    206                 apply(static_cast<const Vec3d*>(_colors->getDataPointer())[pos]); 
    207                 break; 
    208             case(Array::Vec4dArrayType): 
    209                 apply(static_cast<const Vec4d*>(_colors->getDataPointer())[pos]); 
    210                 break; 
    211             default: 
    212                 break; 
    213             } 
    214         } 
    215  
    216         inline void apply(const Vec4ub& v) { glColor4ubv(v.ptr()); } 
    217         inline void apply(const Vec3& v)   { glColor3fv(v.ptr()); } 
    218         inline void apply(const Vec4& v)   { glColor4fv(v.ptr()); } 
    219          
    220         const Array*        _colors; 
    221         const IndexArray*   _indices; 
    222         Array::Type         _colorsType; 
    223         Array::Type         _indicesType; 
    224 }; 
    225  
    226 class DrawVertexAttrib : public osg::Referenced, public osg::ConstValueVisitor 
    227 { 
    228 public: 
    229  
    230     DrawVertexAttrib(const Drawable::Extensions * extensions,unsigned int vertAttribIndex,GLboolean normalized,const Array* attribcoords,const IndexArray* indices): 
    231             _vertAttribIndex(vertAttribIndex), 
    232             _normalized(normalized), 
    233             _extensions(extensions), 
    234             _attribcoords(attribcoords), 
    235             _indices(indices), 
    236             _index(0) {;} 
    237              
    238     inline void applyAndIncrement() { operator()(_index++); } 
    239  
    240     inline void operator () (unsigned int pos) 
    241     { 
    242         if (_indices) _attribcoords->accept(_indices->index(pos),*this); 
    243         else _attribcoords->accept(pos,*this); 
    244     } 
    245  
    246     virtual void apply(const GLshort& s)  
    247     { 
    248         _extensions->glVertexAttrib1s( _vertAttribIndex, s ); 
    249     } 
    250     virtual void apply(const GLfloat& f)  
    251     { 
    252         _extensions->glVertexAttrib1f( _vertAttribIndex, f ); 
    253     } 
    254     virtual void apply(const Vec4ub& v)  
    255     { 
    256         if( _normalized ) 
    257         { 
    258             _extensions->glVertexAttrib4Nubv( _vertAttribIndex, v.ptr() ); 
    259         } 
    260         else 
    261         { 
    262             _extensions->glVertexAttrib4ubv( _vertAttribIndex, v.ptr() ); 
    263         } 
    264     } 
    265     virtual void apply(const Vec2& v)  
    266     { 
    267         _extensions->glVertexAttrib2fv( _vertAttribIndex, v.ptr() ); 
    268     } 
    269     virtual void apply(const Vec3& v)  
    270     { 
    271         _extensions->glVertexAttrib3fv( _vertAttribIndex, v.ptr() ); 
    272     } 
    273     virtual void apply(const Vec4& v)  
    274     { 
    275         _extensions->glVertexAttrib4fv( _vertAttribIndex, v.ptr() ); 
    276     } 
    277     virtual void apply(const Vec2d& v)  
    278     { 
    279         _extensions->glVertexAttrib2dv( _vertAttribIndex, v.ptr() ); 
    280     } 
    281     virtual void apply(const Vec3d& v)  
    282     { 
    283         _extensions->glVertexAttrib3dv( _vertAttribIndex, v.ptr() ); 
    284     } 
    285     virtual void apply(const Vec4d& v)  
    286     { 
    287         _extensions->glVertexAttrib4dv( _vertAttribIndex, v.ptr() ); 
    288     } 
    289  
    290     unsigned int                    _vertAttribIndex; 
    291     GLboolean                       _normalized; 
    292     const Drawable::Extensions*     _extensions; 
    293     const Array*                    _attribcoords; 
    294     const IndexArray*               _indices; 
    295     unsigned int                    _index; 
    296 }; 
    297  
    298 class DrawTexCoord : public osg::Referenced, public osg::ConstValueVisitor 
    299 { 
    300     public: 
    301  
    302         DrawTexCoord(const Array* texcoords,const IndexArray* indices): 
    303             _texcoords(texcoords), 
    304             _indices(indices) {} 
    305  
    306         inline void operator () (unsigned int pos) 
    307         { 
    308             if (_indices) _texcoords->accept(_indices->index(pos),*this); 
    309             else _texcoords->accept(pos,*this); 
    310         } 
    311  
    312         virtual void apply(const GLfloat& v){ glTexCoord1f(v); } 
    313         virtual void apply(const Vec2& v)   { glTexCoord2fv(v.ptr()); } 
    314         virtual void apply(const Vec3& v)   { glTexCoord3fv(v.ptr()); } 
    315         virtual void apply(const Vec4& v)   { glTexCoord4fv(v.ptr()); } 
    316  
    317         const Array*        _texcoords; 
    318         const IndexArray*   _indices; 
    319 }; 
    320  
    321 class DrawMultiTexCoord : public osg::Referenced, public osg::ConstValueVisitor 
    322 { 
    323     public: 
    324      
    325         DrawMultiTexCoord(GLenum target,const Array* texcoords,const IndexArray* indices, 
    326             const Drawable::Extensions * extensions): 
    327             _target(target), 
    328             _texcoords(texcoords), 
    329             _indices(indices), 
    330             _extensions(extensions) {} 
    331  
    332         inline void operator () (unsigned int pos) 
    333         { 
    334             if (_indices) _texcoords->accept(_indices->index(pos),*this); 
    335             else _texcoords->accept(pos,*this); 
    336         } 
    337  
    338         virtual void apply(const GLfloat& v){ _extensions->glMultiTexCoord1f(_target,v); } 
    339         virtual void apply(const Vec2& v)   { _extensions->glMultiTexCoord2fv(_target,v.ptr()); } 
    340         virtual void apply(const Vec3& v)   { _extensions->glMultiTexCoord3fv(_target,v.ptr()); } 
    341         virtual void apply(const Vec4& v)   { _extensions->glMultiTexCoord4fv(_target,v.ptr()); } 
    342          
    343         GLenum              _target; 
    344         const Array*        _texcoords; 
    345         const IndexArray*   _indices; 
    346  
    347         const Drawable::Extensions * _extensions; 
    348 }; 
    349  
    350  
    351 class DrawSecondaryColor : public osg::ConstValueVisitor 
    352 { 
    353     public: 
    354      
    355         DrawSecondaryColor(const Array* colors,const IndexArray* indices, 
    356                            const Drawable::Extensions * extensions): 
    357             _colors(colors), 
    358             _indices(indices), 
    359             _extensions(extensions) 
    360             {} 
    361      
    362         inline void operator () (unsigned int pos) 
    363         { 
    364             if (_indices) _colors->accept(_indices->index(pos),*this); 
    365             else _colors->accept(pos,*this); 
    366         } 
    367  
    368         virtual void apply(const Vec4ub& v) { _extensions->glSecondaryColor3ubv(v.ptr()); } 
    369         virtual void apply(const Vec3& v)   { _extensions->glSecondaryColor3fv(v.ptr()); } 
    370         virtual void apply(const Vec4& v)   { _extensions->glSecondaryColor3fv(v.ptr()); } 
    371  
    372         const Array*        _colors; 
    373         const IndexArray*   _indices; 
    374  
    375         const Drawable::Extensions * _extensions; 
    376 }; 
    377  
    378 class DrawFogCoord : public osg::ConstValueVisitor 
    379 { 
    380     public: 
    381      
    382         DrawFogCoord(const Array* fogcoords,const IndexArray* indices,const Drawable::Extensions * extensions): 
    383             _fogcoords(fogcoords), 
    384             _indices(indices), 
    385             _extensions(extensions) {} 
    386      
    387         inline void operator () (unsigned int pos) 
    388         { 
    389             if (_indices) _fogcoords->accept(_indices->index(pos),*this); 
    390             else _fogcoords->accept(pos,*this); 
    391         } 
    392  
    393         virtual void apply(const GLfloat& v) { _extensions->glFogCoordfv(&v); } 
    394  
    395         const Array*        _fogcoords; 
    396         const IndexArray*   _indices; 
    397  
    398         const Drawable::Extensions * _extensions; 
    399 }; 
    400 #endif 
    401  
    402  
    40323Geometry::ArrayData::ArrayData(const ArrayData& data,const CopyOp& copyop): 
    40424    array(copyop(data.array.get())), 
     
    1285905} 
    1286906 
    1287 #ifndef USE_OLD_DRAW_IMPLEMENTATOIN 
    1288907void Geometry::drawImplementation(RenderInfo& renderInfo) const 
    1289908{ 
     
    15421161    } 
    15431162} 
    1544 #else 
    1545 void Geometry::drawImplementation(RenderInfo& renderInfo) const 
    1546 { 
    1547     State& state = *renderInfo.getState(); 
    1548     bool vertexAttribAlias = state.getUseVertexAttributeAliasing(); 
    1549  
    1550  
    1551 //    unsigned int contextID = state.getContextID(); 
    1552      
    1553     // osg::notify(osg::NOTICE)<<"Geometry::drawImplementation"<<std::endl; 
    1554  
    1555     if (_internalOptimizedGeometry.valid()) 
    1556     { 
    1557         _internalOptimizedGeometry->drawImplementation(renderInfo); 
    1558         return; 
    1559     } 
    1560  
    1561     const Extensions* extensions = getExtensions(state.getContextID(),true); 
    1562  
    1563     if( !( ( _vertexData.array.valid() && _vertexData.array->getNumElements() != 0 ) || 
    1564            ( _vertexAttribList.size() > 0 &&  
    1565              _vertexAttribList[0].array.valid() &&  
    1566              _vertexAttribList[0].array->getNumElements() != 0 ) ) ) 
    1567     { 
    1568         return; 
    1569     } 
    1570  
    1571     if( ( _vertexData.indices.valid() && _vertexData.indices->getNumElements() == 0 ) || 
    1572           ( _vertexAttribList.size() > 0 &&  
    1573           _vertexAttribList[0].indices.valid() &&  
    1574           _vertexAttribList[0].indices->getNumElements() == 0 ) ) 
    1575     { 
    1576         return; 
    1577     } 
    1578  
    1579     AttributeBinding normalBinding = _normalData.binding; 
    1580     AttributeBinding colorBinding = _colorData.binding; 
    1581  
    1582     DrawNormal         drawNormal(vertexAttribAlias?0:_normalData.array.get(),vertexAttribAlias?0:_normalData.indices.get()); 
    1583     DrawColor          drawColor(vertexAttribAlias?0:_colorData.array.get(),vertexAttribAlias?0:_colorData.indices.get()); 
    1584     DrawSecondaryColor drawSecondaryColor(vertexAttribAlias?0:_secondaryColorData.array.get(),vertexAttribAlias?0:_secondaryColorData.indices.get(),extensions); 
    1585     DrawFogCoord       drawFogCoord(vertexAttribAlias?0:_fogCoordData.array.get(),vertexAttribAlias?0:_fogCoordData.indices.get(),extensions); 
    1586  
    1587  
    1588     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    1589     // 
    1590     // Set up secondary color if required. 
    1591     // 
    1592     AttributeBinding secondaryColorBinding = _secondaryColorData.binding; 
    1593     if (secondaryColorBinding!=BIND_OFF && !extensions->isSecondaryColorSupported()) 
    1594     { 
    1595         // switch off if not supported or have a valid data. 
    1596         secondaryColorBinding = BIND_OFF; 
    1597     } 
    1598  
    1599      
    1600     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    1601     // 
    1602     // Set up fog coord if required. 
    1603     // 
    1604     AttributeBinding fogCoordBinding = _fogCoordData.binding; 
    1605     if (fogCoordBinding!=BIND_OFF && !extensions->isFogCoordSupported()) 
    1606     { 
    1607         // switch off if not supported or have a valid data. 
    1608         fogCoordBinding = BIND_OFF; 
    1609     } 
    1610  
    1611  
    1612  
    1613     unsigned int normalIndex = 0; 
    1614     unsigned int colorIndex = 0; 
    1615     unsigned int secondaryColorIndex = 0; 
    1616     unsigned int fogCoordIndex = 0; 
    1617  
    1618 #if USE_DEFAULT_NORMAL 
    1619     // if no values are defined for normal and color provide some defaults... 
    1620     if (_normalData.binding==BIND_OFF) glNormal3f(0.0f,0.0f,1.0f); 
    1621 #endif 
    1622  
    1623 #if USE_DEFAULT_COLOUR 
    1624     if (_colorData.binding==BIND_OFF) glColor4f(1.0f,1.0f,1.0f,1.0f); 
    1625 #endif 
    1626  
    1627     typedef std::vector< ref_ptr<DrawVertexAttrib> > DrawVertexAttribList; 
    1628     typedef std::map< Geometry::AttributeBinding, DrawVertexAttribList> DrawVertexAttribMap; 
    1629     DrawVertexAttribMap drawVertexAttribMap; 
    1630      
    1631     bool vertexVertexAttributesSupported = extensions->isVertexProgramSupported(); 
    1632     bool handleVertexAttributes = (vertexAttribAlias || !_vertexAttribList.empty()) && vertexVertexAttributesSupported; 
    1633  
    1634     bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported(); 
    1635  
    1636  
    1637     if (vertexAttribAlias) 
    1638     { 
    1639         if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX) 
    1640         {  
    1641             drawVertexAttribMap[normalBinding].push_back( new DrawVertexAttrib(extensions,2,false,_normalData.array.get(),_normalData.indices.get()) ); 
    1642             normalBinding = BIND_OFF; 
    1643         } 
    1644  
    1645         if (colorBinding!=BIND_OFF && colorBinding!=BIND_PER_VERTEX) 
    1646         { 
    1647             drawVertexAttribMap[colorBinding].push_back( new DrawVertexAttrib(extensions,3,false,_colorData.array.get(),_colorData.indices.get()) ); 
    1648             colorBinding = BIND_OFF; 
    1649         } 
    1650  
    1651         secondaryColorBinding = BIND_OFF; 
    1652         fogCoordBinding = BIND_OFF; 
    1653     } 
    1654  
    1655     // force the use of the slow path code to test the glBegin/glEnd replacement codes. 
    1656     bool forceSlowPath = true; 
    1657  
    1658     if (areFastPathsUsed() && !forceSlowPath) 
    1659     { 
    1660  
    1661 #define USE_LAZY_DISABLING 
    1662  
    1663 #ifdef USE_LAZY_DISABLING 
    1664         state.lazyDisablingOfVertexAttributes(); 
    1665 #endif 
    1666         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    1667         // 
    1668         // fast path.         
    1669         // 
    1670         if (usingVertexBufferObjects) 
    1671         { 
    1672             // osg::notify(osg::NOTICE)<<"Geometry::drawImplementation() Using VertexBufferObjects"<<std::endl; 
    1673  
    1674             if( _vertexData.array.valid() ) 
    1675                 state.setVertexPointer(_vertexData.array.get()); 
    1676 #ifndef USE_LAZY_DISABLING 
    1677             else 
    1678                 state.disableVertexPointer(); 
    1679 #endif 
    1680  
    1681             if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) 
    1682                 state.setNormalPointer(_normalData.array.get()); 
    1683 #ifndef USE_LAZY_DISABLING 
    1684             else 
    1685                 state.disableNormalPointer(); 
    1686 #endif 
    1687  
    1688             if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) 
    1689                 state.setColorPointer(_colorData.array.get()); 
    1690 #ifndef USE_LAZY_DISABLING 
    1691             else 
    1692                 state.disableColorPointer(); 
    1693 #endif 
    1694  
    1695             if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) 
    1696                 state.setSecondaryColorPointer(_secondaryColorData.array.get()); 
    1697 #ifndef USE_LAZY_DISABLING 
    1698             else 
    1699                 state.disableSecondaryColorPointer(); 
    1700 #endif 
    1701  
    1702             if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid()) 
    1703                 state.setFogCoordPointer(_fogCoordData.array.get()); 
    1704 #ifndef USE_LAZY_DISABLING 
    1705             else 
    1706                 state.disableFogCoordPointer(); 
    1707 #endif 
    1708  
    1709             unsigned int unit; 
    1710             for(unit=0;unit<_texCoordList.size();++unit) 
    1711             { 
    1712                 const Array* array = _texCoordList[unit].array.get(); 
    1713                 if (array) 
    1714                     state.setTexCoordPointer(unit,array); 
    1715 #ifndef USE_LAZY_DISABLING 
    1716                 else 
    1717                     state.disableTexCoordPointer(unit); 
    1718 #endif 
    1719             } 
    1720 #ifndef USE_LAZY_DISABLING 
    1721             state.disableTexCoordPointersAboveAndIncluding(unit); 
    1722 #endif 
    1723  
    1724             if( handleVertexAttributes ) 
    1725             { 
    1726                 unsigned int index; 
    1727                 for( index = 0; index < _vertexAttribList.size(); ++index ) 
    1728                 { 
    1729                     const Array* array = _vertexAttribList[index].array.get(); 
    1730                     const AttributeBinding ab = _vertexAttribList[index].binding; 
    1731  
    1732                     if( ab == BIND_PER_VERTEX && array ) 
    1733                     { 
    1734                         state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize ); 
    1735                     } 
    1736                     else 
    1737                     { 
    1738                         if( array ) 
    1739                         { 
    1740                             const IndexArray* indexArray = _vertexAttribList[index].indices.get(); 
    1741  
    1742                             if( indexArray && indexArray->getNumElements() > 0 ) 
    1743                             { 
    1744                                 drawVertexAttribMap[ab].push_back( 
    1745                                     new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,indexArray) ); 
    1746                             } 
    1747                             else 
    1748                             { 
    1749                                 drawVertexAttribMap[ab].push_back( 
    1750                                     new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); 
    1751                             } 
    1752                         } 
    1753  
    1754 #ifndef USE_LAZY_DISABLING 
    1755                         state.disableVertexAttribPointer( index ); 
    1756 #endif 
    1757                     } 
    1758                 } 
    1759 #ifndef USE_LAZY_DISABLING 
    1760                 state.disableVertexAttribPointersAboveAndIncluding( index ); 
    1761 #endif 
    1762             } 
    1763 #ifndef USE_LAZY_DISABLING 
    1764             else if (vertexVertexAttributesSupported) 
    1765             { 
    1766                 state.disableVertexAttribPointersAboveAndIncluding( 0 ); 
    1767             } 
    1768 #endif 
    1769         } 
    1770         else 
    1771         { 
    1772             // osg::notify(osg::NOTICE)<<"none VertexBuffer path"<<std::endl; 
    1773  
    1774             // 
    1775             // Non Vertex Buffer Object path for defining vertex arrays. 
    1776             //             
    1777             if( _vertexData.array.valid() ) 
    1778                 state.setVertexPointer(_vertexData.array->getDataSize(),_vertexData.array->getDataType(),0,_vertexData.array->getDataPointer()); 
    1779 #ifndef USE_LAZY_DISABLING 
    1780             else 
    1781                 state.disableVertexPointer(); 
    1782 #endif 
    1783  
    1784             if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) 
    1785                 state.setNormalPointer(_normalData.array->getDataType(),0,_normalData.array->getDataPointer()); 
    1786 #ifndef USE_LAZY_DISABLING 
    1787             else 
    1788                 state.disableNormalPointer(); 
    1789 #endif 
    1790  
    1791             if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) 
    1792                 state.setColorPointer(_colorData.array->getDataSize(),_colorData.array->getDataType(),0,_colorData.array->getDataPointer()); 
    1793 #ifndef USE_LAZY_DISABLING 
    1794             else 
    1795                 state.disableColorPointer(); 
    1796 #endif 
    1797  
    1798             if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) 
    1799                 state.setSecondaryColorPointer(_secondaryColorData.array->getDataSize(),_secondaryColorData.array->getDataType(),0,_secondaryColorData.array->getDataPointer()); 
    1800 #ifndef USE_LAZY_DISABLING 
    1801             else 
    1802                 state.disableSecondaryColorPointer(); 
    1803 #endif 
    1804  
    1805             if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid()) 
    1806                 state.setFogCoordPointer(GL_FLOAT,0,_fogCoordData.array->getDataPointer()); 
    1807 #ifndef USE_LAZY_DISABLING 
    1808             else 
    1809                 state.disableFogCoordPointer(); 
    1810 #endif 
    1811  
    1812             unsigned int unit; 
    1813             for(unit=0;unit<_texCoordList.size();++unit) 
    1814             { 
    1815                 const Array* array = _texCoordList[unit].array.get(); 
    1816                 if (array) 
    1817                     state.setTexCoordPointer(unit,array->getDataSize(),array->getDataType(),0,array->getDataPointer()); 
    1818 #ifndef USE_LAZY_DISABLING 
    1819                 else 
    1820                     state.disableTexCoordPointer(unit); 
    1821 #endif 
    1822             } 
    1823 #ifndef USE_LAZY_DISABLING 
    1824             state.disableTexCoordPointersAboveAndIncluding(unit); 
    1825 #endif 
    1826  
    1827             if( handleVertexAttributes ) 
    1828             { 
    1829                 unsigned int index; 
    1830                 for( index = 0; index < _vertexAttribList.size(); ++index ) 
    1831                 { 
    1832                     const Array* array = _vertexAttribList[index].array.get(); 
    1833                     const AttributeBinding ab = _vertexAttribList[index].binding; 
    1834  
    1835                     if( ab == BIND_PER_VERTEX && array ) 
    1836                     { 
    1837                         state.setVertexAttribPointer( index, array->getDataSize(), array->getDataType(), 
    1838                             _vertexAttribList[index].normalize, 0, array->getDataPointer() ); 
    1839                     } 
    1840                     else 
    1841                     { 
    1842                         if( array ) 
    1843                         { 
    1844                             const IndexArray* indexArray = _vertexAttribList[index].indices.get(); 
    1845  
    1846                             if( indexArray && indexArray->getNumElements() > 0 ) 
    1847                             { 
    1848                                 drawVertexAttribMap[ab].push_back( 
    1849                                     new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,indexArray) ); 
    1850                             } 
    1851                             else 
    1852                             { 
    1853                                 drawVertexAttribMap[ab].push_back( 
    1854                                     new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); 
    1855                             } 
    1856                         } 
    1857  
    1858 #ifndef USE_LAZY_DISABLING 
    1859                         state.disableVertexAttribPointer( index ); 
    1860 #endif 
    1861                     } 
    1862                 } 
    1863 #ifndef USE_LAZY_DISABLING 
    1864                 state.disableVertexAttribPointersAboveAndIncluding( index ); 
    1865 #endif 
    1866             } 
    1867 #ifndef USE_LAZY_DISABLING 
    1868             else if (vertexVertexAttributesSupported) 
    1869             { 
    1870                 state.disableVertexAttribPointersAboveAndIncluding( 0 ); 
    1871             } 
    1872 #endif 
    1873         } 
    1874  
    1875 #ifdef USE_LAZY_DISABLING 
    1876         state.applyDisablingOfVertexAttributes(); 
    1877 #endif 
    1878  
    1879  
    1880         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    1881         // 
    1882         // pass the overall binding values onto OpenGL. 
    1883         // 
    1884         if (normalBinding==BIND_OVERALL)        drawNormal(normalIndex++); 
    1885         if (colorBinding==BIND_OVERALL)         drawColor(colorIndex++); 
    1886         if (secondaryColorBinding==BIND_OVERALL)    drawSecondaryColor(secondaryColorIndex++); 
    1887         if (fogCoordBinding==BIND_OVERALL)          drawFogCoord(fogCoordIndex++); 
    1888         if (handleVertexAttributes) 
    1889         { 
    1890             DrawVertexAttribList &list = drawVertexAttribMap[BIND_OVERALL]; 
    1891  
    1892             for( unsigned int i = 0; i < list.size(); ++i ) 
    1893             { 
    1894                 list[i]->applyAndIncrement(); 
    1895             } 
    1896         } 
    1897  
    1898         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    1899         // 
    1900         // draw the primitives themselves. 
    1901         // 
    1902         for(PrimitiveSetList::const_iterator itr=_primitives.begin(); 
    1903             itr!=_primitives.end(); 
    1904             ++itr) 
    1905         { 
    1906  
    1907             if (normalBinding==BIND_PER_PRIMITIVE_SET)      drawNormal(normalIndex++); 
    1908             if (colorBinding==BIND_PER_PRIMITIVE_SET)       drawColor(colorIndex++); 
    1909             if (secondaryColorBinding==BIND_PER_PRIMITIVE_SET)    drawSecondaryColor(secondaryColorIndex++); 
    1910             if (fogCoordBinding==BIND_PER_PRIMITIVE_SET)          drawFogCoord(fogCoordIndex++); 
    1911             if (handleVertexAttributes) 
    1912             { 
    1913                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE_SET]; 
    1914  
    1915                 for( unsigned int i = 0; i < list.size(); ++i ) 
    1916                 { 
    1917                     list[i]->applyAndIncrement(); 
    1918                 } 
    1919             } 
    1920  
    1921             (*itr)->draw(state, usingVertexBufferObjects); 
    1922  
    1923         } 
    1924  
    1925         if (usingVertexBufferObjects) 
    1926         { 
    1927 #if 1 
    1928             state.unbindVertexBufferObject(); 
    1929             state.unbindElementBufferObject(); 
    1930 #endif 
    1931         } 
    1932  
    1933     } 
    1934     else 
    1935     {    
    1936  
    1937         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    1938         // 
    1939         // slow path.         
    1940         // 
    1941          
    1942  
    1943         typedef std::vector< ref_ptr<DrawMultiTexCoord> > DrawTexCoordList; 
    1944         DrawTexCoordList drawTexCoordList; 
    1945         drawTexCoordList.reserve(_texCoordList.size()); 
    1946  
    1947         // fallback if multitexturing not supported. 
    1948         ref_ptr<DrawTexCoord> drawTextCoord; 
    1949  
    1950         if (extensions->isMultiTexSupported() && _texCoordList.size()>1) 
    1951         { 
    1952             // multitexture supported.. 
    1953             for(unsigned int unit=0;unit!=_texCoordList.size();++unit) 
    1954             { 
    1955                 const ArrayData& texcoordData = _texCoordList[unit]; 
    1956                 if (texcoordData.array.valid() && texcoordData.array->getNumElements()>0) 
    1957                 { 
    1958                     if (texcoordData.indices.valid() && texcoordData.indices->getNumElements()>0) 
    1959                     { 
    1960                         drawTexCoordList.push_back(new DrawMultiTexCoord(GL_TEXTURE0+unit,texcoordData.array.get(),texcoordData.indices.get(), 
    1961                                                                          extensions)); 
    1962                     } 
    1963                     else 
    1964                     { 
    1965                         drawTexCoordList.push_back(new DrawMultiTexCoord(GL_TEXTURE0+unit,texcoordData.array.get(),0, 
    1966                                                                           extensions)); 
    1967                     } 
    1968                 } 
    1969             } 
    1970         } 
    1971         else 
    1972         { 
    1973             if (!_texCoordList.empty()) 
    1974             { 
    1975                 const ArrayData& texcoordData = _texCoordList[0]; 
    1976                 if (texcoordData.array.valid() && texcoordData.array->getNumElements()>0) 
    1977                 { 
    1978                     if (texcoordData.indices.valid()) 
    1979                     { 
    1980                         if (texcoordData.indices->getNumElements()>0) 
    1981                         { 
    1982                             drawTextCoord = new DrawTexCoord(texcoordData.array.get(),texcoordData.indices.get()); 
    1983                         } 
    1984                     } 
    1985                     else 
    1986                     { 
    1987                         drawTextCoord = new DrawTexCoord(texcoordData.array.get(),0); 
    1988                     } 
    1989                 } 
    1990             } 
    1991         } 
    1992  
    1993         if(handleVertexAttributes) 
    1994         { 
    1995             unsigned int index; 
    1996             for( index = 1; index < _vertexAttribList.size(); ++index ) 
    1997             { 
    1998                 const ArrayData& vertAttribData = _vertexAttribList[index]; 
    1999              
    2000                 if( vertAttribData.array.valid() && vertAttribData.array->getNumElements() > 0 ) 
    2001                 { 
    2002                     if( vertAttribData.indices.valid() && vertAttribData.indices->getNumElements() > 0 ) 
    2003                     { 
    2004                         drawVertexAttribMap[vertAttribData.binding].push_back(  
    2005                             new DrawVertexAttrib(extensions,index,vertAttribData.normalize,vertAttribData.array.get(),vertAttribData.indices.get() )); 
    2006                     } 
    2007                     else 
    2008                     { 
    2009                         drawVertexAttribMap[vertAttribData.binding].push_back(  
    2010                             new DrawVertexAttrib(extensions,index,vertAttribData.normalize,vertAttribData.array.get(),0) ); 
    2011                     }             
    2012                 } 
    2013             } 
    2014         } 
    2015  
    2016         // disable all the vertex arrays in the slow path as we are 
    2017         // sending everything using glVertex etc. 
    2018         state.disableAllVertexArrays(); 
    2019  
    2020  
    2021         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    2022         // 
    2023         // pass the overall binding values onto OpenGL. 
    2024         // 
    2025         if (_normalData.binding==BIND_OVERALL)      drawNormal(normalIndex++); 
    2026         if (_colorData.binding==BIND_OVERALL)       drawColor(colorIndex++); 
    2027         if (secondaryColorBinding==BIND_OVERALL)    drawSecondaryColor(secondaryColorIndex++); 
    2028         if (fogCoordBinding==BIND_OVERALL)          drawFogCoord(fogCoordIndex++); 
    2029         if (handleVertexAttributes) 
    2030         { 
    2031             DrawVertexAttribList &list = drawVertexAttribMap[BIND_OVERALL]; 
    2032  
    2033             for( unsigned int i = 0; i < list.size(); ++i ) 
    2034             { 
    2035                 list[i]->applyAndIncrement(); 
    2036             } 
    2037         } 
    2038  
    2039         // set up vertex functor. 
    2040         DrawVertex drawVertex(_vertexData.array.get(),_vertexData.indices.get()); 
    2041  
    2042         bool useVertexAttrib =  _vertexAttribList.size() > 0 && 
    2043                                 _vertexAttribList[0].array.valid() &&  
    2044                                  _vertexAttribList[0].array->getNumElements()!=0; 
    2045  
    2046         ref_ptr<DrawVertexAttrib> drawVertexAttribZero; 
    2047         if( useVertexAttrib ) 
    2048         { 
    2049             drawVertexAttribZero = new DrawVertexAttrib(extensions,0, 
    2050                 _vertexAttribList[0].normalize,_vertexAttribList[0].array.get(), 
    2051                 _vertexAttribList[0].indices.get());  
    2052         } 
    2053  
    2054         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    2055         // 
    2056         // draw the primitives themselves. 
    2057         // 
    2058         for(PrimitiveSetList::const_iterator itr=_primitives.begin(); 
    2059             itr!=_primitives.end(); 
    2060             ++itr) 
    2061         { 
    2062             if (_normalData.binding==BIND_PER_PRIMITIVE_SET)           drawNormal(normalIndex++); 
    2063             if (_colorData.binding==BIND_PER_PRIMITIVE_SET)            drawColor(colorIndex++); 
    2064             if (secondaryColorBinding==BIND_PER_PRIMITIVE_SET)    drawSecondaryColor(secondaryColorIndex++); 
    2065             if (fogCoordBinding==BIND_PER_PRIMITIVE_SET)          drawFogCoord(fogCoordIndex++); 
    2066             if (handleVertexAttributes) 
    2067             { 
    2068                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE_SET]; 
    2069  
    2070                 for( unsigned int i = 0; i < list.size(); ++i ) 
    2071                 { 
    2072                     list[i]->applyAndIncrement(); 
    2073                 } 
    2074             } 
    2075  
    2076             const PrimitiveSet* primitiveset = itr->get(); 
    2077             GLenum mode=primitiveset->getMode(); 
    2078  
    2079             unsigned int primLength; 
    2080             switch(mode) 
    2081             { 
    2082                 case(GL_POINTS):    primLength=1; break; 
    2083                 case(GL_LINES):     primLength=2; break; 
    2084                 case(GL_TRIANGLES): primLength=3; break; 
    2085                 case(GL_QUADS):     primLength=4; break; 
    2086                 default:            primLength=0; break; // compute later when =0. 
    2087             } 
    2088  
    2089             // draw primitives by the more flexible "slow" path, 
    2090             // sending OpenGL glBegin/glVertex.../glEnd(). 
    2091             switch(primitiveset->getType()) 
    2092             { 
    2093                 case(PrimitiveSet::DrawArraysPrimitiveType): 
    2094                 { 
    2095                     if (primLength==0) primLength=primitiveset->getNumIndices(); 
    2096  
    2097                     const DrawArrays* drawArray = static_cast<const DrawArrays*>(primitiveset); 
    2098                     glBegin(mode); 
    2099  
    2100                     unsigned int primCount=0; 
    2101                     unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount(); 
    2102                     for(unsigned int vindex=drawArray->getFirst(); 
    2103                         vindex<indexEnd; 
    2104                         ++vindex,++primCount) 
    2105                     { 
    2106  
    2107                         if ((primCount%primLength)==0) 
    2108                         { 
    2109                             if (_normalData.binding==BIND_PER_PRIMITIVE)           drawNormal(normalIndex++); 
    2110                             if (_colorData.binding==BIND_PER_PRIMITIVE)            drawColor(colorIndex++); 
    2111                             if (secondaryColorBinding==BIND_PER_PRIMITIVE)    drawSecondaryColor(secondaryColorIndex++); 
    2112                             if (fogCoordBinding==BIND_PER_PRIMITIVE)          drawFogCoord(fogCoordIndex++); 
    2113                             if (handleVertexAttributes) 
    2114                             { 
    2115                                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE]; 
    2116  
    2117                                 for( unsigned int i = 0; i < list.size(); ++i ) 
    2118                                 { 
    2119                                     list[i]->applyAndIncrement(); 
    2120                                 } 
    2121                             }                         
    2122                         } 
    2123  
    2124                         if (_normalData.binding==BIND_PER_VERTEX)           drawNormal(vindex); 
    2125                         if (_colorData.binding==BIND_PER_VERTEX)            drawColor(vindex); 
    2126                         if (secondaryColorBinding==BIND_PER_VERTEX)    drawSecondaryColor(vindex); 
    2127                         if (fogCoordBinding==BIND_PER_VERTEX)          drawFogCoord(vindex); 
    2128                         if (handleVertexAttributes) 
    2129                         { 
    2130                             DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_VERTEX]; 
    2131  
    2132                             for( unsigned int i = 0; i < list.size(); ++i ) 
    2133                             { 
    2134                                 list[i]->applyAndIncrement(); 
    2135                             } 
    2136                         }   
    2137  
    2138                         for(DrawTexCoordList::iterator texItr=drawTexCoordList.begin(); 
    2139                             texItr!=drawTexCoordList.end(); 
    2140                             ++texItr) 
    2141                         { 
    2142                             (*(*texItr))(vindex); 
    2143                         } 
    2144                         if (drawTextCoord.valid()) (*drawTextCoord)(vindex); 
    2145  
    2146                         if( useVertexAttrib ) 
    2147                         { 
    2148                             (*drawVertexAttribZero)(vindex); 
    2149                         } 
    2150                         else 
    2151                         { 
    2152                             drawVertex(vindex); 
    2153                         } 
    2154                     } 
    2155                      
    2156                     glEnd(); 
    2157                     break; 
    2158                 } 
    2159                 case(PrimitiveSet::DrawArrayLengthsPrimitiveType): 
    2160                 { 
    2161  
    2162                     const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset); 
    2163                     unsigned int vindex=drawArrayLengths->getFirst(); 
    2164                     for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); 
    2165                         primItr!=drawArrayLengths->end(); 
    2166                         ++primItr) 
    2167                     { 
    2168                         unsigned int localPrimLength; 
    2169                         if (primLength==0) localPrimLength=*primItr; 
    2170                         else localPrimLength=primLength; 
    2171  
    2172                         glBegin(mode); 
    2173  
    2174                         for(GLsizei primCount=0;primCount<*primItr;++primCount) 
    2175                         { 
    2176                             if ((primCount%localPrimLength)==0) 
    2177                             { 
    2178                                 if (_normalData.binding==BIND_PER_PRIMITIVE)           drawNormal(normalIndex++); 
    2179                                 if (_colorData.binding==BIND_PER_PRIMITIVE)            drawColor(colorIndex++); 
    2180                                 if (secondaryColorBinding==BIND_PER_PRIMITIVE)    drawSecondaryColor(secondaryColorIndex++); 
    2181                                 if (fogCoordBinding==BIND_PER_PRIMITIVE)          drawFogCoord(fogCoordIndex++); 
    2182                                 if (handleVertexAttributes) 
    2183                                 { 
    2184                                     DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE]; 
    2185  
    2186                                     for( unsigned int i = 0; i < list.size(); ++i ) 
    2187                                     { 
    2188                                         list[i]->applyAndIncrement(); 
    2189                                     } 
    2190                                 }   
    2191                             } 
    2192                              
    2193                             if (_normalData.binding==BIND_PER_VERTEX)           drawNormal(vindex); 
    2194                             if (_colorData.binding==BIND_PER_VERTEX)            drawColor(vindex); 
    2195                             if (secondaryColorBinding==BIND_PER_VERTEX)    drawSecondaryColor(vindex); 
    2196                             if (fogCoordBinding==BIND_PER_VERTEX)          drawFogCoord(vindex); 
    2197                             if (handleVertexAttributes) 
    2198                             { 
    2199                                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_VERTEX]; 
    2200  
    2201                                 for( unsigned int i = 0; i < list.size(); ++i ) 
    2202                                 { 
    2203                                     list[i]->applyAndIncrement(); 
    2204                                 } 
    2205                             }   
    2206                             for(DrawTexCoordList::iterator texItr=drawTexCoordList.begin(); 
    2207                                 texItr!=drawTexCoordList.end(); 
    2208                                 ++texItr) 
    2209                             { 
    2210                                 (*(*texItr))(vindex); 
    2211                             } 
    2212                             if (drawTextCoord.valid()) (*drawTextCoord)(vindex); 
    2213  
    2214                             if( useVertexAttrib ) 
    2215                             { 
    2216                                 (*drawVertexAttribZero)(vindex); 
    2217                             } 
    2218                             else 
    2219                             { 
    2220                                 drawVertex(vindex); 
    2221                             } 
    2222  
    2223                             ++vindex; 
    2224                         } 
    2225                          
    2226                         glEnd(); 
    2227  
    2228                     } 
    2229                     break; 
    2230                 } 
    2231                 case(PrimitiveSet::DrawElementsUBytePrimitiveType): 
    2232                 { 
    2233                     if (primLength==0) primLength=primitiveset->getNumIndices(); 
    2234  
    2235                     const DrawElementsUByte* drawElements = static_cast<const DrawElementsUByte*>(primitiveset); 
    2236                     glBegin(mode); 
    2237  
    2238                     unsigned int primCount=0; 
    2239                     for(DrawElementsUByte::const_iterator primItr=drawElements->begin(); 
    2240                         primItr!=drawElements->end(); 
    2241                         ++primCount,++primItr) 
    2242                     { 
    2243  
    2244                         if ((primCount%primLength)==0) 
    2245                         { 
    2246                             if (_normalData.binding==BIND_PER_PRIMITIVE)           drawNormal(normalIndex++); 
    2247                             if (_colorData.binding==BIND_PER_PRIMITIVE)            drawColor(colorIndex++); 
    2248                             if (secondaryColorBinding==BIND_PER_PRIMITIVE)    drawSecondaryColor(secondaryColorIndex++); 
    2249                             if (fogCoordBinding==BIND_PER_PRIMITIVE)          drawFogCoord(fogCoordIndex++); 
    2250                             if (handleVertexAttributes) 
    2251                             { 
    2252                                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE]; 
    2253  
    2254                                 for( unsigned int i = 0; i < list.size(); ++i ) 
    2255                                 { 
    2256                                     list[i]->applyAndIncrement(); 
    2257                                 } 
    2258                             }   
    2259                         } 
    2260                          
    2261                         unsigned int vindex=*primItr; 
    2262  
    2263                         if (_normalData.binding==BIND_PER_VERTEX)           drawNormal(vindex); 
    2264                         if (_colorData.binding==BIND_PER_VERTEX)            drawColor(vindex); 
    2265                         if (secondaryColorBinding==BIND_PER_VERTEX)    drawSecondaryColor(vindex); 
    2266                         if (fogCoordBinding==BIND_PER_VERTEX)          drawFogCoord(vindex); 
    2267                         if ( extensions->isVertexProgramSupported() ) 
    2268                         { 
    2269                             DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_VERTEX]; 
    2270  
    2271                             for( unsigned int i = 0; i < list.size(); ++i ) 
    2272                             { 
    2273                                 list[i]->applyAndIncrement(); 
    2274                             } 
    2275                         }   
    2276  
    2277                         for(DrawTexCoordList::iterator texItr=drawTexCoordList.begin(); 
    2278                             texItr!=drawTexCoordList.end(); 
    2279                             ++texItr) 
    2280                         { 
    2281                             (*(*texItr))(vindex); 
    2282                         } 
    2283                         if (drawTextCoord.valid()) (*drawTextCoord)(vindex); 
    2284  
    2285                         if( useVertexAttrib ) 
    2286                         { 
    2287                             (*drawVertexAttribZero)(vindex); 
    2288                         } 
    2289                         else 
    2290                         { 
    2291                             drawVertex(vindex); 
    2292                         } 
    2293                     } 
    2294  
    2295                     glEnd(); 
    2296                     break; 
    2297                 } 
    2298                 case(PrimitiveSet::DrawElementsUShortPrimitiveType): 
    2299                 { 
    2300                     if (primLength==0) primLength=primitiveset->getNumIndices(); 
    2301  
    2302                     const DrawElementsUShort* drawElements = static_cast<const DrawElementsUShort*>(primitiveset); 
    2303                     glBegin(mode); 
    2304  
    2305                     unsigned int primCount=0; 
    2306                     for(DrawElementsUShort::const_iterator primItr=drawElements->begin(); 
    2307                         primItr!=drawElements->end(); 
    2308                         ++primCount,++primItr) 
    2309                     { 
    2310  
    2311                         if ((primCount%primLength)==0) 
    2312                         { 
    2313                             if (_normalData.binding==BIND_PER_PRIMITIVE)           drawNormal(normalIndex++); 
    2314                             if (_colorData.binding==BIND_PER_PRIMITIVE)            drawColor(colorIndex++); 
    2315                             if (secondaryColorBinding==BIND_PER_PRIMITIVE)    drawSecondaryColor(secondaryColorIndex++); 
    2316                             if (fogCoordBinding==BIND_PER_PRIMITIVE)          drawFogCoord(fogCoordIndex++); 
    2317                             if (handleVertexAttributes) 
    2318                             { 
    2319                                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE]; 
    2320  
    2321                                 for( unsigned int i = 0; i < list.size(); ++i ) 
    2322                                 { 
    2323                                     list[i]->applyAndIncrement(); 
    2324                                 } 
    2325                             }   
    2326                         } 
    2327                          
    2328                         unsigned int vindex=*primItr; 
    2329  
    2330                         if (_normalData.binding==BIND_PER_VERTEX)           drawNormal(vindex); 
    2331                         if (_colorData.binding==BIND_PER_VERTEX)            drawColor(vindex); 
    2332                         if (secondaryColorBinding==BIND_PER_VERTEX)    drawSecondaryColor(vindex); 
    2333                         if (fogCoordBinding==BIND_PER_VERTEX)          drawFogCoord(vindex); 
    2334                         if (handleVertexAttributes) 
    2335                         { 
    2336                             DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_VERTEX]; 
    2337  
    2338                             for( unsigned int i = 0; i < list.size(); ++i ) 
    2339                             { 
    2340                                 list[i]->applyAndIncrement(); 
    2341                             } 
    2342                         }   
    2343  
    2344                         for(DrawTexCoordList::iterator texItr=drawTexCoordList.begin(); 
    2345                             texItr!=drawTexCoordList.end(); 
    2346                             ++texItr) 
    2347                         { 
    2348                             (*(*texItr))(vindex); 
    2349                         } 
    2350                         if (drawTextCoord.valid()) (*drawTextCoord)(vindex); 
    2351  
    2352                         if( useVertexAttrib ) 
    2353                         { 
    2354                             (*drawVertexAttribZero)(vindex); 
    2355                         } 
    2356                         else 
    2357                         { 
    2358                             drawVertex(vindex); 
    2359                         } 
    2360                     } 
    2361  
    2362                     glEnd(); 
    2363                     break; 
    2364                 } 
    2365                 case(PrimitiveSet::DrawElementsUIntPrimitiveType): 
    2366                 { 
    2367                     if (primLength==0) primLength=primitiveset->getNumIndices(); 
    2368  
    2369                     const DrawElementsUInt* drawElements = static_cast<const DrawElementsUInt*>(primitiveset); 
    2370                     glBegin(mode); 
    2371  
    2372                     unsigned int primCount=0; 
    2373                     for(DrawElementsUInt::const_iterator primItr=drawElements->begin(); 
    2374                         primItr!=drawElements->end(); 
    2375                         ++primCount,++primItr) 
    2376                     { 
    2377  
    2378                         if ((primCount%primLength)==0) 
    2379                         { 
    2380                             if (_normalData.binding==BIND_PER_PRIMITIVE)           drawNormal(normalIndex++); 
    2381                             if (_colorData.binding==BIND_PER_PRIMITIVE)            drawColor(colorIndex++); 
    2382                             if (secondaryColorBinding==BIND_PER_PRIMITIVE)    drawSecondaryColor(secondaryColorIndex++); 
    2383                             if (fogCoordBinding==BIND_PER_PRIMITIVE)          drawFogCoord(fogCoordIndex++); 
    2384                             if ( extensions->isVertexProgramSupported() ) 
    2385                             { 
    2386                                 DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_PRIMITIVE]; 
    2387  
    2388                                 for( unsigned int i = 0; i < list.size(); ++i ) 
    2389                                 { 
    2390                                     list[i]->applyAndIncrement(); 
    2391                                 } 
    2392                             }   
    2393                         } 
    2394                          
    2395                         unsigned int vindex=*primItr; 
    2396  
    2397                         if (_normalData.binding==BIND_PER_VERTEX)           drawNormal(vindex); 
    2398                         if (_colorData.binding==BIND_PER_VERTEX)            drawColor(vindex); 
    2399                         if (secondaryColorBinding==BIND_PER_VERTEX)    drawSecondaryColor(vindex); 
    2400                         if (fogCoordBinding==BIND_PER_VERTEX)          drawFogCoord(vindex); 
    2401                         if ( extensions->isVertexProgramSupported() ) 
    2402                         { 
    2403                             DrawVertexAttribList &list = drawVertexAttribMap[BIND_PER_VERTEX]; 
    2404  
    2405                             for( unsigned int i = 0; i < list.size(); ++i ) 
    2406                             { 
    2407                                 list[i]->applyAndIncrement(); 
    2408                             } 
    2409                         }   
    2410  
    2411                         for(DrawTexCoordList::iterator texItr=drawTexCoordList.begin(); 
    2412                             texItr!=drawTexCoordList.end(); 
    2413                             ++texItr) 
    2414                         { 
    2415                             (*(*texItr))(vindex); 
    2416                         } 
    2417                         if (drawTextCoord.valid()) (*drawTextCoord)(vindex); 
    2418  
    2419                         if( useVertexAttrib ) 
    2420                         { 
    2421                             (*drawVertexAttribZero)(vindex); 
    2422                         } 
    2423                         else 
    2424                         { 
    2425                             drawVertex(vindex); 
    2426                         } 
    2427                     } 
    2428  
    2429                     glEnd(); 
    2430                     break; 
    2431                 } 
    2432                 default: 
    2433                 { 
    2434                     break; 
    2435                 } 
    2436             } 
    2437         } 
    2438     } 
    2439  
    2440 } 
    2441 #endif 
    24421163 
    24431164class AttributeFunctorArrayVisitor : public ArrayVisitor 
     
    30641785 
    30651786        // draw primitives by the more flexible "slow" path, 
    3066         // sending OpenGL glBegin/glVertex.../glEnd(). 
     1787        // sending OpenGL Begin/glVertex.../End(). 
    30671788        switch(primitiveset->getType()) 
    30681789        { 
     
    36842405 
    36852406    geom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,4)); 
    3686      
     2407 
    36872408    return geom; 
    36882409} 
    3689  
    3690  
    3691  
    3692  
    3693 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3694 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3695 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3696 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3697 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3698 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3699 /////////////////////////////////////////////////////////////////////////////////////////////// 
    3700  
    3701  
    3702 // experimental templated rendering code, please ignore... 
    3703 // will move to osg::Geometry once complete. 
    3704 // Robert Osfield, August 2003. 
    3705 #if 0 
    3706  
    3707     struct DrawAttributeArrays  
    3708     { 
    3709         virtual bool valid() const = 0; 
    3710         virtual void set(osg::Geometry* geometry) = 0; 
    3711         virtual unsigned int draw(unsigned int index, unsigned int count) const = 0; 
    3712     }; 
    3713  
    3714     struct V3 
    3715     { 
    3716         V3():_array(0) {} 
    3717  
    3718         bool valid() const { return _array!=0; } 
    3719  
    3720         void set(osg::Geometry* geometry) 
    3721         { 
    3722             _array = 0; 
    3723             osg::Array* array = geometry->getVertexArray(); 
    3724             if (array && array->getType()==osg::Array::Vec3ArrayType) 
    3725             { 
    3726                 osg::Vec3Array* vec3array = static_cast<osg::Vec3Array*>(array); 
    3727                 if (!vec3array->empty()) _array = &(vec3array->front()); 
    3728             } 
    3729         } 
    3730  
    3731         inline void draw(unsigned int index) const 
    3732         { 
    3733             glVertex3fv(_array[index].ptr()); 
    3734         } 
    3735  
    3736         osg::Vec3* _array; 
    3737     }; 
    3738  
    3739     struct V3USI 
    3740     { 
    3741         V3USI():_array(0),_indices(0) {} 
    3742  
    3743         bool valid() const { return _array!=0 && _indices!=0; } 
    3744  
    3745         void set(osg::Geometry* geometry) 
    3746         { 
    3747             _array = 0; 
    3748             osg::Array* array = geometry->getVertexArray(); 
    3749             if (array && array->getType()==osg::Array::Vec3ArrayType) 
    3750             { 
    3751                 osg::Vec3Array* vec3array = static_cast<osg::Vec3Array*>(array); 
    3752                 if (!vec3array->empty()) _array = &(vec3array->front()); 
    3753             } 
    3754  
    3755             _indices = 0; 
    3756             osg::IndexArray* indices = geometry->getVertexIndices(); 
    3757             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    3758             { 
    3759                 osg::UShortArray* ushort3array = static_cast<osg::UShortArray*>(array); 
    3760                 if (!ushort3array->empty()) _indices = &(ushort3array->front()); 
    3761             } 
    3762         } 
    3763  
    3764         inline void draw(unsigned int index) const 
    3765         { 
    3766             glVertex3fv(_array[_indices[index]].ptr()); 
    3767         } 
    3768  
    3769         osg::Vec3*      _array; 
    3770         unsigned short* _indices; 
    3771     }; 
    3772  
    3773     ////////////////////////////// 
    3774  
    3775     struct N3 
    3776     { 
    3777         N3():_array(0) {} 
    3778  
    3779         bool valid() const { return _array!=0; } 
    3780  
    3781         void set(osg::Geometry* geometry) 
    3782         { 
    3783             _array = 0; 
    3784             osg::Array* array = geometry->getVertexArray(); 
    3785             if (array && array->getType()==osg::Array::Vec3ArrayType) 
    3786             { 
    3787                 osg::Vec3Array* vec3array = static_cast<osg::Vec3Array*>(array); 
    3788                 if (!vec3array->empty()) _array = &(vec3array->front()); 
    3789             } 
    3790         } 
    3791  
    3792         inline void draw(unsigned int index) const 
    3793         { 
    3794             glNormal3fv(_array[index].ptr()); 
    3795         } 
    3796  
    3797         osg::Vec3* _array; 
    3798     }; 
    3799  
    3800     struct N3USI 
    3801     { 
    3802         N3USI():_array(0),_indices(0) {} 
    3803  
    3804         bool valid() const { return _array!=0 && _indices!=0; } 
    3805  
    3806         void set(osg::Geometry* geometry) 
    3807         { 
    3808             _array = 0; 
    3809             osg::Array* array = geometry->getVertexArray(); 
    3810             if (array && array->getType()==osg::Array::Vec3ArrayType) 
    3811             { 
    3812                 osg::Vec3Array* vec3array = static_cast<osg::Vec3Array*>(array); 
    3813                 if (!vec3array->empty()) _array = &(vec3array->front()); 
    3814             } 
    3815  
    3816             _indices = 0; 
    3817             osg::IndexArray* indices = geometry->getVertexIndices(); 
    3818             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    3819             { 
    3820                 osg::UShortArray* ushortarray = static_cast<osg::UShortArray*>(array); 
    3821                 if (!ushortarray->empty()) _indices = &(ushortarray->front()); 
    3822             } 
    3823         } 
    3824  
    3825         inline void draw(unsigned int index) const 
    3826         { 
    3827             glNormal3fv(_array[_indices[index]].ptr()); 
    3828         } 
    3829  
    3830         osg::Vec3*      _array; 
    3831         unsigned short* _indices; 
    3832     }; 
    3833  
    3834     ////////////////////////////// 
    3835  
    3836     struct C4 
    3837     { 
    3838         C4():_array(0) {} 
    3839  
    3840         bool valid() const { return _array!=0; } 
    3841  
    3842         void set(osg::Geometry* geometry) 
    3843         { 
    3844             _array = 0; 
    3845             osg::Array* array = geometry->getColorArray(); 
    3846             if (array && array->getType()==osg::Array::Vec4ArrayType) 
    3847             { 
    3848                 osg::Vec4Array* vec4array = static_cast<osg::Vec4Array*>(array); 
    3849                 if (!vec4array->empty()) _array = &(vec4array->front()); 
    3850             } 
    3851         } 
    3852  
    3853         inline void draw(unsigned int index) const 
    3854         { 
    3855             glVertex3fv(_array[index].ptr()); 
    3856         } 
    3857  
    3858         osg::Vec4* _array; 
    3859     }; 
    3860  
    3861     struct C4USI 
    3862     { 
    3863         C4USI():_array(0),_indices(0) {} 
    3864  
    3865         bool valid() const { return _array!=0 && _indices!=0; } 
    3866  
    3867         void set(osg::Geometry* geometry) 
    3868         { 
    3869             _array = 0; 
    3870             osg::Array* array = geometry->getColorArray(); 
    3871             if (array && array->getType()==osg::Array::Vec4ArrayType) 
    3872             { 
    3873                 osg::Vec4Array* vec4array = static_cast<osg::Vec4Array*>(array); 
    3874                 if (!vec4array->empty()) _array = &(vec4array->front()); 
    3875             } 
    3876  
    3877             _indices = 0; 
    3878             osg::IndexArray* indices = geometry->getColorIndices(); 
    3879             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    3880             { 
    3881                 osg::UShortArray* ushortarray = static_cast<osg::UShortArray*>(array); 
    3882                 if (!ushortarray->empty()) _indices = &(ushortarray->front()); 
    3883             } 
    3884         } 
    3885  
    3886         inline void draw(unsigned int index) const 
    3887         { 
    3888             glColor4fv(_array[_indices[index]].ptr()); 
    3889         } 
    3890  
    3891         osg::Vec4*      _array; 
    3892         unsigned short* _indices; 
    3893     }; 
    3894  
    3895     ////////////////////////////// 
    3896  
    3897     struct T2 
    3898     { 
    3899         T2():_array(0) {} 
    3900  
    3901         bool valid() const { return _array!=0; } 
    3902  
    3903         void set(osg::Geometry* geometry) 
    3904         { 
    3905             _array = 0; 
    3906             osg::Array* array = geometry->getTexCoordArray(0); 
    3907             if (array && array->getType()==osg::Array::Vec2ArrayType) 
    3908             { 
    3909                 osg::Vec2Array* vec2array = static_cast<osg::Vec2Array*>(array); 
    3910                 if (!vec2array->empty()) _array = &(vec2array->front()); 
    3911             } 
    3912         } 
    3913  
    3914         inline void draw(unsigned int index) const 
    3915         { 
    3916             glTexCoord2fv(_array[index].ptr()); 
    3917         } 
    3918  
    3919         osg::Vec2* _array; 
    3920     }; 
    3921  
    3922     struct T2USI 
    3923     { 
    3924         T2USI():_array(0),_indices(0) {} 
    3925  
    3926         bool valid() const { return _array!=0 && _indices!=0; } 
    3927  
    3928         void set(osg::Geometry* geometry) 
    3929         { 
    3930             _array = 0; 
    3931             osg::Array* array = geometry->getTexCoordArray(0); 
    3932             if (array && array->getType()==osg::Array::Vec2ArrayType) 
    3933             { 
    3934                 osg::Vec2Array* vec2array = static_cast<osg::Vec2Array*>(array); 
    3935                 if (!vec2array->empty()) _array = &(vec2array->front()); 
    3936             } 
    3937  
    3938             _indices = 0; 
    3939             osg::IndexArray* indices = geometry->getTexCoordIndices(0); 
    3940             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    3941             { 
    3942                 osg::UShortArray* ushortarray = static_cast<osg::UShortArray*>(array); 
    3943                 if (!ushortarray->empty()) _indices = &(ushortarray->front()); 
    3944             } 
    3945         } 
    3946  
    3947         inline void draw(unsigned int index) const 
    3948         { 
    3949             glTexCoord2fv(_array[_indices[index]].ptr()); 
    3950         } 
    3951  
    3952         osg::Vec2*      _array; 
    3953         unsigned short* _indices; 
    3954     }; 
    3955  
    3956  
    3957     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    3958  
    3959     template < class T1 > 
    3960     struct DrawAttributeArrays_T : public DrawAttributeArrays 
    3961     { 
    3962         DrawAttributeArrays_T(osg::Geometry* geometry) 
    3963         { 
    3964  
    3965         } 
    3966  
    3967         virtual bool valid() const { return _t1.valid(); } 
    3968  
    3969         virtual void set(osg::Geometry* geometry) 
    3970         { 
    3971             _t1.set(geometry); 
    3972         } 
    3973  
    3974         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    3975         { 
    3976             for(unsigned int i=0;i<count;++i,++index) 
    3977             { 
    3978                 _t1.draw(index); 
    3979             } 
    3980             return index; 
    3981         } 
    3982  
    3983         T1 _t1; 
    3984     }; 
    3985  
    3986     template < class T1, class T2 > 
    3987     struct DrawAttributeArrays_TT : public DrawAttributeArrays 
    3988     { 
    3989         DrawAttributeArrays_TT() 
    3990         { 
    3991         } 
    3992  
    3993         virtual bool valid() const { return _t1.valid() && _t2.valid(); } 
    3994  
    3995         virtual void set(osg::Geometry* geometry) 
    3996         { 
    3997             _t1.set(geometry); 
    3998             _t2.set(geometry); 
    3999         } 
    4000  
    4001         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    4002         { 
    4003             for(unsigned int i=0;i<count;++i,++index) 
    4004             { 
    4005                 _t1.draw(index); 
    4006                 _t2.draw(index); 
    4007             } 
    4008             return index; 
    4009         } 
    4010  
    4011         T1 _t1; 
    4012         T1 _t2; 
    4013     }; 
    4014  
    4015     template < class T1, class T2, class T3 > 
    4016     struct DrawAttributeArrays_TTT : public DrawAttributeArrays 
    4017     { 
    4018         DrawAttributeArrays_TTT() 
    4019         { 
    4020         } 
    4021  
    4022         virtual bool valid() const { return _t1.valid() && _t2.valid() && _t3.valid(); } 
    4023  
    4024         virtual void set(osg::Geometry* geometry) 
    4025         { 
    4026             _t1.set(geometry); 
    4027             _t2.set(geometry); 
    4028             _t3.set(geometry); 
    4029         } 
    4030  
    4031         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    4032         { 
    4033             for(unsigned int i=0;i<count;++i,++index) 
    4034             { 
    4035                 _t1.draw(index); 
    4036                 _t2.draw(index); 
    4037                 _t3.draw(index); 
    4038             } 
    4039             return index; 
    4040         } 
    4041  
    4042         T1 _t1; 
    4043         T2 _t2; 
    4044         T3 _t3; 
    4045     }; 
    4046  
    4047     template < class T1, class T2, class T3, class T4 > 
    4048     struct DrawAttributeArrays_TTTT : public DrawAttributeArrays 
    4049     { 
    4050         DrawAttributeArrays_TTTT() 
    4051         { 
    4052         } 
    4053  
    4054         virtual bool valid() const { return _t1.valid() && _t2.valid() && _t3.valid() && _t4.valid(); } 
    4055  
    4056         virtual void set(osg::Geometry* geometry) 
    4057         { 
    4058             _t1.set(geometry); 
    4059             _t2.set(geometry); 
    4060             _t3.set(geometry); 
    4061             _t4.set(geometry); 
    4062         } 
    4063  
    4064         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    4065         { 
    4066             for(unsigned int i=0;i<count;++i,++index) 
    4067             { 
    4068                 _t1.draw(index); 
    4069                 _t2.draw(index); 
    4070                 _t3.draw(index); 
    4071                 _t4.draw(index); 
    4072             } 
    4073             return index; 
    4074         } 
    4075  
    4076         T1 _t1; 
    4077         T2 _t2; 
    4078         T3 _t3; 
    4079         T4 _t4; 
    4080     }; 
    4081  
    4082     template < class T1, class T2 > 
    4083     struct DrawAttributeArrays_TT_USI : public DrawAttributeArrays 
    4084     { 
    4085         DrawAttributeArrays_TT_USI() 
    4086         { 
    4087         } 
    4088  
    4089         virtual bool valid() const { return _t1.valid() && _t2.valid() && _indices!=0; } 
    4090  
    4091         virtual void set(osg::Geometry* geometry) 
    4092         { 
    4093             _t1.set(geometry); 
    4094             _t2.set(geometry); 
    4095  
    4096             _indices = 0; 
    4097             osg::IndexArray* indices = geometry->getVertexIndices(); 
    4098             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    4099             { 
    4100                 osg::UShortArray* ushort3array = static_cast<osg::UShortArray*>(array); 
    4101                 if (!ushort3array->empty()) _indices = &(ushort3array->front()); 
    4102             } 
    4103         } 
    4104  
    4105         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    4106         { 
    4107             for(unsigned int i=0;i<count;++i,++index) 
    4108             { 
    4109                 unsigned int ivalue = _indices[index]; 
    4110                 _t1.draw(ivalue); 
    4111                 _t2.draw(ivalue); 
    4112             } 
    4113             return index; 
    4114         } 
    4115  
    4116         T1 _t1; 
    4117         T2 _t2; 
    4118     }; 
    4119  
    4120     template < class T1, class T2, class T3 > 
    4121     struct DrawAttributeArrays_TTT_USI : public DrawAttributeArrays 
    4122     { 
    4123         DrawAttributeArrays_TTT_USI() 
    4124         { 
    4125         } 
    4126  
    4127         virtual bool valid() const { return _t1.valid() && _t2.valid() && _t3.valid() && _indices!=0; } 
    4128  
    4129         virtual void set(osg::Geometry* geometry) 
    4130         { 
    4131             _t1.set(geometry); 
    4132             _t2.set(geometry); 
    4133             _t3.set(geometry); 
    4134  
    4135             _indices = 0; 
    4136             osg::IndexArray* indices = geometry->getVertexIndices(); 
    4137             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    4138             { 
    4139                 osg::UShortArray* ushort3array = static_cast<osg::UShortArray*>(array); 
    4140                 if (!ushort3array->empty()) _indices = &(ushort3array->front()); 
    4141             } 
    4142         } 
    4143  
    4144         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    4145         { 
    4146             for(unsigned int i=0;i<count;++i,++index) 
    4147             { 
    4148                 unsigned int ivalue = _indices[index]; 
    4149                 _t1.draw(ivalue); 
    4150                 _t2.draw(ivalue); 
    4151                 _t3.draw(ivalue); 
    4152             } 
    4153             return index; 
    4154         } 
    4155  
    4156         T1 _t1; 
    4157         T2 _t2; 
    4158         T3 _t3; 
    4159     }; 
    4160  
    4161     template < class T1, class T2, class T3, class T4 > 
    4162     struct DrawAttributeArrays_TTTT_USI : public DrawAttributeArrays 
    4163     { 
    4164         DrawAttributeArrays_TTTT_USI() 
    4165         { 
    4166         } 
    4167  
    4168         virtual bool valid() const { return _t1.valid() && _t2.valid() && _t3.valid() && _t4.valid() && _indices!=0; } 
    4169  
    4170         virtual void set(osg::Geometry* geometry) 
    4171         { 
    4172             _t1.set(geometry); 
    4173             _t2.set(geometry); 
    4174             _t3.set(geometry); 
    4175             _t4.set(geometry); 
    4176  
    4177             _indices = 0; 
    4178             osg::IndexArray* indices = geometry->getVertexIndices(); 
    4179             if (indices && indices->getType()==osg::Array::UShortArrayType) 
    4180             { 
    4181                 osg::UShortArray* ushort3array = static_cast<osg::UShortArray*>(array); 
    4182                 if (!ushort3array->empty()) _indices = &(ushort3array->front()); 
    4183             } 
    4184         } 
    4185  
    4186         virtual unsigned int draw(unsigned int index, unsigned int count) const 
    4187         { 
    4188             for(unsigned int i=0;i<count;++i,++index) 
    4189             { 
    4190                 unsigned int ivalue = _indices[index]; 
    4191                 _t1.draw(ivalue); 
    4192                 _t2.draw(ivalue); 
    4193                 _t3.draw(ivalue); 
    4194                 _t4.draw(ivalue); 
    4195             } 
    4196             return index; 
    4197         } 
    4198  
    4199         T1 _t1; 
    4200         T2 _t2; 
    4201         T3 _t3; 
    4202         T4 _t4; 
    4203     }; 
    4204  
    4205     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    4206  
    4207  
    4208     // One attribute x 2 
    4209  
    4210     typedef DrawAttributeArrays_T<V3>                    DrawAttributeArrays_V3; 
    4211     typedef DrawAttributeArrays_T<V3USI>                 DrawAttributeArrays_V3i; 
    4212  
    4213     // Two attributes x 15 
    4214  
    4215     typedef DrawAttributeArrays_TT<N3,V3>                DrawAttributeArrays_N3V3; 
    4216     typedef DrawAttributeArrays_TT<N3USI,V3>             DrawAttributeArrays_N3iV3; 
    4217     typedef DrawAttributeArrays_TT<N3,V3USI>             DrawAttributeArrays_N3V3i; 
    4218     typedef DrawAttributeArrays_TT<N3USI,V3USI>          DrawAttributeArrays_N3iV3i; 
    4219  
    4220     typedef DrawAttributeArrays_TT_USI<N3,V3>            DrawAttributeArrays_N3V3_i; 
    4221  
    4222     typedef DrawAttributeArrays_TT<C4,V3>                DrawAttributeArrays_C4V3; 
    4223     typedef DrawAttributeArrays_TT<C4USI,V3>             DrawAttributeArrays_C4iV3; 
    4224     typedef DrawAttributeArrays_TT<C4,V3USI>             DrawAttributeArrays_C4V3i; 
    4225     typedef DrawAttributeArrays_TT<C4USI,V3USI>          DrawAttributeArrays_C4iV3i; 
    4226  
    4227     typedef DrawAttributeArrays_TT_USI<C4,V3>            DrawAttributeArrays_C4V3_i; 
    4228  
    4229     typedef DrawAttributeArrays_TT<T2,V3>                DrawAttributeArrays_T2V3; 
    4230     typedef DrawAttributeArrays_TT<T2USI,V3>             DrawAttributeArrays_T2iV3; 
    4231     typedef DrawAttributeArrays_TT<T2,V3USI>             DrawAttributeArrays_T2V3i; 
    4232     typedef DrawAttributeArrays_TT<T2USI,V3USI>          DrawAttributeArrays_T2iV3i; 
    4233  
    4234     typedef DrawAttributeArrays_TT_USI<T2,V3>            DrawAttributeArrays_T2V3_i; 
    4235  
    4236     // Three attributes x 27 
    4237  
    4238     typedef DrawAttributeArrays_TTT<C4,N3,V3>            DrawAttributeArrays_C4N3V3; 
    4239     typedef DrawAttributeArrays_TTT<C4USI,N3,V3>         DrawAttributeArrays_C4iN3V3; 
    4240     typedef DrawAttributeArrays_TTT<C4,N3USI,V3>         DrawAttributeArrays_C4N3iV3; 
    4241     typedef DrawAttributeArrays_TTT<C4USI,N3USI,V3>      DrawAttributeArrays_C4iN3iV3; 
    4242  
    4243     typedef DrawAttributeArrays_TTT<C4,N3,V3USI>         DrawAttributeArrays_C4N3V3i; 
    4244     typedef DrawAttributeArrays_TTT<C4USI,N3,V3USI>      DrawAttributeArrays_C4iN3V3i; 
    4245     typedef DrawAttributeArrays_TTT<C4,N3USI,V3USI>      DrawAttributeArrays_C4N3iV3i; 
    4246     typedef DrawAttributeArrays_TTT<C4USI,N3USI,V3USI>   DrawAttributeArrays_C4iN3iV3i; 
    4247  
    4248     typedef DrawAttributeArrays_TTT_USI<C4,N3,V3>        DrawAttributeArrays_C4N3V3_i; 
    4249  
    4250  
    4251     typedef DrawAttributeArrays_TTT<T2,N3,V3>            DrawAttributeArrays_T2N3V3; 
    4252     typedef DrawAttributeArrays_TTT<T2USI,N3,V3>         DrawAttributeArrays_T2iN3V3; 
    4253     typedef DrawAttributeArrays_TTT<T2,N3USI,V3>         DrawAttributeArrays_T2iN3iV3; 
    4254     typedef DrawAttributeArrays_TTT<T2USI,N3USI,V3>      DrawAttributeArrays_T2N3iV3; 
    4255  
    4256     typedef DrawAttributeArrays_TTT<T2,N3,V3USI>         DrawAttributeArrays_T2N3V3i; 
    4257     typedef DrawAttributeArrays_TTT<T2USI,N3,V3USI>      DrawAttributeArrays_T2iN3V3i; 
    4258     typedef DrawAttributeArrays_TTT<T2,N3USI,V3USI>      DrawAttributeArrays_T2iN3iV3i; 
    4259     typedef DrawAttributeArrays_TTT<T2USI,N3USI,V3USI>   DrawAttributeArrays_T2N3iV3i; 
    4260  
    4261     typedef DrawAttributeArrays_TTT_USI<T2,N3,V3>        DrawAttributeArrays_T2N3V3_i; 
    4262  
    4263  
    4264  
    4265     typedef DrawAttributeArrays_TTT<T2,C4,V3>            DrawAttributeArrays_T2C4V3; 
    4266     typedef DrawAttributeArrays_TTT<T2USI,C4,V3>         DrawAttributeArrays_T2iC4V3; 
    4267     typedef DrawAttributeArrays_TTT<T2,C4USI,V3>         DrawAttributeArrays_T2C4iV3; 
    4268     typedef DrawAttributeArrays_TTT<T2USI,C4USI,V3>      DrawAttributeArrays_T2iC4iV3; 
    4269  
    4270     typedef DrawAttributeArrays_TTT<T2,C4,V3USI>         DrawAttributeArrays_T2C4V3i; 
    4271     typedef DrawAttributeArrays_TTT<T2USI,C4,V3USI>      DrawAttributeArrays_T2iC4V3i; 
    4272     typedef DrawAttributeArrays_TTT<T2,C4USI,V3USI>      DrawAttributeArrays_T2C4iV3i; 
    4273     typedef DrawAttributeArrays_TTT<T2USI,C4USI,V3USI>   DrawAttributeArrays_T2iC4iV3i; 
    4274  
    4275     typedef DrawAttributeArrays_TTT_USI<T2,C4,V3>        DrawAttributeArrays_T2C4V3_t; 
    4276  
    4277  
    4278     // Four attributes x 17 
    4279  
    4280     typedef DrawAttributeArrays_TTTT<T2,C4,N3,V3>                DrawAttributeArrays_T2C4N3V3; 
    4281     typedef DrawAttributeArrays_TTTT<T2USI,C4,N3,V3>             DrawAttributeArrays_T2iC4N3V3; 
    4282     typedef DrawAttributeArrays_TTTT<T2,C4USI,N3,V3>             DrawAttributeArrays_T2C4iN3V3; 
    4283     typedef DrawAttributeArrays_TTTT<T2USI,C4USI,N3,V3>          DrawAttributeArrays_T2iC4iN3V3; 
    4284  
    4285     typedef DrawAttributeArrays_TTTT<T2,C4,N3USI,V3>             DrawAttributeArrays_T2C4N3iV3; 
    4286     typedef DrawAttributeArrays_TTTT<T2USI,C4,N3USI,V3>          DrawAttributeArrays_T2iC4N3iV3; 
    4287     typedef DrawAttributeArrays_TTTT<T2,C4USI,N3USI,V3>           DrawAttributeArrays_T2C4iN3iV3; 
    4288     typedef DrawAttributeArrays_TTTT<T2USI,C4USI,N3USI,V3>       DrawAttributeArrays_T2iC4iN3iV3; 
    4289  
    4290     typedef DrawAttributeArrays_TTTT<T2,C4,N3,V3USI>             DrawAttributeArrays_T2C4N3V3i; 
    4291     typedef DrawAttributeArrays_TTTT<T2USI,C4,N3,V3USI>          DrawAttributeArrays_T2iC4N3V3i; 
    4292     typedef DrawAttributeArrays_TTTT<T2,C4USI,N3,V3USI>          DrawAttributeArrays_T2C4iN3V3i; 
    4293     typedef DrawAttributeArrays_TTTT<T2USI,C4USI,N3,V3USI>       DrawAttributeArrays_T2iC4iN3V3i; 
    4294  
    4295     typedef DrawAttributeArrays_TTTT<T2,C4,N3USI,V3USI>          DrawAttributeArrays_T2C4N3iV3i; 
    4296     typedef DrawAttributeArrays_TTTT<T2USI,C4,N3USI,V3USI>       DrawAttributeArrays_T2iC4N3iV3i; 
    4297     typedef DrawAttributeArrays_TTTT<T2,C4USI,N3USI,V3USI>       DrawAttributeArrays_T2C4iN3iV3i; 
    4298     typedef DrawAttributeArrays_TTTT<T2USI,C4USI,N3USI,V3USI>    DrawAttributeArrays_T2iC4iN3iV3i; 
    4299  
    4300     typedef DrawAttributeArrays_TTTT_USI<T2,C4,N3,V3>            DrawAttributeArrays_T2C4N3V3_i; 
    4301  
    4302     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    4303  
    4304  
    4305 #endif