I recently separated my logic and rendering threads to fix this problem:
GLFW window freezes on title bar hold/drag
This means the logic and rendering are no longer running in lock-step as they were before, so it is possible that the logic has not finished executing by the time we are ready to render. To handle this case, the rendering thread will keep sleeping for 1ms until the logic has finished executing.
Pseudo-code
Logic thread
while (!exiting) {
timeBefore = now();
updateGame();
renderingDue = true;
timeElapsed = now() - timeBefore;
sleep(MS_PER_FRAME - timeElapsed);
}
Rendering thread
while (!exiting) {
if (renderingDue) {
render();
renderingDue = false;
GLFW.glfwSwapBuffers(window);
} else {
// Not yet ready to render, but try again in a short while
sleep(1);
}
}
This seems to work fine for me, at least with vsync disabled. When I tested with vsync enabled I encountered stuttering, which I suppose is because if we miss a rendering frame, we have to wait until the next monitor refresh interval before we can catch up.
However, on some other systems, in particular low-end laptops, there is a lot of flickering / tearing during gameplay. I don't understand what would cause this, since we are always calling glfwSwapBuffers()
after rendering, not during.
Is there something fundamentally wrong with my approach?
I know ideally the rendering thread should take a delta value so that it can render the state "between" logic threads (yes, I have read Fix Your Timestep!), but I am nonetheless curious about what is happening here.
sleep
is an issue here. How is the cpu percentage while your game is running? \$\endgroup\$