#include #include #include "voxel.h" #include "window.h" World world; Camera camera; void sleep(double seconds) { struct timespec req, rem; req.tv_sec = seconds; req.tv_nsec = 0; if (seconds < 0) return; while (thrd_sleep(&req, &rem) == thrd_error) req = rem; } /// handles rendering VOXEL_RESULT render_main(void *) { Renderer renderer; if (window_init_gl() != VOXEL_OK) return VOXEL_ERROR; if (renderer_init(&renderer) != VOXEL_OK) return VOXEL_ERROR; while (!window_closed()) { if (window.resize) { glViewport(0, 0, window.width, window.height); window.resize = false; } renderer_start(&renderer, &camera); world_render(&world, &renderer); renderer_stop(&renderer); window_swap(); } renderer_free(&renderer); return VOXEL_OK; } #define TPS 20 /// handles game logic VOXEL_RESULT logic_main(void *) { double last_tick, next_tick; last_tick = 0; next_tick = 0; while (!window_closed()) { world_update(&world, &camera); next_tick = last_tick + (1.0 / TPS); sleep(next_tick - last_tick); last_tick = next_tick; } return VOXEL_OK; } /// handles user input VOXEL_RESULT input_main(void *) { double last_tick, next_tick; last_tick = 0; next_tick = 0; while (!window_closed()) { window_update(); if (key_down(GLFW_KEY_ESCAPE)) { window.close = true; break; } camera_update(&camera); next_tick = last_tick + (1.0 / TPS); sleep(next_tick - last_tick); last_tick = next_tick; } return VOXEL_OK; } VOXEL_RESULT main(void) { thrd_t render_thread, logic_thread, input_thread; if (window_init() != VOXEL_OK) return VOXEL_ERROR; camera_init(&camera); world_init(&world, 0); thrd_create(&logic_thread, logic_main, NULL); thrd_create(&input_thread, input_main, NULL); thrd_create(&render_thread, render_main, NULL); thrd_join(logic_thread, NULL); thrd_join(input_thread, NULL); thrd_join(render_thread, NULL); world_free(&world); window_close(); return VOXEL_OK; }