Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SDL_image PNG transparency error

I am loading PNG file (with some transparent places) into my SDL application.

Googling on how to do it provided me with this code sample:

SDL_Surface *LoadImage(std::string filename)
{
    SDL_Surface* loaded_image = 0, compatible_image = 0;

    if (!filename.c_str())
        return 0;

    loaded_image = IMG_Load(filename.c_str());

    if (!loaded_image)
        return 0;

    compatible_image = SDL_DisplayFormat(loaded_image);

    SDL_FreeSurface(loaded_image);

    return compatible_image;
}

But when the line compatible_image = SDL_DisplayFormat(loaded_image); is reached, application halts with an uncatchable exception (even try { /* ... */ } catch (...) { /* ... */ } does not help). Replacing SDL_DisplayFormat() with SDL_DisplayFormatAlpha() did not help too. So, i just removed the exception-trowable lines and get this code working to load images:

SDL_Surface *LoadImage(std::string filename)
{
    if (!filename.c_str())
        return 0;

    return IMG_Load(filename.c_str());
}

And i've found such unpleasant thing: when some sprite overlaps with transparent pieces of another one, artifacts appear. Something like this:

normal state

artifacts appearing

I am animating my "hero" with this simple algorithm:

// SDL_Surface sprite = LoadImage("hero.bmp");
// hero.bmp contains animation frames followed one-by-one in a single line
// spriteFrameCnt is a number of animation frames
// spriteWidth and spriteHeight contain single frame params

SDL_Rect srcRect;
srcRect.x = spriteFrame * spriteWidth;
srcRect.w = spriteWidth;
srcRect.y = 0;
srcRect.h = spriteHeight;
spriteFrame = ++spriteFrame % spriteFrameCnt;

SDL_BlitSurface(sprite, &srcRect, screen, &rcSprite);

How can this be explained and fixed?

like image 404
shybovycha Avatar asked Nov 06 '11 12:11

shybovycha


2 Answers

Use SDL_DisplayFormatAlpha instead of SDL_DisplayFormat. It properly preserves the transparency.

like image 59
TheBuzzSaw Avatar answered Oct 06 '22 00:10

TheBuzzSaw


Not sure if this is the problem, but you should make sure you're calling SDL_Init before SDL_DisplayFormat

like image 22
btmorex Avatar answered Oct 06 '22 01:10

btmorex