1
\$\begingroup\$

Whenever I call SDL_RenderPresent, the previous frame is replaced with black before the new frame is displayed. It's almost like when I call SDL_RenderPresent(renderer), it automatically calls SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255) and thenSDL_RenderClear(renderer).

I want to keep the previous frame because only 100 pixels are changed per frame. How do I prevent it from writing over the previous frame?

Here's an example:

// Error checking removed for clarity
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("title", 0, 0, width, height, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

// after some other, non-SDL related stuff, I run this code:
SDL_Rect a = {
    .x = 0,
    .y = 0,
    .w = 100,
    .h = 100
};
SDL_Rect b = {
    .x = 200,
    .y = 0,
    .w = 100,
    .h = 100
};

SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0x00);
SDL_RenderClear(renderer);

SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
SDL_RenderDrawRect(renderer, &a);
SDL_RenderPresent(renderer);
// A red outline of a square is displayed on a white background
SDL_Delay(2500);

SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
SDL_RenderDrawRect(renderer, &b);
SDL_RenderPresent(renderer);
// A green outline of a square is displayed on a black background.
// The red outline is gone.
SDL_Delay(2500);

How do I prevent SDL_RenderPresent from painting over the previous frame with black? Why is it doing that even though I'm not telling it to clear between the presents?

\$\endgroup\$
  • 4
    \$\begingroup\$ Read the documentation: wiki.libsdl.org/SDL_RenderPresent "The backbuffer should be considered invalidated after each present; do not assume that previous contents will exist between frames" - this is actually normal and desirable behaviour when drawing because graphics cards can optimize better if they don't have to preserve the previous frame. Even if only a few pixels change it's a false optimization and you should always just redraw the full scene each frame. \$\endgroup\$ – Maximus Minimus May 5 '17 at 23:17
1
\$\begingroup\$

To get past this, you might be able to use a texture buffer which you render to before rendering to the window. This is accomplished with creating a texture with SDL_TEXTUREACCESS_TARGET, and using SDL_SetRenderTarget.

A link with an example can be found here: https://gamedev.stackexchange.com/a/143394/95877

Note: I do not know the intricacies of this, and the wording does not state this "backbuffer" only applies to a window, but since SDL_RenderClear only clears the current rendering target with the current color, if you do not call this on a texture, I see no reason the texture itself would ever be invalidated, as it is a texture of course.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.