Hi, lately I was trying to convert an osg-file which uses multitexturing to openFlight and realized, that the texture coordinates for units >0 got corrupted. (First 3 coords are repeated again and again).
So I had a look at the openFlight Plugin and found the problem in expGeometry.cpp, line 772, function writeUVList: Code: void FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom ) { unsigned int numLayers( 0 ); uint32 flags( 0 ); unsigned int idx; for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { flags |= LAYER_1 >> (idx-1); numLayers++; } } if( numLayers == 0 ) return; uint16 length( 8 + (8*numLayers*numVerts) ); _records->writeInt16( (int16) UV_LIST_OP ); _records->writeUInt16( length ); _records->writeInt32( flags ); osg::Vec2 defaultCoord( 0., 0. ); // const osg::StateSet* ss = getCurrentStateSet(); for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { osg::Array* t = const_cast<osg::Array*>( geom.getTexCoordArray( idx ) ); osg::ref_ptr<osg::Vec2Array> t2 = dynamic_cast<osg::Vec2Array*>( t ); if (!t2.valid()) { std::ostringstream warning; warning << "fltexp: No Texture2D for unit " << idx; osg::notify( osg::WARN ) << warning.str() << std::endl; _fltOpt->getWriteResult().warn( warning.str() ); t2 = new osg::Vec2Array; } else if (static_cast<int>(t2->getNumElements()) != numVerts) { std::ostringstream warning; warning << "fltexp: Invalid number of texture coordinates for unit " << idx; osg::notify( osg::WARN ) << warning.str() << std::endl; _fltOpt->getWriteResult().warn( warning.str() ); } const int size = t2->getNumElements(); int vIdx; for( vIdx=0; vIdx<numVerts; vIdx++) { osg::Vec2& tc( defaultCoord ); if (vIdx < size) tc = (*t2)[ vIdx ]; _records->writeFloat32( tc[0] ); _records->writeFloat32( tc[1] ); } } } } My Geometry contained 444 vertices and as many texture coordinates, so the size of the array t2 is 444 (and therefor does not equal numVerts which is 3 (using triangles)). The indices are always 0, 1, 2, so each time the function is called, the same three texture coordinates are added. I fixed this problem adding indices respectivly firstIndex as input parameter like it is done in writeVertexList: Code: void FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom, const std::vector<unsigned int>& indices ) { unsigned int numLayers( 0 ); uint32 flags( 0 ); unsigned int idx; for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { flags |= LAYER_1 >> (idx-1); numLayers++; } } if( numLayers == 0 ) return; uint16 length( 8 + (8*numLayers*numVerts) ); _records->writeInt16( (int16) UV_LIST_OP ); _records->writeUInt16( length ); _records->writeInt32( flags ); osg::Vec2 defaultCoord( 0., 0. ); // const osg::StateSet* ss = getCurrentStateSet(); for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { osg::Array* t = const_cast<osg::Array*>( geom.getTexCoordArray( idx ) ); osg::ref_ptr<osg::Vec2Array> t2 = dynamic_cast<osg::Vec2Array*>( t ); if (!t2.valid()) { std::ostringstream warning; warning << "fltexp: No Texture2D for unit " << idx; osg::notify( osg::WARN ) << warning.str() << std::endl; _fltOpt->getWriteResult().warn( warning.str() ); t2 = new osg::Vec2Array; } const int size = t2->getNumElements(); for( int cIdx=0; cIdx<numVerts; cIdx++) { int vIdx = indices[cIdx]; osg::Vec2& tc( defaultCoord ); if (vIdx < size) tc = (*t2)[ vIdx ]; _records->writeFloat32( tc[0] ); _records->writeFloat32( tc[1] ); } } } } and Code: void FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom, unsigned int first ) { unsigned int numLayers( 0 ); uint32 flags( 0 ); unsigned int idx; for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { flags |= LAYER_1 >> (idx-1); numLayers++; } } if( numLayers == 0 ) return; uint16 length( 8 + (8*numLayers*numVerts) ); _records->writeInt16( (int16) UV_LIST_OP ); _records->writeUInt16( length ); _records->writeInt32( flags ); osg::Vec2 defaultCoord( 0., 0. ); // const osg::StateSet* ss = getCurrentStateSet(); for( idx=1; idx<8; idx++) { if( isTextured( idx, geom ) ) { osg::Array* t = const_cast<osg::Array*>( geom.getTexCoordArray( idx ) ); osg::ref_ptr<osg::Vec2Array> t2 = dynamic_cast<osg::Vec2Array*>( t ); if (!t2.valid()) { std::ostringstream warning; warning << "fltexp: No Texture2D for unit " << idx; osg::notify( osg::WARN ) << warning.str() << std::endl; _fltOpt->getWriteResult().warn( warning.str() ); t2 = new osg::Vec2Array; } else if (static_cast<int>(t2->getNumElements()) < first + numVerts) { std::ostringstream warning; warning << "fltexp: Invalid number of texture coordinates for unit " << idx; osg::notify( osg::WARN ) << warning.str() << std::endl; _fltOpt->getWriteResult().warn( warning.str() ); } const int size = t2->getNumElements(); int cIdx; for( cIdx=0; cIdx<numVerts; cIdx++) { int vIdx = first + cIdx; osg::Vec2& tc( defaultCoord ); if (vIdx < size) tc = (*t2)[ vIdx ]; _records->writeFloat32( tc[0] ); _records->writeFloat32( tc[1] ); } } } } I wondered why this problem has not occured to somebody else. I think MultiTexturing has been used and tested before, hasn't it? Is something different in my setup? I added an osg file for testing purposes. Here Quads are used, so the first 4 texture coordinates are repeated if the file is exported to flt. I am using osg 2.9.0 on windows XP. Cheers, Katharina ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=33243#33243 Attachments: http://forum.openscenegraph.org//files/multitextest_897.osg _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org