diff options
Diffstat (limited to 'gltfview/src')
-rw-r--r-- | gltfview/src/game.c | 104 |
1 files changed, 54 insertions, 50 deletions
diff --git a/gltfview/src/game.c b/gltfview/src/game.c index d7352d4..f2e5a88 100644 --- a/gltfview/src/game.c +++ b/gltfview/src/game.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <unistd.h> // usleep; TODO Remove. | 24 | #include <unistd.h> // usleep; TODO Remove. |
25 | 25 | ||
26 | // Paths to various scene files. | 26 | // Paths to various scene files. |
27 | static const char* BOX = "/assets/models/box.gltf"; | 27 | static const char* BOX = "/assets/models/box.gltf"; |
28 | static const char* SUZANNE = "/assets/models/suzanne.gltf"; | 28 | static const char* SUZANNE = "/assets/models/suzanne.gltf"; |
29 | static const char* SPONZA = | 29 | static const char* SPONZA = |
30 | "/assets/glTF-Sample-Models/2.0/Sponza/glTF/Sponza.gltf"; | 30 | "/assets/glTF-Sample-Models/2.0/Sponza/glTF/Sponza.gltf"; |
@@ -37,8 +37,8 @@ static const char* DAMAGED_HELMET = | |||
37 | 37 | ||
38 | static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp"; | 38 | static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp"; |
39 | 39 | ||
40 | static ShaderProgram* load_shader(RenderBackend* render_backend, | 40 | static ShaderProgram* load_shader( |
41 | const char* view_mode) { | 41 | RenderBackend* render_backend, const char* view_mode) { |
42 | ShaderProgram* shader = 0; | 42 | ShaderProgram* shader = 0; |
43 | if (strcmp(view_mode, "debug") == 0) { | 43 | if (strcmp(view_mode, "debug") == 0) { |
44 | shader = gfx_make_debug3d_shader(render_backend); | 44 | shader = gfx_make_debug3d_shader(render_backend); |
@@ -59,23 +59,24 @@ static Texture* load_environment_map(RenderBackend* render_backend) { | |||
59 | return gfx_load_texture( | 59 | return gfx_load_texture( |
60 | render_backend, | 60 | render_backend, |
61 | &(LoadTextureCmd){ | 61 | &(LoadTextureCmd){ |
62 | .origin = TextureFromFile, | 62 | .origin = TextureFromFile, |
63 | .type = LoadCubemap, | 63 | .type = LoadCubemap, |
64 | .colour_space = sRGB, | 64 | .colour_space = sRGB, |
65 | .filtering = NearestFiltering, | 65 | .filtering = NearestFiltering, |
66 | .mipmaps = false, | 66 | .mipmaps = false, |
67 | .data.cubemap.filepaths = { | 67 | .data.cubemap.filepaths = { |
68 | mstring_make("/assets/skybox/clouds1/clouds1_east.bmp"), | 68 | mstring_make("/assets/skybox/clouds1/clouds1_east.bmp"), |
69 | mstring_make("/assets/skybox/clouds1/clouds1_west.bmp"), | 69 | mstring_make("/assets/skybox/clouds1/clouds1_west.bmp"), |
70 | mstring_make("/assets/skybox/clouds1/clouds1_up.bmp"), | 70 | mstring_make("/assets/skybox/clouds1/clouds1_up.bmp"), |
71 | mstring_make("/assets/skybox/clouds1/clouds1_down.bmp"), | 71 | mstring_make("/assets/skybox/clouds1/clouds1_down.bmp"), |
72 | mstring_make("/assets/skybox/clouds1/clouds1_north.bmp"), | 72 | mstring_make("/assets/skybox/clouds1/clouds1_north.bmp"), |
73 | mstring_make("/assets/skybox/clouds1/clouds1_south.bmp")}}); | 73 | mstring_make("/assets/skybox/clouds1/clouds1_south.bmp")} |
74 | }); | ||
74 | } | 75 | } |
75 | 76 | ||
76 | /// Creates an object to render the skyquad in the background. | 77 | /// Creates an object to render the skyquad in the background. |
77 | static SceneNode* make_skyquad_object_node(Game* game, | 78 | static SceneNode* make_skyquad_object_node( |
78 | const Texture* environment_map) { | 79 | Game* game, const Texture* environment_map) { |
79 | assert(game); | 80 | assert(game); |
80 | 81 | ||
81 | SceneObject* skyquad_object = | 82 | SceneObject* skyquad_object = |
@@ -92,12 +93,12 @@ static SceneNode* make_skyquad_object_node(Game* game, | |||
92 | } | 93 | } |
93 | 94 | ||
94 | /// Creates an environment light. | 95 | /// Creates an environment light. |
95 | static SceneNode* make_environment_light(Game* game, | 96 | static SceneNode* make_environment_light( |
96 | const Texture* environment_light) { | 97 | Game* game, const Texture* environment_light) { |
97 | assert(game); | 98 | assert(game); |
98 | 99 | ||
99 | Light* light = gfx_make_light(&(LightDesc){ | 100 | Light* light = gfx_make_light(&(LightDesc){ |
100 | .type = EnvironmentLightType, | 101 | .type = EnvironmentLightType, |
101 | .light = (EnvironmentLightDesc){.environment_map = environment_light}}); | 102 | .light = (EnvironmentLightDesc){.environment_map = environment_light}}); |
102 | if (!light) { | 103 | if (!light) { |
103 | return 0; | 104 | return 0; |
@@ -127,8 +128,8 @@ static bool load_skyquad(Game* game, SceneNode** node) { | |||
127 | } | 128 | } |
128 | 129 | ||
129 | /// Loads the 3D scene. | 130 | /// Loads the 3D scene. |
130 | static bool load_scene(Game* game, const char* scene_filepath, | 131 | static bool load_scene( |
131 | const char* view_mode) { | 132 | Game* game, const char* scene_filepath, const char* view_mode) { |
132 | assert(game); | 133 | assert(game); |
133 | 134 | ||
134 | game->camera = gfx_make_camera(); | 135 | game->camera = gfx_make_camera(); |
@@ -151,9 +152,10 @@ static bool load_scene(Game* game, const char* scene_filepath, | |||
151 | return false; | 152 | return false; |
152 | } | 153 | } |
153 | 154 | ||
154 | if (!gfx_load_scene(game->gfx, sky_node, shader, | 155 | if (!gfx_load_scene( |
155 | &(LoadSceneCmd){.origin = SceneFromFile, | 156 | game->gfx, sky_node, shader, |
156 | .filepath = scene_filepath})) { | 157 | &(LoadSceneCmd){ |
158 | .origin = SceneFromFile, .filepath = scene_filepath})) { | ||
157 | return false; | 159 | return false; |
158 | } | 160 | } |
159 | 161 | ||
@@ -164,14 +166,14 @@ static bool load_scene(Game* game, const char* scene_filepath, | |||
164 | static bool load_texture_debugger_scene(Game* game) { | 166 | static bool load_texture_debugger_scene(Game* game) { |
165 | assert(game); | 167 | assert(game); |
166 | 168 | ||
167 | Texture* texture = | 169 | Texture* texture = gfx_load_texture( |
168 | gfx_load_texture(game->render_backend, | 170 | game->render_backend, |
169 | &(LoadTextureCmd){.origin = TextureFromFile, | 171 | &(LoadTextureCmd){ |
170 | .type = LoadTexture, | 172 | .origin = TextureFromFile, |
171 | .filtering = LinearFiltering, | 173 | .type = LoadTexture, |
172 | .mipmaps = false, | 174 | .filtering = LinearFiltering, |
173 | .data.texture.filepath = | 175 | .mipmaps = false, |
174 | mstring_make(CLOUDS1_TEXTURE)}); | 176 | .data.texture.filepath = mstring_make(CLOUDS1_TEXTURE)}); |
175 | 177 | ||
176 | game->camera = gfx_make_camera(); | 178 | game->camera = gfx_make_camera(); |
177 | if (!game->camera) { | 179 | if (!game->camera) { |
@@ -191,12 +193,12 @@ static bool load_texture_debugger_scene(Game* game) { | |||
191 | } | 193 | } |
192 | 194 | ||
193 | MaterialDesc material_desc = (MaterialDesc){0}; | 195 | MaterialDesc material_desc = (MaterialDesc){0}; |
194 | material_desc.shader = shader; | 196 | material_desc.uniforms[0] = (ShaderUniform){ |
195 | material_desc.uniforms[0] = (ShaderUniform){.type = UniformTexture, | 197 | .type = UniformTexture, |
196 | .value.texture = texture, | 198 | .value.texture = texture, |
197 | .name = sstring_make("Texture")}; | 199 | .name = sstring_make("Texture")}; |
198 | material_desc.num_uniforms = 1; | 200 | material_desc.num_uniforms = 1; |
199 | Material* material = gfx_make_material(&material_desc); | 201 | Material* material = gfx_make_material(&material_desc); |
200 | if (!material) { | 202 | if (!material) { |
201 | return false; | 203 | return false; |
202 | } | 204 | } |
@@ -204,7 +206,8 @@ static bool load_texture_debugger_scene(Game* game) { | |||
204 | MeshDesc mesh_desc = (MeshDesc){0}; | 206 | MeshDesc mesh_desc = (MeshDesc){0}; |
205 | mesh_desc.geometry = geometry; | 207 | mesh_desc.geometry = geometry; |
206 | mesh_desc.material = material; | 208 | mesh_desc.material = material; |
207 | Mesh* mesh = gfx_make_mesh(&mesh_desc); | 209 | mesh_desc.shader = shader; |
210 | Mesh* mesh = gfx_make_mesh(&mesh_desc); | ||
208 | if (!mesh) { | 211 | if (!mesh) { |
209 | return false; | 212 | return false; |
210 | } | 213 | } |
@@ -224,7 +227,7 @@ static bool load_texture_debugger_scene(Game* game) { | |||
224 | 227 | ||
225 | bool game_new(Game* game, int argc, const char** argv) { | 228 | bool game_new(Game* game, int argc, const char** argv) { |
226 | // TODO: getopt() to implement proper argument parsing. | 229 | // TODO: getopt() to implement proper argument parsing. |
227 | const char* view_mode = argc > 1 ? argv[1] : ""; | 230 | const char* view_mode = argc > 1 ? argv[1] : ""; |
228 | const char* scene_filepath = argc > 2 ? argv[2] : DEFAULT_SCENE_FILE; | 231 | const char* scene_filepath = argc > 2 ? argv[2] : DEFAULT_SCENE_FILE; |
229 | 232 | ||
230 | game->gfx = gfx_init(); | 233 | game->gfx = gfx_init(); |
@@ -233,7 +236,7 @@ bool game_new(Game* game, int argc, const char** argv) { | |||
233 | } | 236 | } |
234 | 237 | ||
235 | game->render_backend = gfx_get_render_backend(game->gfx); | 238 | game->render_backend = gfx_get_render_backend(game->gfx); |
236 | game->renderer = gfx_get_renderer(game->gfx); | 239 | game->renderer = gfx_get_renderer(game->gfx); |
237 | 240 | ||
238 | game->scene = gfx_make_scene(game->gfx); | 241 | game->scene = gfx_make_scene(game->gfx); |
239 | if (!game->scene) { | 242 | if (!game->scene) { |
@@ -270,26 +273,27 @@ void game_update(Game* game, double t, double dt) { | |||
270 | game->elapsed -= 1.0; | 273 | game->elapsed -= 1.0; |
271 | } | 274 | } |
272 | Camera* camera = gfx_get_camera_camera(game->camera); | 275 | Camera* camera = gfx_get_camera_camera(game->camera); |
273 | spatial3_orbit(&camera->spatial, vec3_make(0, 0, 0), | 276 | spatial3_orbit( |
274 | /*radius=*/2, | 277 | &camera->spatial, vec3_make(0, 0, 0), |
275 | /*azimuth=*/t * 0.5, /*zenith=*/0); | 278 | /*radius=*/2, |
279 | /*azimuth=*/t * 0.5, /*zenith=*/0); | ||
276 | spatial3_lookat(&camera->spatial, vec3_make(0, 0, 0)); | 280 | spatial3_lookat(&camera->spatial, vec3_make(0, 0, 0)); |
277 | } | 281 | } |
278 | 282 | ||
279 | void game_render(const Game* game) { | 283 | void game_render(const Game* game) { |
280 | gfx_render_scene(game->renderer, game->render_backend, game->scene, | 284 | gfx_render_scene( |
281 | game->camera); | 285 | game->renderer, game->render_backend, game->scene, game->camera); |
282 | } | 286 | } |
283 | 287 | ||
284 | void game_set_viewport(Game* game, int width, int height) { | 288 | void game_set_viewport(Game* game, int width, int height) { |
285 | gfx_set_viewport(game->render_backend, width, height); | 289 | gfx_set_viewport(game->render_backend, width, height); |
286 | 290 | ||
287 | const R fovy = 90 * TO_RAD; | 291 | const R fovy = 90 * TO_RAD; |
288 | const R aspect = (R)width / (R)height; | 292 | const R aspect = (R)width / (R)height; |
289 | const R near = 0.1; | 293 | const R near = 0.1; |
290 | const R far = 1000; | 294 | const R far = 1000; |
291 | const mat4 projection = mat4_perspective(fovy, aspect, near, far); | 295 | const mat4 projection = mat4_perspective(fovy, aspect, near, far); |
292 | 296 | ||
293 | Camera* camera = gfx_get_camera_camera(game->camera); | 297 | Camera* camera = gfx_get_camera_camera(game->camera); |
294 | camera->projection = projection; | 298 | camera->projection = projection; |
295 | } | 299 | } |