Hi Gabriel,
There are two reasons why I cannot do it in B3d/Bmax. They are:
1 - Method I use for 'occlusion' of sprites by the background image
2 - Number of frames of animation used and size
Explanation for point 1 -
Although my game is isometric in appearance it does not use tiles for the background, instead it uses a single pre rendered image (which may have sections animated) along with 2 other images which contain the 'z ordering' information at each pixel in the background image. This means that I can have extremely detailed and complex level designs (ie like those in Baldurs Gate ) without using tiles. Each pixel in the sprite is tested against the z ordering images to determine if the pixel should be occluded or not. If I were to use regular image commands I would have no way of occluding parts of the sprites when they are partially behind a wall or behind a tree etc - not without using some kind of tile system - which I don't want to do as I couldn't use a prerendered image for the background.
Point 2 -
Each character has about 800 frames of animation, although some have more like 1000+. If I were to load them as an 'animimage' then for the 'Demon' who fits inside a bounding box of about 350x350 (considering all frames) he would take up over 300MB of video memory. Even if I were to crop the images to minimise transparent space it is still going to be over 100MB. Instead I have my own image format which is stored in System Memory, and only stores non transparent pixels the Demon takes up about 50MB of System Memory (he is the largest most of the others are between 4 & 16 MB of System Memory) That also leaves me with a lot more video memory to play with for the level and things like fonts and the like.
Hope that explains things a bit better.
From Matty
EDIT - to explain further I'll show how I store an animated sprite image and how I draw it to the screen.
Image Format
For a single image:
XSize - 1 byte that can be of value 1/2/4 which determines whether the xcoordinates are stored as bytes,shorts or ints
YSize - 1 byte that can be of value 1/2/4 which determines the whether the ycoordinates are stored as bytes, shorts or ints
NumberOfColumns - 4 bytes (int), how many vertical strips of color values exist in the image, not necessarily equal to the width of the image in pixels.
then for each column the following is stored:
Xcoord - 1/2/4 bytes depending on XSize = x position of pixel in image
YCoord1 - 1/2/4 bytes depending on YSize = y position of start of column
YCoord2 - 1/2/4 bytes depending on YSize = y position of end of column
For each pixel between Ycoord1 and Ycoord 2 inclusive
RGBA - 4 byte int with R,G,B,A information
Note that when putting these images together (for which I've created a tool that reads either tga or uncompressed tif images) only pixels with an alpha greater than zero are stored ie completely transparent .
For an animated image I simply combine each of these images in the format above and have a separate header which holds the offset of the start of each image.
I've got a nice workflow from poser or softimage to export images in either tga or tif format and then I simply run a tool written in blitzplus which converts these tif/tga images into images for my game. There are a couple of other things I'll probably put in the header at some point but they are not essential.
In the game itself when drawing these images I simply run through a bank containing the image data above and test each pixel as follows:
pseudocode
If Pixel is within screen boundaries then
If Pixel Has Not Already Been Drawn To Then
IF Pixel is within game world boundary then
PixelDepth=peekint the pixel depth from a bank containing the background image z order value
If PixelDepth<'FootZValue' then
'FootZValue' is the Z order value at the 'feet' of the sprite, assuming humanoid shapes (or anything which would reasonably be expected to fit into a cylindrical bounding box) this value should be the same
for all pixels in the sprite image
The above line about the PixelDepth<FootZValue is what does the occlusion between the background scene and the sprite's pixels. I don't know of any other way to use a pre rendered scene (that is not easily broken into tiles) as a background image and have sprites move about them with correct occlusion at points.
Modify RGB value of pixel as per lighting information passed to function for the sprite position in the world (RGB has components multiply blended with light map with light value being from the 'foot' point on the sprite in the world)
If AntiAlias then
PeekByte the Alphalevel of the pixel (which I just realised I can simply use a bit shift for so will change that right away...)
Background RGB= Read Int from background rgb to get background pixel color at this point
Perform Alpha Calculation If Alpha<255
endif
writepixelfast rgb at x,y
poke byte into bank which marks this pixel as already drawn to...(no pixel is drawn more than twice - 1 for the background (blitted) and 1 here
endif
endif
endif
endif
|