c++ /SDL:褪去已经具有逐像素alpha信息的表面



假设我们有一个32位的PNG文件,其中有一些幽灵/无形的角色,以半透明的方式绘制。它不是在每个地方都是透明的,所以当我们把它加载到一个表面时,我们需要每像素的alpha信息。

对于渐入渐出,设置整个表面的alpha值是一个很好的方法;但不是在这种情况下,因为表面已经有逐像素信息,而SDL没有将两者结合起来。

什么是有效的解决方法(而不是要求美工为角色提供一些很棒的淡入/淡出动画)?

我认为实现你想要的结果的最简单方法是首先加载包含你的角色精灵的source表面,然后,为你的幽灵的每个实例创建表面的working副本。你要做的是每次一个实例的alpha值改变,SDL_BlitSurface (doc)你的source到你的working副本,然后应用你的透明度(你可能应该保持为0和1之间的浮动),然后在每个像素的alpha通道上应用你的透明度。

在32位表面的情况下,假设您最初加载了source并分配了working SDL_Surface s,您可能会执行以下操作:

SDL_BlitSurface(source, NULL, working, NULL);
if(SDL_MUSTLOCK(working)) 
{
    if(SDL_LockSurface(working) < 0) 
    {
        return -1;
    }
}
Uint8 * pixels = (Uint8 *)working->pixels;
pitch_padding = (working->pitch - (4 * working->w));
pixels += 3; // Big Endian will have an offset of 0, otherwise it's 3 (R, G and B)
for(unsigned int row = 0; row < working->h; ++row) 
{
    for(unsigned int col = 0; col < working->w; ++col) 
    {
        *pixels = (Uint8)(*pixels * character_transparency); // Could be optimized but probably not worth it
        pixels += 4;
    }
    pixels += pitch_padding;
}
if(SDL_MUSTLOCK(working)) 
{
    SDL_UnlockSurface(working);
}

这段代码的灵感来自SDL_gfx(这里),但如果你只是这样做,我不会为此费心链接到一个库。

最新更新