SDL_CreateRGBSurface difficulties

Started by
4 comments, last by Feidias 18 years, 10 months ago
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?
- - - - - - - - - - - - - - - -I am you and what I see is me
Advertisement
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;#endifSDL_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.
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
- - - - - - - - - - - - - - - -I am you and what I see is me
Well, I gotta head out, but thanks anyway
- - - - - - - - - - - - - - - -I am you and what I see is me
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.
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

This topic is closed to new replies.

Advertisement