I'm trying to blit a surface created by IMG_Load
(SDL_image) onto one created via SDL_CreateRGBSurface
. When both surfaces are loaded with IMG_Load
, this works fine, but not when the target surface was created using SDL_CreateRGBSurface
.
By experimentation, I figured out that if I call SDL_SetAlpha
on the source surface, it suddenly works fine. The documentation is a bit lacking, but how I understand it, the way I call it below should clear the SDL_SRCALPHA
flag, presumably set by IMG_Load
. It seems like the alpha flag of the source surface is what matters when blitting, so I guess this turns off alpha blending altogether.
The big question is: Why is this SDL_SetAlpha
necessary in the first place? And is this really the right way to do it?
Here's code that reproduces this:
#include <SDL/SDL.h>
#include <SDL_image/SDL_image.h>
SDL_Surface* copy_surface(SDL_Surface* source)
{
SDL_Surface *target;
target = SDL_CreateRGBSurface(0, source->w, source->h,
source->format->BitsPerPixel,
source->format->Rmask, source->format->Gmask,
source->format->Bmask, source->format->Amask);
/*
* I really don't understand why this is necessary. This is supposed to
* clear the SDL_SRCALPHA flag presumably set by IMG_Load. But why wouldn't
* blitting work otherwise?
*/
SDL_SetAlpha(source, 0, 0);
SDL_BlitSurface(source, 0, target, 0);
return target;
}
int main(int argc, char* argv[])
{
SDL_Event event;
SDL_Surface *copy, *screen, *source;
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(800, 600, 0, 0);
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
source = IMG_Load("source.png");
if (!source) {
fprintf(stderr, "Unable to load source image\n");
return 1;
}
copy = copy_surface(source);
SDL_BlitSurface(copy, 0, screen, 0);
SDL_Flip(screen);
while (SDL_WaitEvent(&event))
if (event.type == SDL_QUIT
|| (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE))
break;
SDL_Quit();
return 0;
}
You'll need source.png. I'm using a 400x400 transparent PNG with some black scribbling.