From bd57f345ed9dbed1d81683e48199626de2ea9044 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 27 Jun 2025 10:18:39 -0700 Subject: Restructure project --- src/util/skyquad.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/util/skyquad.c (limited to 'src/util/skyquad.c') diff --git a/src/util/skyquad.c b/src/util/skyquad.c new file mode 100644 index 0000000..08fa044 --- /dev/null +++ b/src/util/skyquad.c @@ -0,0 +1,161 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +SceneObject* gfx_make_skyquad(GfxCore* gfxcore, const Texture* texture) { + assert(gfxcore); + assert(texture); + + ShaderProgram* shader = 0; + Geometry* geometry = 0; + Material* material = 0; + Mesh* mesh = 0; + SceneObject* object = 0; + + shader = gfx_make_skyquad_shader(gfxcore); + if (!shader) { + goto cleanup; + } + + geometry = gfx_make_quad_11(gfxcore); + if (!geometry) { + goto cleanup; + } + + MaterialDesc material_desc = (MaterialDesc){0}; + material_desc.uniforms[0] = (ShaderUniform){ + .type = UniformTexture, + .value.texture = texture, + .name = sstring_make("Skyquad")}; + material_desc.num_uniforms = 1; + material = gfx_make_material(&material_desc); + if (!material) { + goto cleanup; + } + + MeshDesc mesh_desc = (MeshDesc){0}; + mesh_desc.geometry = geometry; + mesh_desc.material = material; + mesh_desc.shader = shader; + mesh = gfx_make_mesh(&mesh_desc); + if (!mesh) { + goto cleanup; + } + + object = gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}}); + if (!object) { + goto cleanup; + } + + return object; + +cleanup: + if (shader) { + gfx_destroy_shader_program(gfxcore, &shader); + } + if (geometry) { + gfx_destroy_geometry(gfxcore, &geometry); + } + if (material) { + gfx_destroy_material(&material); + } + if (mesh) { + gfx_destroy_mesh(&mesh); + } + if (object) { + gfx_destroy_object(&object); + } + return false; +} + +/// Create an environment light node. +static SceneNode* make_environment_light( + SceneNode* root, const Texture* environment_map) { + assert(root); + assert(environment_map); + + Light* light = 0; + SceneNode* light_node = 0; + + light = gfx_make_light(&(LightDesc){ + .type = EnvironmentLightType, + .light = {(EnvironmentLightDesc){.environment_map = environment_map}}}); + 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( + GfxCore* gfxcore, SceneNode* root, const Texture* environment_map) { + assert(gfxcore); + 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(gfxcore, 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; +} -- cgit v1.2.3