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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org