Skip to main content
GameDev.net gamedev.net
🔒 Locked

Creating SDL_Surface With Alpha Channel Not Working

Started by NGenD Sep 27, 2009 at 2:33 PM 4 replies 3.7k views
Original Post
NGenD
NGenD
N = SDL_CreateRGBSurface ( SDL_SRCALPHA, W,
	H * StringStack.size ( ) + H,
	Target->format->BitsPerPixel,
	Target->format->Rmask,
	Target->format->Gmask,
	Target->format->Bmask,
	Target->format->Amask );

SDL_FillRect ( N, NULL, SDL_MapRGBA ( Target->format, 52, 193, 124, 0 ) );
This code creates a blank SDL_Surface, but whenever I use SDL_FillRect while using SDL_MapRGBA with an alpha value of 0, the surface still shows up as non-transparent. Why is it that the alpha channel isn't being created? P.S.- In this case, Target is the screen surface. P.P.S.- My goal is to create a completely transparent surface in the format of the target surface.
rip-off
rip-off
SDL_MapRGBA should use the format of the surface itself. My experience has been that if you check the surface format of the "screen" surface, it is 32 bit (if requested) but the alpha channel is set to 8 bits of loss. Simply put, the surface is in 24 bit colour mode, but packed like a 32 bit surface.

You can instead use the format values here rather than trusting the format of the screen.
NGenD
NGenD
I've checked endianness in a few other scripts for loading, but I thought that I'd use the format of the screen just to save some processing. I'm guessing that a value of 0 for the alpha mask would make it 24-bit? In which case, I should still be able to use the screen format for the RGB mask and then create the A mask according to endianness, correct?
rip-off
rip-off
Your screen format is likely to be similar, so that probably isn't a big deal. But the main thing is MapRGB, you can't expect a pixel value mapped from a surface A to have any meaning on surface B, whose format differs. Remember - the format includes the Mask, Shift and Loss values, not just the mask.
grimfang4
grimfang4
Yeah, rip-off is saying to try something like this:
SDL_FillRect ( N, NULL, SDL_MapRGBA ( N->format, 52, 193, 124, 0 ) );
instead of this:
SDL_FillRect ( N, NULL, SDL_MapRGBA ( Target->format, 52, 193, 124, 0 ) );

Follow his advice and the link he posted. There's no benefit to making a surface's format 'sorta' like the screen's format, so don't bother using Target->format at all in the SDL_CreateRGBSurface call. If you want a 32-bit surface with alpha, then use 32 instead of Target->format->BitsPerPixel. Then, if the screen surface happens to not be 32 bits, you can still use other 32-bit alpha surfaces. I don't ever expect to receive a 32-bit screen surface. You should be using SDL_SetVideoMode with 0 passed as the bit depth, since 32 can fail on some systems. Often, you'll get a 24-bit screen.

Also, using SDL_SRCALPHA in that call won't do anything. The standard thing to put there is SDL_SWSURFACE (or identically, 0). The reason that you're not getting a surface with an alpha channel is because Target->format->Amask == 0 (the screen surface has no alpha channel or, as rip-off puts it, the alpha info is ignored).

You might be interested in this article I wrote:
http://code.bluedinosaurs.com/tutorials/blending.html

Jonny D
andrern2000
andrern2000
Check this out. This may help you.

lazyfoo .net /SDL_tutorials/ lesson05 /index.php (without spaces)


Also, you need the image to be saved as PNG. If you saved it as JPEG, the color maybe compressed, resulting the color converted into another channel. So white maybe converted into alittle greyish, so the alpha color code doesn't match with it anymore.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.