SDL - 不浪费 CPU 时间的旧 CRT 扫描线

SDL - Old CRT scanlines without waste CPU time

我想模拟旧的 CRT 扫描线,但我找不到一种方法只允许创建扫描线层一次,以避免在每个主循环周期浪费 CPU 时间。

基本上在我的游戏中,我在主循环周期中有这段代码:

createTExture();

SDL_RenderClear(windowRenderer);

SDL_RenderCopy(windowRenderer, gameFrameTexture, &sourceRectangle, &destinationRectangle);

// Scanlines
if (scanlines)
{
    for (i = 0; i < destinationRectangle.h; i += 3)
    {
        SDL_RenderDrawLine(windowRenderer, destinationRectangle.x, destinationRectangle.y + i, destinationRectangle.x + destinationRectangle.w, destinationRectangle.y + i);
    }
}

SDL_RenderPresent(windowRenderer);

使用 SDL_RenderDrawLine()for 循环为每 3 行创建一个扫描线,输出非常好但是...在 CPU 性能低的硬件上它很慢。

因此,我尝试将 SDL_SetRenderTarget() 与 2 个纹理和透明度一起使用,gameFrameTexturescanlinesTexture,直接在纹理上创建扫描线并使用 [=17= 渲染帧] 按正确顺序重复两次。但是这样当 SDL_RenderCopy()sourceRectangledestinationRectangle 之间执行复制时扫描线被拉伸(因为纹理没有游戏的维度 window)所以输出是大扫描线(就高度而言)非常难看。

有没有办法在 window、默认渲染器上仅创建一次扫描线?

解决方案

正如我之前尝试的那样,正确的方法是使用 2 个纹理,一个用于扫描线,另一个用于游戏帧。 但是...扫描线纹理必须具有最终分辨率(window 或全屏)以避免拉伸。

重要的是为纹理设置 SDL_BLENDMODE_BLEND SDL_SetTextureBlendMode() 并使用 alpha(透明度)值设置 SDL_SetRenderDrawColor()。通过这种方式,所有绘图操作都将使用这种颜色(即扫描线将是黑色并具有少量透明度)

But in this way scanlines are stretched ... (because texture doesn't have the dimension of the game window)

知道分辨率后立即动态创建纹理,然后将其与您建议的解决方案一起应用(使用一些不透明度复制到渲染目标两次)。