I have a 2-D tile-based game. Some of the tiles have transparent
areas. (When the program renders the game display 20 times/sec, it
has to do about 100 bits of tiles. The tile size is user-configurable,
but the most common size is 48x48 pixels.)
Currently, this is how the rendering works. The program requests a
32-bit SDL_Surface for the video screen, regardless of the native
setup. (24-bit color, no alpha channel.) The tiles are read from a BMP
file. Tiles with transparencies are specified by two tiles in the BMP
file, an image tile and a mask tile. The program stores the tiles are
stored in memory, 32 bits per pixel, with a special pixel value used
to indicate a transparent pixel. The transparent pixel value is
usually 0xFF000000. (It’s figured out using something like “~0UL ^
rmask ^ gmask ^ bmask”.) The tiles are stored in malloc()ed memory –
no SDL surfaces involved. I then have a few (relatively) simple
functions to “manually” blit tiles to the screen, minus the
transparent pixels.
Unfortunately, the above solution bypasses much of SDL. (The code
never once calls SDL_BlitSurface, for example) But, it was the fastest
of several approaches that I tested on my hardware, so it was what I
used.
However, I’ve gotten complaints from a few users that my program runs
too slowly on their machine. I believe that the bottleneck for them is
SDL’s translation of the screen from 32bpp to the native format. There
are enough people complaining to motivate me to try to create an
alternate display engine. Presumably this second engine should use a
native-format screen surface. The question is, how to deal with the
sprites?
Here are the ideas I’ve come up with. I’m hoping that someone here
with more SDL experience than myself can offer some guidance as to
which is more likely to bear fruit before I slog out a bunch of code.
-
Use SDL_SetColorKey() on my tile surfaces to get transparent
pixels. This is the usual approach, but it requires my program to
find a color to use for the key on the fly. And if the native
format is only 8bpp, it is highly likely that there wouldn’t be any
unused colors available. Increasing the pixel depth in order to
make a 257th color available would only lose the advantage of
keeping to the native format. -
Keep the tiles in my non-SDL memory, with 32 bits per pixel, but
using native pixel values. (0xFF000000 will still mark transparent
pixels.) Write three more sets of tile-copying functions to handle
8-, 16-, and 24-bit destination surfaces. This is the approach that
I’m leaning toward at the moment, though it probably involves the
most new code. -
Add alpha values to the tile pixels, using only 0 and 255. Use
SDL_DisplayFormatAlpha() to create the tile surfaces, and use
SDL_BlitSurface() to copy these to the screen surface. My initial
tests suggest that this approach would be SLOW. -
Something else entirely that I haven’t thought of.
b