How should I load images + specs into TGB?
by Tomas Lazaro · in Torque Game Builder · 02/04/2011 (4:28 pm) · 0 replies
Hi everyone,
I would like to know what do you think is the best way to load and handle images with extra data in TGB. I will begin with an example of how I'm used to do this with other toolset (not with Torque).
For every game I have worked, we always used a fixed resolution that is scaled in runtime. Most of our games were 800x600 while the newest ones are now in 1024x768. It is then quite usual for to me to ask the artists to provide images with the canvas included. Image I wanted a Main Menu button; since most of the times the MM are extremely custom and "artistic" it's easier to have all the images in 1024x768 PNGs with transparency all around. Then all I have to do is add all images at x=0 and y=0 and will look exactly how the artists had it in their Photoshop files.
This is extremely useful for Hidden Object games when you might have 30 images floating around and the artist have them all nicely placed in their PSDs. When exported those will produce i.e. 1024x768 so we add them all at x=0 and y=0.
That is really nice but if done just like that you will end up with dozens of 1024x768 textures (rounded up to nearest power of 2 square: 2048x2048) loaded in runtime. Those are 4 bytes (RGBA) * 2048 * 2048 = 16MB per texture. Really bad idea. I'm not talking about disk space, I'm talking about runtime textures!
The way we solve this is by preprocessing the images before packaging them. The most important process is Cropping. All images are stripped from the extra transparent areas around them. We determine the smallest rectangle that contains the relevant pixels (pixels with alpha > 0) and only keep that. So the 1024x768 images may get cropped down to a 200x100. We output a file with the original size and placement of the rectangle in it to so we can reproduce it in runtime. For instance we can say that from a starting file of 1024x768 we only have a relevant image of 200x100 placed at x=150 and y=125. The thing is our resource manager will load that image in runtime and will say that it is a 1024x768 image, getWidth() and getHeight() will return (1024, 768), if we place it a x=0 and y=0 in the game it will look exactly like the original file did.
The thing is it internally uses a texture of 200x100 and knows it's offset and final size, completely hiding it from the API user but using the smallest runtime texture possible (256x256 in this example, 0.25 MB vs the 16MB it could have been).
The intermediate steps might not be the smartest or best way to do this but the final results is we give artists the ability to place images in screen space without us having to worry about it as we just add them at x=0 and y=0 without any extra overhead at runtime.
SIDE NOTE: I was trying to be illustrative about textures for the usual case, we actually make up images out of small textures, avoiding the generation of a 2048x2048 for a 1024x768. We actually create 128x128 or 256x256 squares wasting no extra texture space for a 1024x768 texture. Other 'hacks' include what TGB does of packaging several images in one file making it end up as a single texture (datablocks stuff).
My question is: How should I load this auto generated meta-data to TGB? I can create my own classes representing my cropped textures but how do I load the meta-data? Should I create a big TorqueScript file with something like datablocks and import it or should I directly load a custom file? Can I associate it somehow to the loading of images perhaps? Maybe I could have the meta data loaded from a file just like the optional alpha channel is loaded automatically?
I also have some image files that have other data associated, like tiles for tilemaps that have extra configuration. Should I create a custom file format with my data or auto generating TorqueScript files is fine?
Thanks!
I would like to know what do you think is the best way to load and handle images with extra data in TGB. I will begin with an example of how I'm used to do this with other toolset (not with Torque).
Cropping Images
For every game I have worked, we always used a fixed resolution that is scaled in runtime. Most of our games were 800x600 while the newest ones are now in 1024x768. It is then quite usual for to me to ask the artists to provide images with the canvas included. Image I wanted a Main Menu button; since most of the times the MM are extremely custom and "artistic" it's easier to have all the images in 1024x768 PNGs with transparency all around. Then all I have to do is add all images at x=0 and y=0 and will look exactly how the artists had it in their Photoshop files.
This is extremely useful for Hidden Object games when you might have 30 images floating around and the artist have them all nicely placed in their PSDs. When exported those will produce i.e. 1024x768 so we add them all at x=0 and y=0.
That is really nice but if done just like that you will end up with dozens of 1024x768 textures (rounded up to nearest power of 2 square: 2048x2048) loaded in runtime. Those are 4 bytes (RGBA) * 2048 * 2048 = 16MB per texture. Really bad idea. I'm not talking about disk space, I'm talking about runtime textures!
The way we solve this is by preprocessing the images before packaging them. The most important process is Cropping. All images are stripped from the extra transparent areas around them. We determine the smallest rectangle that contains the relevant pixels (pixels with alpha > 0) and only keep that. So the 1024x768 images may get cropped down to a 200x100. We output a file with the original size and placement of the rectangle in it to so we can reproduce it in runtime. For instance we can say that from a starting file of 1024x768 we only have a relevant image of 200x100 placed at x=150 and y=125. The thing is our resource manager will load that image in runtime and will say that it is a 1024x768 image, getWidth() and getHeight() will return (1024, 768), if we place it a x=0 and y=0 in the game it will look exactly like the original file did.
The thing is it internally uses a texture of 200x100 and knows it's offset and final size, completely hiding it from the API user but using the smallest runtime texture possible (256x256 in this example, 0.25 MB vs the 16MB it could have been).
The intermediate steps might not be the smartest or best way to do this but the final results is we give artists the ability to place images in screen space without us having to worry about it as we just add them at x=0 and y=0 without any extra overhead at runtime.
SIDE NOTE: I was trying to be illustrative about textures for the usual case, we actually make up images out of small textures, avoiding the generation of a 2048x2048 for a 1024x768. We actually create 128x128 or 256x256 squares wasting no extra texture space for a 1024x768 texture. Other 'hacks' include what TGB does of packaging several images in one file making it end up as a single texture (datablocks stuff).
How to do it in TGB?
My question is: How should I load this auto generated meta-data to TGB? I can create my own classes representing my cropped textures but how do I load the meta-data? Should I create a big TorqueScript file with something like datablocks and import it or should I directly load a custom file? Can I associate it somehow to the loading of images perhaps? Maybe I could have the meta data loaded from a file just like the optional alpha channel is loaded automatically?
I also have some image files that have other data associated, like tiles for tilemaps that have extra configuration. Should I create a custom file format with my data or auto generating TorqueScript files is fine?
Thanks!
About the author
Professional Game Developer/Programmer