From 3db2b6fe574ce7d2e0b49720f0453b824a4d8312 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Thu, 5 Jan 2023 17:17:39 -0800 Subject: Move skyquad node setup to util. --- gfx/include/gfx/util/skyquad.h | 20 ++++++++-- gfx/src/util/skyquad.c | 83 +++++++++++++++++++++++++++++++++++++++++- gltfview/src/game.c | 62 ++++++------------------------- 3 files changed, 108 insertions(+), 57 deletions(-) diff --git a/gfx/include/gfx/util/skyquad.h b/gfx/include/gfx/util/skyquad.h index 88c9c41..f792a13 100644 --- a/gfx/include/gfx/util/skyquad.h +++ b/gfx/include/gfx/util/skyquad.h @@ -1,10 +1,22 @@ /// A skyquad is like a skybox but with a single quad. #pragma once -typedef struct Gfx Gfx; -typedef struct Scene Scene; +typedef struct Gfx Gfx; +typedef struct Scene Scene; +typedef struct SceneNode SceneNode; typedef struct SceneObject SceneObject; -typedef struct Texture Texture; +typedef struct Texture Texture; /// Create a skyquad. -SceneObject* gfx_make_skyquad(Gfx*, Scene*, const Texture*); +SceneObject* gfx_make_skyquad(Gfx*, const Texture*); + +/// Set up a skyquad in the scene. +/// +/// This function adds two scene nodes under the given root node: +/// - An object node to render the skyquad in the background. +/// - A light node to light up other objects with the skyquad. +/// +/// Return the light node under which objects affected by the light can be +/// rooted. +SceneNode* gfx_setup_skyquad( + Gfx*, SceneNode* root, const Texture* environment_map); diff --git a/gfx/src/util/skyquad.c b/gfx/src/util/skyquad.c index 2461f8c..b59d7b9 100644 --- a/gfx/src/util/skyquad.c +++ b/gfx/src/util/skyquad.c @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -13,9 +15,8 @@ #include -SceneObject* gfx_make_skyquad(Gfx* gfx, Scene* scene, const Texture* texture) { +SceneObject* gfx_make_skyquad(Gfx* gfx, const Texture* texture) { assert(gfx); - assert(scene); assert(texture); // TODO: pass RenderBackend directly? @@ -84,3 +85,81 @@ cleanup: } return false; } + +/// Create an environment light node. +static SceneNode* make_environment_light( + SceneNode* root, const Texture* environment_light) { + assert(root); + + Light* light = 0; + SceneNode* light_node = 0; + + light = gfx_make_light(&(LightDesc){ + .type = EnvironmentLightType, + .light = (EnvironmentLightDesc){.environment_map = environment_light}}); + if (!light) { + goto cleanup; + } + + light_node = gfx_make_light_node(light); + if (!light_node) { + goto cleanup; + } + gfx_set_node_parent(light_node, root); + + return light_node; + +cleanup: + if (light) { + gfx_destroy_light(&light); + } + if (light_node) { + gfx_destroy_node(&light_node); + } + return 0; +} + +SceneNode* gfx_setup_skyquad( + Gfx* gfx, SceneNode* root, const Texture* environment_map) { + assert(gfx); + assert(root); + assert(environment_map); + + SceneObject* skyquad_object = 0; + SceneNode* object_node = 0; + SceneNode* light_node = 0; + + // Create the skyquad object. + skyquad_object = gfx_make_skyquad(gfx, environment_map); + if (!skyquad_object) { + goto cleanup; + } + + // Create an object node to render the skyquad in the background. + object_node = gfx_make_object_node(skyquad_object); + if (!object_node) { + goto cleanup; + } + gfx_set_node_parent(object_node, root); + + // Create an environment light node under which to root objects affected by + // the skyquad. + light_node = make_environment_light(root, environment_map); + if (!light_node) { + goto cleanup; + } + + return light_node; + +cleanup: + if (skyquad_object) { + gfx_destroy_object(&skyquad_object); + } + if (object_node) { + gfx_destroy_node(&object_node); + } + if (light_node) { + gfx_destroy_node(&light_node); + } + return 0; +} diff --git a/gltfview/src/game.c b/gltfview/src/game.c index bd474d6..54e498b 100644 --- a/gltfview/src/game.c +++ b/gltfview/src/game.c @@ -55,7 +55,7 @@ static ShaderProgram* load_shader( return shader; } -/// Loads the skyquad texture. +/// Load the skyquad texture. static Texture* load_environment_map(RenderBackend* render_backend) { return gfx_load_texture( render_backend, @@ -75,60 +75,20 @@ static Texture* load_environment_map(RenderBackend* render_backend) { }); } -/// Creates an object to render the skyquad in the background. -static SceneNode* make_skyquad_object_node( - Game* game, const Texture* environment_map) { +/// Load the skyquad and return the environment light node. +static SceneNode* load_skyquad(Game* game) { assert(game); - SceneObject* skyquad_object = - gfx_make_skyquad(game->gfx, game->scene, environment_map); - if (!skyquad_object) { - return 0; - } - SceneNode* skyquad_node = gfx_make_object_node(skyquad_object); - if (!skyquad_node) { - return 0; - } - gfx_set_node_parent(skyquad_node, gfx_get_scene_root(game->scene)); - return skyquad_node; -} - -/// Creates an environment light. -static SceneNode* make_environment_light( - Game* game, const Texture* environment_light) { - assert(game); - - Light* light = gfx_make_light(&(LightDesc){ - .type = EnvironmentLightType, - .light = (EnvironmentLightDesc){.environment_map = environment_light}}); - if (!light) { - return 0; - } - SceneNode* light_node = gfx_make_light_node(light); - if (!light_node) { - return 0; - } - gfx_set_node_parent(light_node, gfx_get_scene_root(game->scene)); - return light_node; -} - -/// Loads the skyquad and returns the SceneNode with the environment light. -static bool load_skyquad(Game* game, SceneNode** node) { - assert(game); - assert(node); - Texture* environment_map = load_environment_map(game->render_backend); if (!environment_map) { - return false; + return 0; } - make_skyquad_object_node(game, environment_map); - *node = make_environment_light(game, environment_map); - - return true; + return gfx_setup_skyquad( + game->gfx, gfx_get_scene_root(game->scene), environment_map); } -/// Loads the 3D scene. +/// Load the 3D scene. static bool load_scene( Game* game, const char* scene_filepath, const char* view_mode) { assert(game); @@ -143,8 +103,8 @@ static bool load_scene( // Damaged helmet. spatial3_set_position(&camera->spatial, vec3_make(0, 0, 2)); - SceneNode* sky_node = 0; - if (!load_skyquad(game, &sky_node) || !sky_node) { + SceneNode* sky_light_node = load_skyquad(game); + if (!sky_light_node) { return false; } @@ -155,7 +115,7 @@ static bool load_scene( // } if (!gfx_load_scene( - game->gfx, sky_node, + game->gfx, sky_light_node, &(LoadSceneCmd){ .origin = SceneFromFile, .filepath = scene_filepath})) { return false; @@ -164,7 +124,7 @@ static bool load_scene( return true; } -/// Loads a scene for debugging textures. +/// Load a scene for debugging textures. static bool load_texture_debugger_scene(Game* game) { assert(game); -- cgit v1.2.3