TSShapeInstance::snapShot is making invalid bitmaps
by Steve Lamperti · in Torque Game Engine · 01/14/2005 (4:26 pm) · 16 replies
I'm trying to call the snapShot method from TSShapeInstance to make bitmap pictures of objects. I've gotten the code to the point where it produces a GBitmap, but when I then write that bitmap out to disk with GBitmap::writeMSBmp, I'm getting a file that seems like it might be the right size, but isn't readable by picture viewer, or other graphic programs. Anyone have any suggestions as to what may be going wrong?
#2
Thanks for the suggestion. Interestingly that worked, sort of. I got a readable png file, but it made me realize that I was trying to create a file that was too small pixel wise, and the bmp file that I thought might be ok was really quite a bit too big in terms of diskspace.
The png image isn't recognizable, but that's probably a result of trying to output the snapshot in 16 pixels.
The bmp file was coming out bigger then a meg, and I was specifying that the size of the output picture should only be 16x16 pixels. I'll try playing around with the size, and the detail of the image of the png, but I still need this as a bmp, so I'll have to figure out why that isn't working at some point.
01/14/2005 (5:02 pm)
Ben,Thanks for the suggestion. Interestingly that worked, sort of. I got a readable png file, but it made me realize that I was trying to create a file that was too small pixel wise, and the bmp file that I thought might be ok was really quite a bit too big in terms of diskspace.
The png image isn't recognizable, but that's probably a result of trying to output the snapshot in 16 pixels.
The bmp file was coming out bigger then a meg, and I was specifying that the size of the output picture should only be 16x16 pixels. I'll try playing around with the size, and the detail of the image of the png, but I still need this as a bmp, so I'll have to figure out why that isn't working at some point.
#3
01/15/2005 (3:39 pm)
Yes, would be interesting to find out why it's not saving a proper BMP. I would suspect maybe something to do with the alpha?
#4
Also, I'm having trouble figuring out how the detail levels are supposed to work. Does anyone have a link to some doc that describes how detail levels work in the engine? I've been trying to find some explanation, and not having much luck.
01/17/2005 (9:26 am)
Even the PNGs I'm getting are not recognizable as images. Perhaps I am misunderstanding how this function is supposed to work? From looking at it, and how it's used, I was expecting that it would return a picture image of how the 3D shape would look. The Png's I'm getting just look like white shapes on a black background. Also, I'm having trouble figuring out how the detail levels are supposed to work. Does anyone have a link to some doc that describes how detail levels work in the engine? I've been trying to find some explanation, and not having much luck.
#5
If I write out a BMP it produces a file that is quite large, and cannot be read by programs that should be able to read a BMP.
If I write out a GIF, it produces an empty file. zero bytes.
If I write out a png, it produces a file that is readable, and contains a white outline (profile) of the shape that I am trying to snapshot.
I could not find any doc on this function, so I am not entirely sure what it is supposed to do. Perhaps I have the options set wrong, or perhaps I misunderstood what it is doing.
I think the comment about the alpha channel is probably correct, but I'm not really familiar enough with the graphics to be sure. Perhaps I'll dive into the code, and try to add an option to make the alpha channel optional.
01/17/2005 (3:54 pm)
O.K. here's what I'm getting from the snapshot function:If I write out a BMP it produces a file that is quite large, and cannot be read by programs that should be able to read a BMP.
If I write out a GIF, it produces an empty file. zero bytes.
If I write out a png, it produces a file that is readable, and contains a white outline (profile) of the shape that I am trying to snapshot.
I could not find any doc on this function, so I am not entirely sure what it is supposed to do. Perhaps I have the options set wrong, or perhaps I misunderstood what it is doing.
I think the comment about the alpha channel is probably correct, but I'm not really familiar enough with the graphics to be sure. Perhaps I'll dive into the code, and try to add an option to make the alpha channel optional.
#6
01/18/2005 (12:15 am)
Are you sure it's loading the textures before it creates the sapshot? If they aren't loaded, you'll get an all-white shape.
#7
01/18/2005 (12:16 am)
Also, please check that the BMP and GIF writers can support alpha! The GBitmap created by snapshot have an alpha channel which may be wreaking havoc with the output code!
#8
If someone who knows this stuff better then I can suggest why I am still not getting textures, I would appreciate it.
01/18/2005 (9:42 am)
Here's the code of my snapshot routine. I believe that you are right about the alpha channel thing, so I added an arg to shapshot called noAlpha, which returns before the code does the alpha calcs. I also have been thinking along the same lines with the textures, so I added the initMaterialList, and PreloadmaterialList calls.If someone who knows this stuff better then I can suggest why I am still not getting textures, I would appreciate it.
//
// JSL - V7.0 getSnapShot
// Take a snapShot
//
GBitmap *getSnapShot(unsigned char *objectName, long width, long height)
{
Resource<TSShape> shape;
TSShapeInstance *shapeInstance;
GBitmap *theMap;
GameBaseData *theData;
ShapeBaseData *shapeData;
if (Game == NULL || Game->isRunning() == false)
return(NULL);
Sim::findObject((const char *) objectName, theData);
shapeData = dynamic_cast<ShapeBaseData *>(theData);
if (shapeData)
{
shape = ResourceManager->load((const char *) shapeData->shapeName);
if (shape == NULL)
return(NULL);
shape->init();
shape->initMaterialList();
shape->preloadMaterialList();
shapeInstance = new TSShapeInstance((TSShape *) shape, true);
// JSL - make sure the picture is rotated correctly.
MatrixF angMat;
angMat.mul(MatrixF(EulerF(0,0,M_PI_F)),MatrixF(EulerF(M_PI_F,0,0)));
theMap = shapeInstance->snapshot(width, height, false, angMat, 0, 0, true, true);
delete shapeInstance;
return(theMap);
}
return(NULL);
}
#9
01/18/2005 (7:22 pm)
Please note that when I refer to alpha, I mean that the GBitmap HAS an alpha channel, not whether anything is using it. The BMP and JPG formats by default don't even have a place to put alpha... so perhaps it's because the code is trying to put the alpha somewhere that things are breaking. Does that make sense?
#10
When I changed the snapshot routine to not add the alpha channel, my gBitmap was able to write out as a bmp successfully, so I think that is working correctly. In fact, my entire routine is working great, except for the fact that the bmp file contains a white profile of the shape I am trying to draw.
I believe that the BMP/GIF/Alpha channel question is resolved, if I can just figure out the reason why I am not getting textures, I believe that I am done.
Thanks for your help so far. Any guesses about the textures?
01/19/2005 (9:12 am)
Ben,When I changed the snapshot routine to not add the alpha channel, my gBitmap was able to write out as a bmp successfully, so I think that is working correctly. In fact, my entire routine is working great, except for the fact that the bmp file contains a white profile of the shape I am trying to draw.
I believe that the BMP/GIF/Alpha channel question is resolved, if I can just figure out the reason why I am not getting textures, I believe that I am done.
Thanks for your help so far. Any guesses about the textures?
#11
01/19/2005 (12:48 pm)
Probably snapshot is getting called before the textures are loaded into the shape?
#12
shape->init();
shape->initMaterialList();
shape->preloadMaterialList();
It's quite possible that these calls are not enough, and that I missed something. If so, and someone sees what I missed I'd appreciate being corrected.
01/19/2005 (12:56 pm)
That's why I added the calls to the routines below, as listed in the code of the routine above. shape->init();
shape->initMaterialList();
shape->preloadMaterialList();
It's quite possible that these calls are not enough, and that I missed something. If so, and someone sees what I missed I'd appreciate being corrected.
#13
01/19/2005 (10:39 pm)
Possibly need to call loadMaterialList or some such, rather than preload?
#14
01/20/2005 (12:01 pm)
I checked, and preloadMaterialList looks like the right call. In fact, it looks like the materials are loaded correctly, and even having render calls being called on them. I'm quite confused at this point.
#15
shapeInstance = new TSShapeInstance((TSShape *) shape, true);
should actually not have the (TSShape *) cast, as the method is expecting to receive a TSShape resource, not a TSShape *. This messed up my TSShapeInstance object when it tried to find the resource path for the TSShape, thus causing the textures to not be loaded because the path to them was not available.
I'm now getting a valid picture back from the snapshot method.
01/20/2005 (4:11 pm)
In case anyone is interested in this thread, I've resolved this problem. A big part of the problem was actually a cast that should not have been there. The line shapeInstance = new TSShapeInstance((TSShape *) shape, true);
should actually not have the (TSShape *) cast, as the method is expecting to receive a TSShape resource, not a TSShape *. This messed up my TSShapeInstance object when it tried to find the resource path for the TSShape, thus causing the textures to not be loaded because the path to them was not available.
I'm now getting a valid picture back from the snapshot method.
#16
01/20/2005 (11:17 pm)
Ah, wonderful. An odyssey through Torque, eh? :)
Associate Kyle Carter