SDL_image PNG透明度错误

shy*_*cha 5 graphics animation sdl image 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;
}
Run Code Online (Sandbox Code Playgroud)

但是当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());
}
Run Code Online (Sandbox Code Playgroud)

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

正常状态

出现的文物

我用这个简单的算法动画我的"英雄":

// 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);
Run Code Online (Sandbox Code Playgroud)

如何解释和修复?

The*_*Saw 6

SDL_DisplayFormatAlpha而不是SDL_DisplayFormat.它恰当地保留了透明度.


shy*_*cha 1

找到了解决方案:当绘制带有透明块的图块并在第一个图块的顶部绘制另一个精灵时,会出现伪影。他们当然会的,因为第一个精灵后面什么都没有!

第一个也是最快的修复方法是在进行任何进一步的位块传送之前用某种颜色填充整个背景。

第二种也是最漂亮的方法(就我而言)是绘制一些背景图像(如图所示的草)。

结果如下:

第一个例子

第二个例子

正如您所看到的,没有出现任何伪影。干得好,我!=)