Last active
August 21, 2022 15:36
-
-
Save digital-synapse/b0b68478ad19a3b40ad77d0e62576f59 to your computer and use it in GitHub Desktop.
multi-threaded game loop in c++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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