summaryrefslogtreecommitdiff
path: root/gfx-iso/src/app.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-08-31 18:58:39 -0700
committer3gg <3gg@shellblade.net>2024-08-31 18:58:39 -0700
commitdaf6262c029892212f6b9b4014887c2c37e9ef75 (patch)
tree40b24f4f23cc48e55c3511c28c7bef29834d61b3 /gfx-iso/src/app.c
parent0a78a9d9c1ac2090da56f395d6f2394a8a210010 (diff)
Handle resizing.
Diffstat (limited to 'gfx-iso/src/app.c')
-rw-r--r--gfx-iso/src/app.c196
1 files changed, 0 insertions, 196 deletions
diff --git a/gfx-iso/src/app.c b/gfx-iso/src/app.c
deleted file mode 100644
index 2f2241f..0000000
--- a/gfx-iso/src/app.c
+++ /dev/null
@@ -1,196 +0,0 @@
1#include <isogfx/app.h>
2#include <isogfx/isogfx.h>
3
4#include <gfx/app.h>
5#include <gfx/core.h>
6#include <gfx/gfx.h>
7#include <gfx/renderer.h>
8#include <gfx/scene.h>
9#include <gfx/util/geometry.h>
10#include <gfx/util/shader.h>
11
12#include <assert.h>
13#include <stdbool.h>
14#include <stdlib.h>
15
16static const int WINDOW_WIDTH = 1408;
17static const int WINDOW_HEIGHT = 960;
18static const int MAX_FPS = 60;
19
20typedef struct AppState {
21 Gfx* gfx;
22 IsoGfx* iso;
23 IsoGfxApp* app;
24 Texture* screen_texture;
25 Scene* scene;
26} AppState;
27
28typedef struct GfxAppState {
29 AppState state;
30} GfxAppState;
31
32static bool init(GfxAppState* gfx_app_state, int argc, const char** argv) {
33 assert(gfx_app_state);
34 AppState* state = &gfx_app_state->state;
35
36 IsoGfxApp* app = state->app;
37
38 // Virtual screen dimensions.
39 const int scale = app->pixel_scale == 0 ? 1 : app->pixel_scale;
40 const int screen_width = WINDOW_WIDTH / scale;
41 const int screen_height = WINDOW_HEIGHT / scale;
42
43 if (!(state->iso = isogfx_new(&(IsoGfxDesc){
44 .screen_width = screen_width, .screen_height = screen_height}))) {
45 goto cleanup;
46 }
47
48 if (!(*app->init)(app->state, state->iso, argc, argv)) {
49 goto cleanup;
50 }
51
52 isogfx_resize(state->iso, screen_width, screen_height);
53
54 if (!(state->gfx = gfx_init())) {
55 goto cleanup;
56 }
57 GfxCore* gfxcore = gfx_get_core(state->gfx);
58
59 if (!(state->screen_texture = gfx_make_texture(
60 gfxcore, &(TextureDesc){
61 .width = screen_width,
62 .height = screen_height,
63 .dimension = Texture2D,
64 .format = TextureSRGBA8,
65 .filtering = NearestFiltering,
66 .wrap = ClampToEdge,
67 .mipmaps = false}))) {
68 goto cleanup;
69 }
70
71 ShaderProgram* shader = gfx_make_view_texture_shader(gfxcore);
72 if (!shader) {
73 goto cleanup;
74 }
75
76 Geometry* geometry = gfx_make_quad_11(gfxcore);
77 if (!geometry) {
78 goto cleanup;
79 }
80
81 MaterialDesc material_desc = (MaterialDesc){.num_uniforms = 1};
82 material_desc.uniforms[0] = (ShaderUniform){
83 .type = UniformTexture,
84 .value.texture = state->screen_texture,
85 .name = sstring_make("Texture")};
86 Material* material = gfx_make_material(&material_desc);
87 if (!material) {
88 return false;
89 }
90
91 const MeshDesc mesh_desc =
92 (MeshDesc){.geometry = geometry, .material = material, .shader = shader};
93 Mesh* mesh = gfx_make_mesh(&mesh_desc);
94 if (!mesh) {
95 goto cleanup;
96 }
97
98 SceneObject* object =
99 gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}});
100 if (!object) {
101 goto cleanup;
102 }
103
104 state->scene = gfx_make_scene();
105 SceneNode* node = gfx_make_object_node(object);
106 SceneNode* root = gfx_get_scene_root(state->scene);
107 gfx_set_node_parent(node, root);
108
109 return true;
110
111cleanup:
112 if (state->gfx) {
113 gfx_destroy(&state->gfx);
114 }
115 free(state);
116 return false;
117}
118
119static void shutdown(GfxAppState* gfx_app_state) {
120 assert(gfx_app_state);
121 AppState* state = &gfx_app_state->state;
122
123 if (state->app) {
124 assert(state->iso);
125 (*state->app->shutdown)(state->app->state, state->iso);
126 }
127
128 isogfx_del(&state->iso);
129 gfx_destroy(&state->gfx);
130}
131
132static void update(GfxAppState* gfx_app_state, double t, double dt) {
133 assert(gfx_app_state);
134 AppState* state = &gfx_app_state->state;
135
136 isogfx_update(state->iso, t);
137
138 assert(state->app->update);
139 (*state->app->update)(state->app->state, state->iso, t, dt);
140}
141
142static void render(GfxAppState* gfx_app_state) {
143 assert(gfx_app_state);
144 AppState* state = &gfx_app_state->state;
145
146 assert(state->app->render);
147 (*state->app->render)(state->app->state, state->iso);
148
149 const Pixel* screen = isogfx_get_screen_buffer(state->iso);
150 assert(screen);
151 gfx_update_texture(
152 state->screen_texture, &(TextureDataDesc){.pixels = screen});
153
154 GfxCore* gfxcore = gfx_get_core(state->gfx);
155 Renderer* renderer = gfx_get_renderer(state->gfx);
156
157 // TODO: Prevent stretching of the virtual screen onto the window; preserve
158 // aspect ratio.
159 gfx_start_frame(gfxcore);
160 gfx_render_scene(
161 renderer, &(RenderSceneParams){
162 .mode = RenderDefault, .scene = state->scene, .camera = 0});
163 gfx_end_frame(gfxcore);
164}
165
166static void resize(GfxAppState* gfx_app_state, int width, int height) {
167 assert(gfx_app_state);
168 AppState* state = &gfx_app_state->state;
169
170 GfxCore* gfxcore = gfx_get_core(state->gfx);
171 gfx_set_viewport(gfxcore, width, height);
172}
173
174void iso_run(int argc, const char** argv, IsoGfxApp* app) {
175 GfxAppState app_state = {
176 .state = (AppState){
177 .app = app,
178 }
179 };
180 gfx_app_run(
181 &(GfxAppDesc){
182 .argc = argc,
183 .argv = argv,
184 .width = WINDOW_WIDTH,
185 .height = WINDOW_HEIGHT,
186 .max_fps = MAX_FPS,
187 .update_delta_time = MAX_FPS > 0 ? 1.0 / (double)MAX_FPS : 0.0,
188 .title = "Isometric Renderer",
189 .app_state = &app_state},
190 &(GfxAppCallbacks){
191 .init = init,
192 .update = update,
193 .render = render,
194 .resize = resize,
195 .shutdown = shutdown});
196}