From 0dc3a9df980630b671bbc5df69503c2e72dcf004 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sun, 2 Nov 2025 18:18:56 -0800 Subject: Consolidate scene data structures --- src/core/shader_program.c | 29 +++++++++++ src/memory.c | 4 +- src/render/llr.c | 119 ++++------------------------------------------ src/render/llr_impl.h | 31 ------------ src/render/renderer.c | 3 +- src/scene/light.c | 39 +++++++++++++++ src/scene/light_impl.h | 20 ++++++++ src/scene/material.c | 24 ++++++++++ src/scene/material_impl.h | 13 +++++ src/scene/mesh.c | 26 ++++++++++ src/scene/mesh_impl.h | 11 +++++ src/scene/object.c | 3 +- 12 files changed, 177 insertions(+), 145 deletions(-) create mode 100644 src/scene/light.c create mode 100644 src/scene/light_impl.h create mode 100644 src/scene/material.c create mode 100644 src/scene/material_impl.h create mode 100644 src/scene/mesh.c create mode 100644 src/scene/mesh_impl.h (limited to 'src') diff --git a/src/core/shader_program.c b/src/core/shader_program.c index eeb46f8..3840019 100644 --- a/src/core/shader_program.c +++ b/src/core/shader_program.c @@ -209,6 +209,35 @@ static ShaderUniform* get_or_allocate_uniform( // The functions below save the value of a uniform in the shader program. If the // uniform does not even exist, then there is no need to store the value. +void gfx_set_uniform(ShaderProgram* prog, const ShaderUniform* uniform) { + switch (uniform->type) { + case UniformInt: + gfx_set_int_uniform(prog, uniform->name.str, uniform->value.uniform_int); + break; + case UniformFloat: + gfx_set_float_uniform( + prog, uniform->name.str, uniform->value.uniform_float); + break; + case UniformMat4: + gfx_set_mat4_uniform(prog, uniform->name.str, &uniform->value.uniform_mat4); + break; + case UniformVec3: + gfx_set_vec3_uniform(prog, uniform->name.str, uniform->value.uniform_vec3); + break; + case UniformVec4: + gfx_set_vec4_uniform(prog, uniform->name.str, uniform->value.uniform_vec4); + break; + case UniformTexture: + gfx_set_texture_uniform(prog, uniform->name.str, uniform->value.texture); + break; + case UniformMat4Array: + gfx_set_mat4_array_uniform( + prog, uniform->name.str, uniform->value.array.values, + uniform->value.array.count); + break; + } +} + void gfx_set_int_uniform(ShaderProgram* prog, const char* name, int value) { assert(prog); assert(name); diff --git a/src/memory.c b/src/memory.c index de20f78..754f04d 100644 --- a/src/memory.c +++ b/src/memory.c @@ -4,7 +4,9 @@ #include #include "animation_impl.h" -#include "render/llr_impl.h" +#include "scene/light_impl.h" +#include "scene/material_impl.h" +#include "scene/mesh_impl.h" #include "scene/model_impl.h" #include "scene/node_impl.h" #include "scene/object_impl.h" diff --git a/src/render/llr.c b/src/render/llr.c index c9c6d34..752b65b 100644 --- a/src/render/llr.c +++ b/src/render/llr.c @@ -1,14 +1,15 @@ #include "llr_impl.h" #include "animation_impl.h" -#include "memory.h" +#include "scene/light_impl.h" +#include "scene/material_impl.h" +#include "scene/mesh_impl.h" #include "scene/node_impl.h" #include #include #include -#include static const int IRRADIANCE_MAP_WIDTH = 1024; static const int IRRADIANCE_MAP_HEIGHT = 1024; @@ -17,108 +18,23 @@ static const int PREFILTERED_ENVIRONMENT_MAP_HEIGHT = 128; static const int BRDF_INTEGRATION_MAP_WIDTH = 512; static const int BRDF_INTEGRATION_MAP_HEIGHT = 512; -static void make_environment_light( - Light* light, const EnvironmentLightDesc* desc) { - assert(light); - assert(desc); - light->type = EnvironmentLightType; - light->environment.environment_map = desc->environment_map; -} - -Light* gfx_make_light(const LightDesc* desc) { - assert(desc); - - Light* light = mem_alloc_light(); - - switch (desc->type) { - case EnvironmentLightType: - make_environment_light(light, &desc->light.environment); - break; - default: - log_error("Unhandled light type"); - gfx_destroy_light(&light); - return 0; - } - - return light; -} - -void gfx_destroy_light(Light** light) { - assert(light); - if (*light) { - mem_free_light(light); - } -} - -static void material_make(Material* material, const MaterialDesc* desc) { - assert(material); - assert(desc); - assert(desc->num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); - material->alpha_mode = desc->alpha_mode; - material->alpha_cutoff = desc->alpha_cutoff; - material->num_uniforms = (int8_t)desc->num_uniforms; - for (int i = 0; i < desc->num_uniforms; ++i) { - material->uniforms[i] = desc->uniforms[i]; - } -} - -Material* gfx_make_material(const MaterialDesc* desc) { - assert(desc); - Material* material = mem_alloc_material(); - material_make(material, desc); - return material; -} - -void gfx_destroy_material(Material** material) { mem_free_material(material); } - -// TODO: Move this to core/shader_program. -static void set_uniform(ShaderProgram* prog, const ShaderUniform* uniform) { - switch (uniform->type) { - case UniformInt: - gfx_set_int_uniform(prog, uniform->name.str, uniform->value.uniform_int); - break; - case UniformFloat: - gfx_set_float_uniform( - prog, uniform->name.str, uniform->value.uniform_float); - break; - case UniformMat4: - gfx_set_mat4_uniform(prog, uniform->name.str, &uniform->value.uniform_mat4); - break; - case UniformVec3: - gfx_set_vec3_uniform(prog, uniform->name.str, uniform->value.uniform_vec3); - break; - case UniformVec4: - gfx_set_vec4_uniform(prog, uniform->name.str, uniform->value.uniform_vec4); - break; - case UniformTexture: - gfx_set_texture_uniform(prog, uniform->name.str, uniform->value.texture); - break; - case UniformMat4Array: - gfx_set_mat4_array_uniform( - prog, uniform->name.str, uniform->value.array.values, - uniform->value.array.count); - break; - } -} - /// Activate the material. /// /// This configures the shader uniforms that are specific to the material. -static void gfx_material_activate( - ShaderProgram* shader, const Material* material) { +static void material_activate(ShaderProgram* shader, const Material* material) { assert(material); for (int i = 0; i < material->num_uniforms; ++i) { const ShaderUniform* uniform = &material->uniforms[i]; - set_uniform(shader, uniform); + gfx_set_uniform(shader, uniform); } if (material->alpha_mode != Opaque) { - set_uniform( + gfx_set_uniform( shader, &(ShaderUniform){.name = sstring_make("AlphaMode"), .type = UniformInt, .value.uniform_int = material->alpha_mode}); } if (material->alpha_mode == Mask) { - set_uniform( + gfx_set_uniform( shader, &(ShaderUniform){.name = sstring_make("AlphaCutoff"), .type = UniformFloat, @@ -126,25 +42,6 @@ static void gfx_material_activate( } } -static void mesh_make(Mesh* mesh, const MeshDesc* desc) { - assert(mesh); - assert(desc); - assert(desc->geometry); - assert(desc->material); - assert(desc->shader); - mesh->geometry = desc->geometry; - mesh->material = desc->material; - mesh->shader = desc->shader; -} - -Mesh* gfx_make_mesh(const MeshDesc* desc) { - Mesh* mesh = mem_alloc_mesh(); - mesh_make(mesh, desc); - return mesh; -} - -void gfx_destroy_mesh(Mesh** mesh) { mem_free_mesh(mesh); } - /// Initialize renderer state for IBL. static bool init_ibl(LLR* renderer) { assert(renderer); @@ -334,7 +231,7 @@ static void configure_state(LLR* renderer) { // Geometry may be rendered without a material. if (renderer->material) { - gfx_material_activate(renderer->shader, renderer->material); + material_activate(renderer->shader, renderer->material); } } diff --git a/src/render/llr_impl.h b/src/render/llr_impl.h index 3a5455a..9d70843 100644 --- a/src/render/llr_impl.h +++ b/src/render/llr_impl.h @@ -10,43 +10,12 @@ #include #include -typedef struct Geometry Geometry; typedef struct GfxCore GfxCore; typedef struct IBL IBL; typedef struct Material Material; typedef struct ShaderProgram ShaderProgram; typedef struct Texture Texture; -/// An environment light. -typedef struct EnvironmentLight { - const Texture* environment_map; - const Texture* irradiance_map; // Renderer implementation. - const Texture* prefiltered_environment_map; // Renderer implementation. - int max_reflection_lod; // Mandatory when prefiltered_environment_map is - // given. -} EnvironmentLight; - -/// A scene light. -typedef struct Light { - LightType type; - union { - EnvironmentLight environment; - }; -} Light; - -typedef struct Material { - AlphaMode alpha_mode; - float alpha_cutoff; - int8_t num_uniforms; - ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_MATERIAL]; -} Material; - -typedef struct Mesh { - const Geometry* geometry; - const Material* material; - ShaderProgram* shader; // TODO: Move this back to Material? -} Mesh; - /// Immediate mode renderer. /// /// The renderer caches state changes in memory and only programs the underlying diff --git a/src/render/renderer.c b/src/render/renderer.c index 6962d6b..a9d9bef 100644 --- a/src/render/renderer.c +++ b/src/render/renderer.c @@ -3,10 +3,11 @@ #include "animation_impl.h" #include "llr_impl.h" #include "memory.h" +#include "scene/material_impl.h" +#include "scene/mesh_impl.h" #include "scene/model_impl.h" #include "scene/node_impl.h" #include "scene/object_impl.h" -#include "scene/scene_impl.h" #include #include diff --git a/src/scene/light.c b/src/scene/light.c new file mode 100644 index 0000000..4233330 --- /dev/null +++ b/src/scene/light.c @@ -0,0 +1,39 @@ +#include "light_impl.h" + +#include "memory.h" + +#include +#include + +static void make_environment_light( + Light* light, const EnvironmentLightDesc* desc) { + assert(light); + assert(desc); + light->type = EnvironmentLightType; + light->environment.environment_map = desc->environment_map; +} + +Light* gfx_make_light(const LightDesc* desc) { + assert(desc); + + Light* light = mem_alloc_light(); + + switch (desc->type) { + case EnvironmentLightType: + make_environment_light(light, &desc->light.environment); + break; + default: + log_error("Unhandled light type"); + gfx_destroy_light(&light); + return 0; + } + + return light; +} + +void gfx_destroy_light(Light** light) { + assert(light); + if (*light) { + mem_free_light(light); + } +} diff --git a/src/scene/light_impl.h b/src/scene/light_impl.h new file mode 100644 index 0000000..3191a50 --- /dev/null +++ b/src/scene/light_impl.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +/// An environment light. +typedef struct EnvironmentLight { + const Texture* environment_map; + const Texture* irradiance_map; // Renderer implementation. + const Texture* prefiltered_environment_map; // Renderer implementation. + int max_reflection_lod; // Mandatory when prefiltered_environment_map is + // given. +} EnvironmentLight; + +/// A scene light. +typedef struct Light { + LightType type; + union { + EnvironmentLight environment; + }; +} Light; diff --git a/src/scene/material.c b/src/scene/material.c new file mode 100644 index 0000000..9fe6c1b --- /dev/null +++ b/src/scene/material.c @@ -0,0 +1,24 @@ +#include "material_impl.h" + +#include "memory.h" + +static void material_make(Material* material, const MaterialDesc* desc) { + assert(material); + assert(desc); + assert(desc->num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); + material->alpha_mode = desc->alpha_mode; + material->alpha_cutoff = desc->alpha_cutoff; + material->num_uniforms = (int8_t)desc->num_uniforms; + for (int i = 0; i < desc->num_uniforms; ++i) { + material->uniforms[i] = desc->uniforms[i]; + } +} + +Material* gfx_make_material(const MaterialDesc* desc) { + assert(desc); + Material* material = mem_alloc_material(); + material_make(material, desc); + return material; +} + +void gfx_destroy_material(Material** material) { mem_free_material(material); } diff --git a/src/scene/material_impl.h b/src/scene/material_impl.h new file mode 100644 index 0000000..488ffc7 --- /dev/null +++ b/src/scene/material_impl.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +typedef struct ShaderProgram ShaderProgram; + +typedef struct Material { + AlphaMode alpha_mode; + float alpha_cutoff; + int8_t num_uniforms; + ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_MATERIAL]; +} Material; diff --git a/src/scene/mesh.c b/src/scene/mesh.c new file mode 100644 index 0000000..770c3fb --- /dev/null +++ b/src/scene/mesh.c @@ -0,0 +1,26 @@ +#include "mesh_impl.h" + +#include + +#include "memory.h" + +#include + +static void mesh_make(Mesh* mesh, const MeshDesc* desc) { + assert(mesh); + assert(desc); + assert(desc->geometry); + assert(desc->material); + assert(desc->shader); + mesh->geometry = desc->geometry; + mesh->material = desc->material; + mesh->shader = desc->shader; +} + +Mesh* gfx_make_mesh(const MeshDesc* desc) { + Mesh* mesh = mem_alloc_mesh(); + mesh_make(mesh, desc); + return mesh; +} + +void gfx_destroy_mesh(Mesh** mesh) { mem_free_mesh(mesh); } diff --git a/src/scene/mesh_impl.h b/src/scene/mesh_impl.h new file mode 100644 index 0000000..c7e2211 --- /dev/null +++ b/src/scene/mesh_impl.h @@ -0,0 +1,11 @@ +#pragma once + +typedef struct Geometry Geometry; +typedef struct Material Material; +typedef struct ShaderProgram ShaderProgram; + +typedef struct Mesh { + const Geometry* geometry; + const Material* material; + ShaderProgram* shader; // TODO: Move this back to Material? +} Mesh; diff --git a/src/scene/object.c b/src/scene/object.c index 7004ce1..ac86b39 100644 --- a/src/scene/object.c +++ b/src/scene/object.c @@ -3,8 +3,9 @@ #include #include "memory.h" -#include "node_impl.h" #include "render/llr_impl.h" +#include "scene/mesh_impl.h" +#include "scene/node_impl.h" #include -- cgit v1.2.3