I mostly like SDL, but some of its ways are a little bizarre, requiring knowledge of how things work underneath, but without making that knowledge easily available.
Having just spent several hours trying to get blitting with transparent surfaces to work, I thought I would share so that hopefully others won’t go through the same frustrating period of confusion. Also, it’ll be here if I forget how to do this in the future.
To create a surface supporting transparency, you need to specify the bit masks for each pixel, which is a long way of saying ‘do this:’
SDL_Surface* surface; #if SDL_BYTEORDER == SDL_BIG_ENDIAN surface = SDL_CreateRGBSurface(SDL_HWSURFACE,width,height,32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); #else surface = SDL_CreateRGBSurface(SDL_HWSURFACE,width,height,32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); #endif
Here, we set the flags differently based on the endian-ness of the computer. Otherwise, things could go horribly wrong, with colours being inverted and other stuff you really don’t want.
The surface will be filled-in with black pixels, but we want it to be transparent, so we fill it with transparent pixels using
SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
Now, this is all pretty simple so far, and yet I had so much trouble getting some surfaces of text on a transparent background to blit to this surface. The trick is that you have to make sure that the
SDL_SRCALPHA flag is not set on the source surface. Otherwise, the surfaces are blended together, and as the target surface is completely transparent, nothing will apparently be blitted.
You can remove the flag like this:
SDL_SetAlpha( sourceSurface, 0, SDL_ALPHA_OPAQUE );