SDL_image PNG 透明度错误

5

我正在将一张PNG文件(其中有一些透明的区域)加载到我的SDL应用程序中。

在Google上搜索如何做到这一点,我找到了以下代码示例:

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

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

正常状态

出现伪影

我正在使用这个简单算法对我的“英雄”进行动画处理:

// 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个回答

6
使用SDL_DisplayFormatAlpha而不是SDL_DisplayFormat。它可以正确地保留透明度。

1

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


是的,现在异常没有被抛出。感谢你。但无论我如何尝试,工件都不会消失... - shybovycha

1

找到了解决方案:当绘制具有透明部件的瓷砖并在第一个瓷砖上方绘制另一个精灵时,会出现伪影。当然会出现,因为第一个精灵后面没有任何东西!

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

第二种最美丽的方式(在我的情况下)是绘制一些背景图像(如所示的草地)。

以下是结果:

first example

second example

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接