Sign in to follow this  
Geno the Great

SDL_CreateRGBSurface difficulties

Recommended Posts

I'm making a sprite sheet loader, and so far it's going perfectly, except for one slight problem: When you call the function GetSprite(int index), the function identifies the part of the sprite sheet at index, and grabs it to return to the user. My method is to create a new surface with SDL_CreateRGBSurface, blit the portion of the sprite that I want onto it, and return it. Works fine. However, the new surface doesn't preserve the alpha of the original (Using PNG), and I suspect it's an issue with create RGB Surface. Have a look at my code:
SDL_Surface *sprite = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0);

int code = SDL_BlitSurface(spritesheet, &srcrect, sprite, NULL); // blit the section we want into "sprite"

if(code == 0)
{
	return sprite; // it's up to the programmer to free the surface.
}
else
{
	printf("Unable to blit sprite\n");
	return NULL;
}
The function does what it's supposed to, but when displayed, the image is black where there would normally be alpha transparency. What can I do to fix it?

Share this post


Link to post
Share on other sites
Looking at the example from the docs, you might want to call SDL_CreateRGBSurface like this:


/* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order,
as expected by OpenGL for textures */

Uint32 rmask, gmask, bmask, amask;

/* SDL interprets each pixel as a 32-bit number, so our masks must depend
on the endianness (byte order) of the machine */

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

SDL_Surface *sprite = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);




That way the masks are correct and the alpha should be usable. If that does not work, you may have to call SDL_SetColorKey manually again for the surface, since you simply blit from one source to another format. See if that does anything.

Share this post


Link to post
Share on other sites
I never liked using preprocessor stuff within my code, but trying that, it makes the whole image white. I remember using that code before in some really old project, and it worked fine...

Changing the code to



SDL_Surface *sprite = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
SDL_Surface *sprite2 = SDL_DisplayFormatAlpha(sprite);
SDL_FreeSurface(sprite);

// etc, then return sprite2



makes the images white, as does just using the straight RGB surface and not formatting it. However, using DisplayFormat instead of DisplayFormatAlpha brings it back to the original black.

I would say "Is it possible that I'm doing something wrong", but I already know that I'm doing something wrong. Something stupid. This code has worked before, and I can't figure out why it doesn't want to work now

Edit: I'm under the impression that SetColorKey won't work for the surfaces in question, since it only sets 1 color as being a certain level of transparency, while a PNG image can have any number of colors transparent, and all different levels of transparency

Share this post


Link to post
Share on other sites
When you blit, the alpha gets 'used', so to speak. Think about how you would want it to work if you were blitting to the screen. That's probably what you're getting here.

Try calling SDL_SetAlpha(sprite, 0, 0) before you blit it. That should produce behaviour where, according to the docs, "The RGBA data is copied to the destination surface." Hope that helps.

Share this post


Link to post
Share on other sites
I guess you have set all surfaces 32 bit? You could also try SDL_CreateRGBSurfaceFrom to make a surface from the PNG pic data, if that is possible. When I was playing with SDL alpha I got an impression that SDL doesn't support pixel based alpha and a surface has unified alpha value. I hope I'm wrong:)
Btw, color key doesn't have an alpha value afaik, it just doesn't show any selected RGB value.

Edit: Oh, there is per pixel alpha, but it works only in certain situations:

SDL_SetAlpha

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this