AtlasImageImporter::populateChunks() bug
by Tom Spilman · in Torque Game Engine Advanced · 10/28/2007 (5:01 pm) · 4 replies
Welcome to Tom's bug of the day!

Today's bug is in AtlasImageImporter::populateChunks()...
Spot the bug? Of course not!
Look specifically at the innermost loops for both sides of the main if statement...
... and ...
Notice how the first setColor() is leafY, leafX and the second is leafX, leafY. You would think that the first one is bugged and leafX, leafY is correct... and you would be very wrong!
The bug is in the PNG version of the branch and the fix is...
Why is this correct? You shouldn't ask questions like this... it makes Atlas angry. ;)


Today's bug is in AtlasImageImporter::populateChunks()...
if(mSource->getNumberChannels() == 0)
{
atc->mFormat = AtlasTexChunk::FormatJPEG;
atc->layerCount = 1;
// Construct the bitmap for this tile.
GBitmap *gb = new GBitmap[1];
gb->allocateBitmap(tileSize, tileSize);
ColorI col;
for(S32 leafX=0; leafX<tileSize; leafX++)
for(S32 leafY=0; leafY<tileSize; leafY++)
{
mSource->getColor(leafX + x*tileSize, leafY + y*tileSize, col.red, col.green, col.blue, col.alpha);
gb->setColor(leafY, leafX, col);
}
atc->bitmap = gb;
}
else
{
// It's a multilayer image, so set things up a bit differently
atc->mFormat = AtlasTexChunk::FormatPNG;
const S32 channelCount = mSource->getNumberChannels();
atc->layerCount = (channelCount + 3) / 4;
// Set up the chunk's bitmaps.
atc->bitmap = new GBitmap[atc->layerCount];
for(S32 i=0; i<atc->layerCount; i++)
atc->bitmap[i].allocateBitmap(tileSize, tileSize, false, GFXFormatR8G8B8A8);
// Ok, now sample each pixel & write out into the bitmaps.
U8 *alphas = new U8[channelCount];
ColorI c;
for(S32 leafX=0; leafX<tileSize; leafX++)
{
for(S32 leafY=0; leafY<tileSize; leafY++)
{
mSource->sampleChannels(leafX + x*tileSize, leafY + y*tileSize, alphas);
// Now store the alphas into their respective bitmaps.
for(S32 alphaStep=0; alphaStep < channelCount; alphaStep+=4)
{
c.red = alphas[alphaStep+0];
c.green = (alphaStep + 1 < channelCount) ? alphas[alphaStep+1] : 0;
c.blue = (alphaStep + 2 < channelCount) ? alphas[alphaStep+2] : 0;
c.alpha = (alphaStep + 3 < channelCount) ? alphas[alphaStep+3] : 0;
atc->bitmap[alphaStep/4].setColor(leafX, leafY, c);
}
}Spot the bug? Of course not!
Look specifically at the innermost loops for both sides of the main if statement...
gb->setColor(leafY, leafX, col);
... and ...
atc->bitmap[alphaStep/4].setColor(leafX, leafY, c);
Notice how the first setColor() is leafY, leafX and the second is leafX, leafY. You would think that the first one is bugged and leafX, leafY is correct... and you would be very wrong!
The bug is in the PNG version of the branch and the fix is...
// Now store the alphas into their respective bitmaps.
for(S32 alphaStep=0; alphaStep < channelCount; alphaStep+=4)
{
c.red = alphas[alphaStep+0];
c.green = (alphaStep + 1 < channelCount) ? alphas[alphaStep+1] : 0;
c.blue = (alphaStep + 2 < channelCount) ? alphas[alphaStep+2] : 0;
c.alpha = (alphaStep + 3 < channelCount) ? alphas[alphaStep+3] : 0;
atc->bitmap[alphaStep/4].setColor(leafY, leafX, c); // fixed!
}Why is this correct? You shouldn't ask questions like this... it makes Atlas angry. ;)

About the author
Tom is a programmer and co-owner of Sickhead Games, LLC.
#2
10/29/2007 (12:35 am)
Good find Tom and entertaining to read ;-)
#3
10/29/2007 (4:45 am)
Thanks a lot for sharing fixes Tom!
#4
This fixed all weird compiling issues we've been having, but now having issues with the jpeg side for blended terrains :(
11/03/2007 (9:24 am)
Great fixes Tom.. I can't believe its taken this long for some of these to be found.This fixed all weird compiling issues we've been having, but now having issues with the jpeg side for blended terrains :(
Torque 3D Owner J.C. Smith