Search code examples
csdl-2

SDL - Old CRT scanlines without waste CPU time


I want to simulate old CRT scanlines but I can't find a way that permits to create scanlines layer only one time in order to avoid to waste CPU time for each main loop cycle.

Basically in my game I have this piece of code in the main loop cycle:

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

The for cycle that uses SDL_RenderDrawLine() creates one scanline for each 3 lines and the output is very good but... on hardware with low CPU performance it is slow.

So, I tried to use SDL_SetRenderTarget() with 2 textures and transparency, gameFrameTexture and scanlinesTexture, creating the scanlines directly on the texture and rendering the frame using SDL_RenderCopy() two times in the correct order. But in this way scanlines are stretched when SDL_RenderCopy() performs the copy between sourceRectangle and destinationRectangle (because texture doesn't have the dimension of the game window) so the output is very ugly with large (in terms of height) scanlines.

Is there a way to create the scanlines on the window, on the default renderer, only one time?

SOLUTION

As I tried before, the correct way is to use 2 textures, one for scanlines and the other one for game frame. BUT... the scanlines texture MUST have the final resolution (window or fullscreen) in order to avoid the stretch.

The important thing is to set SDL_BLENDMODE_BLEND for the texture with SDL_SetTextureBlendMode() and to set SDL_SetRenderDrawColor() with an alpha (transparency) value. In this way all drawing operations will use this color (i.e. scanlines will be black with a little amount of transparency)


Solution

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

    Create the texture dynamically as soon as you know the resolution, and then apply it with your proposed solution (copying to the render target twice with some opacity).