SDL混合导致不正确的帧插值

时间:2016-06-27 17:47:26

标签: c++ graphics sdl alphablending

在使用SDL中的粒子引擎时,我偶然发现了以下问题:

在实现了here所描述的帧插值技术之后(步骤6:优化,我基本上将当前帧的最后一帧绘制为254的alpha值),以便淡出),I注意到一些像素应该逐渐从白色变为黑色,最终保持灰色,rgba值为112。在做了一些数学运算之后,我发现了导致这种情况的原因:每一帧我将最后一帧的rgba值乘以254/255,这可以很好地处理和排除112.

然后发生了一些有趣的事情。当您执行以下操作:round(112/255 * 254)= 112时,值将保持不变(我将数字四舍五入,因为结束值将存储为像素的8位颜色值),这意味着我使用alpha的淡化技术不再适用。 问题是我希望这些灰色像素保持在112以进一步淡出。问题是,我如何在SDL中实现这样的目标?

我知道我可以将254的值降低,这样这种最小值会减少,但我希望我的粒子能够轻轻地淡出(我正在制作一个60fps的游戏)。我自己也考虑过创建一个OpenGL图形引擎(这样我就可以使用浮点纹理,在这种情况下我需要精确度),但是我在OpenGL上的表现还不够好而且缺乏是时候做这样的事了。 我需要使用纹理进行存储的原因是我希望有粒子发出痕迹(好像你停止清除帧缓冲区并移动了一个对象,但是不是屏幕变得混乱,旧的像素会淡出)

                currentFrame->renderTo();//Draw to the current frame rendertarget
                graphics.clear(Color(0,0,0,0)); //Clear the screen using the given color
                graphics.scale=1.0f; //Manipulate pixel size (for visible pixel art)
                SDL_SetTextureBlendMode(lastFrame->texture, SDL_BLENDMODE_NONE); 
                //Set blendmode to opaque
                graphics.drawTexture(lastFrame,graphics.camera.position,Color(255,255,255,254));
                //Draw the last frame 
                SDL_SetTextureBlendMode(lastFrame->texture, SDL_BLENDMODE_BLEND);
                //Revert blendmode to alpha blending

1 个答案:

答案 0 :(得分:1)

我会使用一个名为'decay'的全局浮点变量来存储非舍入的alpha值。

float decay = 255.0;
[...]
decay  = decay / 255.0 * 254.0;
Uint8 alpha = round(decay);

如果每个像素需要一个'衰变'值,那么你可以为粒子声明一个结构:

typedef struct {
    int active;
    float x,y;
    float dx,dy; // directions for x and y
    float decay;
    Uint8 r,g,b,a; // colour
} s_dots;

s_dots dots[MAX_NUMBER_OF_DOTS];