summaryrefslogtreecommitdiff
path: root/app/include/gfx/app.h
blob: ffff4bcadbddf9833163ab9b88fd528dc5d80034 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#pragma once

#include <stdbool.h>

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;                                                               \
  }