From 456d7f883ca34ec83692ff3879ca5f5717e82b33 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 2 May 2026 14:59:18 -0700 Subject: Use the simloop library --- app/CMakeLists.txt | 1 + app/demo/main.c | 11 ++++++----- app/include/gfx/app.h | 54 +++++++++++++++++++++++++-------------------------- app/src/app.c | 46 ++++++++++++++++--------------------------- 4 files changed, 51 insertions(+), 61 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 021a77d..b88219a 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(gfx-app PUBLIC glad glfw log + simloop timer) add_subdirectory(demo) diff --git a/app/demo/main.c b/app/demo/main.c index 0aa4e34..2efca7c 100644 --- a/app/demo/main.c +++ b/app/demo/main.c @@ -2,10 +2,11 @@ #include -const int WIDTH = 960; -const int HEIGHT = 600; -const int MAX_FPS = 60; -const char* TITLE = "iso3d"; +const int WIDTH = 960; +const int HEIGHT = 600; +const int UPDATE_FPS = 60; +const int MAX_FPS = 60; +const char* TITLE = "iso3d"; typedef struct GfxAppState { int unused; @@ -47,4 +48,4 @@ void Resize(GfxApp* app, GfxAppState* state, int width, int height) { (void)height; } -GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS, TITLE) +GFX_APP_MAIN(WIDTH, HEIGHT, UPDATE_FPS, MAX_FPS, TITLE) diff --git a/app/include/gfx/app.h b/app/include/gfx/app.h index 3017707..42fccec 100644 --- a/app/include/gfx/app.h +++ b/app/include/gfx/app.h @@ -5,13 +5,13 @@ typedef struct GfxAppState GfxAppState; /// Application settings. typedef struct GfxAppDesc { - int argc; // Number of application arguments. - const char** argv; // Application arguments. - int width; // Window width. - int height; // Window height. - int max_fps; // Desired maximum display framerate. 0 to disable. - double update_delta_time; // Desired delta time between frame updates. - const char* title; // Window title. + int argc; // Number of application arguments. + const char** argv; // Application arguments. + int width; // Window width. + int height; // Window height. + int update_fps; // Desired frame update frequency. + int max_render_fps; // Desired maximum render frame rate. 0 to disable. + const char* title; // Window title. GfxAppState* app_state; } GfxAppDesc; @@ -88,24 +88,24 @@ bool gfx_app_is_key_pressed(GfxApp*, Key); /// Define a main function that initializes and puts the application in a loop. /// See also: gfx_app_run(). -#define GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS, TITLE) \ - int main(int argc, const char** argv) { \ - GfxAppState app_state = {0}; \ - gfx_app_run( \ - &(GfxAppDesc){ \ - .argc = argc, \ - .argv = argv, \ - .width = WIDTH, \ - .height = HEIGHT, \ - .max_fps = MAX_FPS, \ - .update_delta_time = MAX_FPS > 0 ? 1.0 / (double)MAX_FPS : 0.0, \ - .title = TITLE, \ - .app_state = &app_state, \ - }, \ - &(GfxAppCallbacks){.init = Init, \ - .shutdown = Shutdown, \ - .update = Update, \ - .render = Render, \ - .resize = Resize}); \ - return 0; \ +#define GFX_APP_MAIN(WIDTH, HEIGHT, UPDATE_FPS, MAX_RENDER_FPS, TITLE) \ + int main(int argc, const char** argv) { \ + GfxAppState app_state = {0}; \ + gfx_app_run( \ + &(GfxAppDesc){ \ + .argc = argc, \ + .argv = argv, \ + .width = WIDTH, \ + .height = HEIGHT, \ + .update_fps = UPDATE_FPS, \ + .max_render_fps = MAX_RENDER_FPS, \ + .title = TITLE, \ + .app_state = &app_state, \ + }, \ + &(GfxAppCallbacks){.init = Init, \ + .shutdown = Shutdown, \ + .update = Update, \ + .render = Render, \ + .resize = Resize}); \ + return 0; \ } diff --git a/app/src/app.c b/app/src/app.c index 8262378..c056ddd 100644 --- a/app/src/app.c +++ b/app/src/app.c @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -13,9 +14,8 @@ typedef struct GfxApp { GfxAppState* app_state; GfxAppCallbacks callbacks; - int max_fps; - double update_delta_time; GLFWwindow* window; + Simloop simloop; } GfxApp; /// Storing the application state in a global variable so that we can call the @@ -32,17 +32,9 @@ static void loop(GfxApp* app) { assert(app); assert(app->window); - const time_delta min_frame_time = - app->max_fps > 0 ? time_delta_from_sec(1.0 / (double)(app->max_fps)) : 0; - const time_delta update_dt = time_delta_from_sec(app->update_delta_time); - time_delta time = 0; - time_delta time_budget = 0; - Timer timer = timer_make(); - - // Warm up the update to initialize the application's state. - (*app->callbacks.update)( - app, app->app_state, time_delta_to_sec(time), - time_delta_to_sec(update_dt)); + time_delta time = 0; + Timer timer = timer_make(); + SimloopOut simout = {}; // Warm up the rendering before entering the main loop. A renderer can // compile shaders and do other initialization the first time it renders a @@ -53,25 +45,21 @@ static void loop(GfxApp* app) { timer_start(&timer); while (!glfwWindowShouldClose(app->window)) { timer_tick(&timer); - time_budget += timer.delta_time; + simloop_update(&app->simloop, timer.delta_time, &simout); + + glfwPollEvents(); - while (time_budget >= update_dt) { + if (simout.should_update) { (*app->callbacks.update)( app, app->app_state, time_delta_to_sec(time), - time_delta_to_sec(update_dt)); - - time += update_dt; - time_budget -= update_dt; + time_delta_to_sec(simout.update_dt)); } (*app->callbacks.render)(app, app->app_state); glfwSwapBuffers(app->window); - glfwPollEvents(); - const time_point frame_end = time_now(); - const time_delta frame_time = time_diff(timer.last_tick, frame_end); - if ((min_frame_time > 0) && (frame_time < min_frame_time)) { - time_sleep(min_frame_time - frame_time); + if (simout.throttle > 0) { + time_sleep(simout.throttle); } } } @@ -82,11 +70,9 @@ bool gfx_app_run(const GfxAppDesc* desc, const GfxAppCallbacks* callbacks) { bool success = false; - g_gfx_app.app_state = desc->app_state; - g_gfx_app.callbacks = *callbacks; - g_gfx_app.max_fps = desc->max_fps; - g_gfx_app.update_delta_time = desc->update_delta_time; - g_gfx_app.window = nullptr; + g_gfx_app.app_state = desc->app_state; + g_gfx_app.callbacks = *callbacks; + g_gfx_app.window = nullptr; if (!glfwInit()) { LOGE("glfwInit() failed"); @@ -138,6 +124,8 @@ bool gfx_app_run(const GfxAppDesc* desc, const GfxAppCallbacks* callbacks) { // Set GLFW callbacks now that the application has been initialized. glfwSetWindowSizeCallback(g_gfx_app.window, on_resize); + g_gfx_app.simloop = simloop_make(&(SimloopArgs){ + .update_fps = desc->update_fps, .max_render_fps = desc->max_render_fps}); loop(&g_gfx_app); (*g_gfx_app.callbacks.shutdown)(&g_gfx_app, g_gfx_app.app_state); -- cgit v1.2.3