Hey hey people,
I’ve been learning SDL2 for a while now and decided to share a simple way to turn on vsync & prevent screen tearing while software rendering and using just surface editing and SDL_UpdateWindowSurface function for drawing to the screen.
Everyone in the tutorials always writes there is no Vsync functionality for the software renderer & this was bothering me. So I started to think about it & came up with this simple dirty solution that turned out to be working fine. So here is how to do it:
The overall idea is to use accelerated renderer (as created with SDL_CreateRenderer ) that has vsync enabled as a trigger for SDL_UpdateWindowSurface
In the INIT section, after we created a window we create a normal accelerated renderer with vsync, assigned to that window.
accelerated_renderer=SDL_CreateRenderer(Main_Window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
But we won’t be using it for graphics at all.
Then we assign a surface to the window, as usual with software rendering:
SDL Surface * window = SDL_GetWindowSurface(Main_Window);
We then create a smallest texture only 1pix by 1pix:
texture = SDL_CreateTexture(accelerated_renderer, window->format->format, SDL_TEXTUREACCESS_STREAMING, 1, 1);
Also we create smallest SDL_Rect 1pix by 1pix:
SDL_Rect rect; rect.h=1; rect.w=1; rect.x=0; rect.y=0;
In the DRAW loop we put first the
SDL_RenderCopy(accelerated_renderer,texture,NULL, rect);
and then
SDL_RenderPresent(accelerated_renderer);
that will render single pixel texture (extremely fast) & then right after that we put our SDL_UpdateWindowSurface(window);
Why it works? - The accelerated_renderer gets “loaded” with the texture and ready to render. When we call RenderPresent it will wait for the beginning of vblank period and then render a single empty pixel. This will happen extremely fast(due to min texture) so the rest of the vblank period can be used by the following command, which is SDL_UpdateWindowSurface(window); So now the window update will happen in the remaining vblank period & no rendering artifacts will be seen on the screen.
And this is how you get a nice steady 60 fps software rendering without picture tearing.
Hope someone finds this trick useful.
Also, since this was my first post here - greetings to all of you.