Material unpackData bug
by Davide Archetti · in Torque Game Engine Advanced · 12/08/2004 (8:40 am) · 7 replies
I have modified how the datablocks are sent over the net, practically, when you run the game, a local server is created and the datablocks downloaded but the mission isn't loaded, then, when you join a remote server, the datablocks are downloaded again and a crash occur in the function decRef of the class RefObjectRef.
Looking at the stack, all starts in the function Material::setStageData, the problem is in the line
because stages[i].tex[GFXShaderFeatureData::BumpMap] isn't NULL.
Yes, this is an assignment so also if the left operand isn't initialized there shouldn't be problem, but since it uses the reference counting system, the assign operator is obtained using the set function of the RefObjectRef class, that calls decRef, so if the object points to an unallocated block of memory when you try to use it, it crashes.
I've seen that the problem is in the function Material::unpackData, in this line
because reading this piece of memory, the code sets the variable stages with values that point to an unallocated memory on the client. This seems the problem, in fact I have moved the
But it's better that who knows what is happening here takes a look at it because with this patch, we loose the value of the lightmap field in the StageData struct
Looking at the stack, all starts in the function Material::setStageData, the problem is in the line
stages[i].tex[GFXShaderFeatureData::BumpMap] = GFXTexHandle(bumpFilename[i], &GFXDefaultStaticDiffuseProfile );
because stages[i].tex[GFXShaderFeatureData::BumpMap] isn't NULL.
Yes, this is an assignment so also if the left operand isn't initialized there shouldn't be problem, but since it uses the reference counting system, the assign operator is obtained using the set function of the RefObjectRef class, that calls decRef, so if the object points to an unallocated block of memory when you try to use it, it crashes.
I've seen that the problem is in the function Material::unpackData, in this line
stream->_read( (U32)&endDataMarker - (U32)&startDataMarker, &startDataMarker );
because reading this piece of memory, the code sets the variable stages with values that point to an unallocated memory on the client. This seems the problem, in fact I have moved the
StageData stages[MAX_STAGES];line just above the
U8 startDataMarker;and the error is disappeared.
But it's better that who knows what is happening here takes a look at it because with this patch, we loose the value of the lightmap field in the StageData struct
#2
12/08/2004 (11:07 am)
I know what this problem is Davide - I'm working on fixing it at home. Should be fixed in the next few days , hopefully this weekend.
#3
12/08/2004 (12:23 pm)
OK, thank you
#4
12/08/2004 (12:29 pm)
//--------------------------------------------------------------------------
// Pack data
//--------------------------------------------------------------------------
void Material::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString( getName() );
U32 i = 0;
for( i=0; i<MAX_STAGES; i++ )
stream->write(diffuse[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(specular[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(specularPower[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->writeFlag(pixelSpecular[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->writeFlag(vertexSpecular[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(animFlags[i]);
for( i=0; i<MAX_STAGES; i++ )
mathWrite(*stream, scrollDir[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(scrollSpeed[i]);
for( i=0; i<MAX_STAGES; i++ )
mathWrite(*stream, scrollOffset[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(rotSpeed[i]);
for( i=0; i<MAX_STAGES; i++ )
mathWrite(*stream, rotPivotOffset[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(rotPos[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(wavePos[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(waveFreq[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(waveAmp[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(waveType[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(seqFramePerSec[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->write(seqSegSize[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->writeFlag(glow[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->writeFlag(emissive[i]);
stream->writeFlag(castsShadow);
stream->writeFlag(breakable);
stream->writeFlag(doubleSided);
stream->writeFlag(dynamicCubemap);
stream->writeFlag(translucent);
stream->write(translucentBlendOp);
for( i=0; i<MAX_STAGES; i++ )
{
stream->writeString( baseTexFilename[i] );
stream->writeString( detailFilename[i] );
stream->writeString( bumpFilename[i] );
stream->writeString( envFilename[i] );
}
stream->writeString( cubemapName );
}
#5
12/08/2004 (12:29 pm)
//--------------------------------------------------------------------------
// Unpack data
//--------------------------------------------------------------------------
void Material::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
const char *name = stream->readSTString();
assignName( name );
U32 i = 0;
for( i=0; i<MAX_STAGES; i++ )
stream->read(&diffuse[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&specular[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&specularPower[i]);
for( i=0; i<MAX_STAGES; i++ )
pixelSpecular[i] = stream->readFlag();
for( i=0; i<MAX_STAGES; i++ )
vertexSpecular[i] = stream->readFlag();
for( i=0; i<MAX_STAGES; i++ )
stream->read(&animFlags[i]);
for( i=0; i<MAX_STAGES; i++ )
mathRead(*stream, &scrollDir[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&scrollSpeed[i]);
for( i=0; i<MAX_STAGES; i++ )
mathRead(*stream, &scrollOffset[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&rotSpeed[i]);
for( i=0; i<MAX_STAGES; i++ )
mathRead(*stream, &rotPivotOffset[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&rotPos[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&wavePos[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&waveFreq[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&waveAmp[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&waveType[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&seqFramePerSec[i]);
for( i=0; i<MAX_STAGES; i++ )
stream->read(&seqSegSize[i]);
for( i=0; i<MAX_STAGES; i++ )
glow[i] = stream->readFlag();
for( i=0; i<MAX_STAGES; i++ )
emissive[i] = stream->readFlag();
castsShadow = stream->readFlag();
breakable = stream->readFlag();
doubleSided = stream->readFlag();
dynamicCubemap = stream->readFlag();
translucent = stream->readFlag();
U32 blendOp;
stream->read(&blendOp);
translucentBlendOp = (BlendOp)blendOp;
for( U32 i=0; i<MAX_STAGES; i++ )
{
baseTexFilename[i] = stream->readSTString();
detailFilename[i] = stream->readSTString();
bumpFilename[i] = stream->readSTString();
envFilename[i] = stream->readSTString();
}
cubemapName = stream->readSTString();
mCubemapData = static_cast<CubemapData*>(Sim::findObject( cubemapName ) );
}
#6
12/08/2004 (12:30 pm)
Make sure that the material mappings are being called on both the server and the client or you get really bad results (data/materialMap.cs by default)
#7
12/14/2004 (1:02 pm)
I checked in Matt's changes, thanks Matt.
Associate Kyle Carter