SDL_image PNG透明度错误

时间:2011-11-06 12:36:02

标签: image animation graphics sdl sprite

我正在将PNG文件(带有一些透明的地方)加载到我的SDL应用程序中。

谷歌搜索如何做到这一点为我提供了这个代码示例:

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;
}

但是当到达行compatible_image = SDL_DisplayFormat(loaded_image);时,应用程序会因无法捕获的异常而停止(即使try { /* ... */ } catch (...) { /* ... */ }也无效)。用SDL_DisplayFormat()替换SDL_DisplayFormatAlpha()也无济于事。所以,我刚刚删除了异常可扩展的行并使这段代码能够加载图像:

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

    return IMG_Load(filename.c_str());
}

我发现了这样的不愉快的事情:当一些精灵与另一个精灵的透明碎片重叠时,会出现伪影。像这样:

normal state

artifacts appearing

我用这个简单的算法为我的“英雄”制作动画:

// 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);

如何解释和解决这个问题?

3 个答案:

答案 0 :(得分:6)

使用SDL_DisplayFormatAlpha代替SDL_DisplayFormat。它恰当地保留了透明度。

答案 1 :(得分:1)

不确定这是否是问题,但您应该确保在SDL_DisplayFormat之前调用SDL_Init

答案 2 :(得分:1)

找到一个解决方案:当绘制一个带有透明碎片的瓷砖并在第一个瓷砖的顶部绘制另一个精灵时,会出现工件。当然他们会,因为第一个精灵背后没有任何东西!

第一个也是最快速的解决方法是在任何进一步的blitting之前用一些颜色填充整个背景。

第二种也是最美丽的方式(在我的例子中)是绘制一些背景图像(如图所示)。

结果如下:

first example

second example

如您所见,没有出现任何文物。干得好,我! =)