#pragma once #include 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. GfxAppState* app_state; } GfxAppDesc; typedef bool (*GfxAppInit)(GfxAppState*, int argc, const char** argv); typedef void (*GfxAppShutdown)(GfxAppState*); typedef void (*GfxAppUpdate)(GfxAppState*, double t, double dt); typedef void (*GfxAppRender)(GfxAppState*); typedef void (*GfxAppResize)(GfxAppState*, int width, int height); /// Application callback functions. typedef struct GfxAppCallbacks { GfxAppInit init; GfxAppShutdown shutdown; GfxAppUpdate update; GfxAppRender render; GfxAppResize resize; } GfxAppCallbacks; typedef enum Key { KeyA = 'a', KeyB, KeyC, KeyD, KeyE, KeyF, KeyG, KeyH, KeyI, KeyJ, KeyK, KeyL, KeyM, KeyN, KeyO, KeyP, KeyQ, KeyR, KeyS, KeyT, KeyU, KeyV, KeyW, KeyX, KeyY, KeyZ, } Key; /// Create a window with an OpenGL context and run the main loop. bool gfx_app_run(const GfxAppDesc*, const GfxAppCallbacks*); /// Get the mouse coordinates relative to the app's window. void gfx_app_get_mouse_position(double* x, double* y); /// Return true if the given key is pressed. bool gfx_is_key_pressed(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 = (GfxAppInit)app_init, \ .update = (GfxAppUpdate)app_update, \ .render = (GfxAppRender)app_render, \ .resize = (GfxAppResize)app_resize, \ .shutdown = (GfxAppShutdown)app_end}); \ return 0; \ }