Skip to content

Instantly share code, notes, and snippets.

@digital-synapse
Last active August 21, 2022 15:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digital-synapse/b0b68478ad19a3b40ad77d0e62576f59 to your computer and use it in GitHub Desktop.
Save digital-synapse/b0b68478ad19a3b40ad77d0e62576f59 to your computer and use it in GitHub Desktop.
multi-threaded game loop in c++
int main(int argc, char* argv[])
{
if (!init()) return 1;
world.load();
player.load();
// launch game logic loop on a seperate thread
// this will handle update logic, animations, collision detection, etc
// and will run on a seperate CPU core than the main UI thread
// update thread manages its own update frequency by measuring
// execution time of each loop, and yielding any remaining time
// with thread_sleep to cap the update frequency at 50hz
// note: for the purposes of this simple example
// we are only using 1 update thread but you could also easily
// split this up into multiple threads. for example. one thread
// could be dedicated for physics, another for animations, another
// for AI/pathfinding etc. If you wanted you could utilize all
// 4/8/16 CPU cores in this way.
std::thread update_thread(update);
// run the render loop in process on the main UI thread
// this will handle updating the screen at 60 FPS
// the render loop will wait for vsync which is the refresh
// signal from the monitor/video card the the screen is about
// to redraw. Most monitors vsync at 60hz but some can vsync at 50, 40, 80, 120, etc
// in addition to waiting for vsync we are also capping the render loop at 60hz
render();
// Clean up
update_thread.join(); // wait for thread to finish
deinit(); // dealloc all resoures
return 0;
}
void render() {
const uint64_t nanos_60fps = 16666666;
while (running) {
uint64_t start_nanos = nanos();
// Redraw
world.render(display_buffer);
wait_vsync(); // wait for refresh signal from monitor (usually 60 hz)
flip(display_buffer); // draw screen (double buffering)
uint64_t end_nanos = nanos();
uint64_t elapsed_nanos = end_nanos - start_nanos;
// wait for 60 FPS
if (elapsed_nanos < nanos_60fps) {
nanosleep(nanos_60fps - elapsed_nanos); // yield remaining CPU time
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment