Graphical artifacts with opengl when renderering to back buffer in Windows

I am creating a game engine where the UI and scene is rendered to two separate textures and then the textures are overlaid on top of one another and presented to the renderer. This let’s me render the UI at a higher resolution than the scene. I do most of dev and testing on linux using opengl and so far so good - but I noticed when testing in Windows 10 that this causes graphical bugs.

I attached a screenshot, when the graphics change from frame to frame it is like the renderer is not completely cleared as some of the graphics from the prior frame still appears (like after burn image on an old TV). I noticed if I switch to direct3d for windows this goes away. Does anyone know why this happen? The issue with direct3d is that it limits the max texture size to 8192x8192.

Here is how I do the rendering every frame:

SDL_RenderClear(Game::renderer);

Game::sceneTexture = SDL_CreateTexture(Game::renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, Game::logicalWidth, Game::logicalHeight);
SDL_SetRenderTarget(Game::renderer, Game::sceneTexture);
[RENDER GAME SCENE]
Game::UITexture = SDL_CreateTexture(Game::renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, Game::screenWidth, Game::screenHeight);
SDL_SetRenderTarget(Game::renderer, Game::UITexture);
[RENDER UI]
//Render everything to screen
SDL_SetRenderTarget(Game::renderer, nullptr);

SDL_RenderCopy(Game::renderer, Game::sceneTexture, nullptr, nullptr);

SDL_SetTextureBlendMode(Game::UITexture, SDL_BLENDMODE_BLEND);
SDL_RenderCopy(Game::renderer, Game::UITexture, nullptr, nullptr);

SDL_RenderPresent(Game::renderer);

//Clean up
SDL_DestroyTexture(Game::sceneTexture);
SDL_DestroyTexture(Game::UITexture);

The curious thing is this only affects the rendering of Game::UITexture, but not sceneTexture. I noticed this is even true when the logical and screen resolutions are the same. I.E., if I only render the scene but not the UI the artifacts don’t appear.

Capture

My understanding is that you are recommended to call SDL_RenderClear() even though you subsequently SDL_RenderCopy() onto the entire canvas. I do that and have never seen the effect you describe, using OpenGL in Windows.

Hi rtrussel,

I am using SDL_RenderClear at the top of every frame, are you suggesting I do it another time?

No, but you didn’t show it in your listing so I assumed you weren’t doing it. It’s hard to understand how “the renderer is not completely cleared” if there’s a SDL_RenderClear(). Here is what I would have expected the code to look like:

//Render everything to screen
SDL_SetRenderTarget(Game::renderer, nullptr);

SDL_RenderClear(Game::renderer);
SDL_RenderCopy(Game::renderer, Game::sceneTexture, nullptr, nullptr);

SDL_SetTextureBlendMode(Game::UITexture, SDL_BLENDMODE_BLEND);
SDL_RenderCopy(Game::renderer, Game::UITexture, nullptr, nullptr);

SDL_RenderPresent(Game::renderer);