From 65d448aad0e6c792b1adba1272efef73b31c4885 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 24 Oct 2025 18:33:36 -0700 Subject: Consolidate renderers --- src/render/llr_impl.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/render/llr_impl.h (limited to 'src/render/llr_impl.h') diff --git a/src/render/llr_impl.h b/src/render/llr_impl.h new file mode 100644 index 0000000..319441c --- /dev/null +++ b/src/render/llr_impl.h @@ -0,0 +1,117 @@ +#pragma once + +#include +#include + +#include "scene/types.h" + +#include +#include + +#include +#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; + }; + node_idx parent; // Parent SceneNode. +} Light; + +typedef struct Material { + ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_MATERIAL]; + int num_uniforms; +} 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 +/// shader program when a draw call is issued and if anything has changed. This +/// keeps the number of graphics API calls to a minimum, but requires tracking +/// state changes. The 'changed' booleans below fulfill this purpose, and +/// indicate whether a given state has changed since the last draw call. +/// +/// The renderer must combine state changes accordingly. For example, if only +/// the lights have changed, then it is sufficient to update light uniforms in +/// the current shader program. On the other hand, if the shader program has +/// changed, then the renderer must reconfigure it from scratch and set light +/// uniforms, camera uniforms, etc. +/// +/// Note that the shader program API has its own level of caching as well, so +/// reconfiguration at the level of the renderer does not result in the +/// worst-case set of graphics API calls. +typedef struct LLR { + GfxCore* gfxcore; + + union { + struct { + bool shader_changed : 1; // Whether the shader has changed. + bool camera_changed : 1; // Whether the camera parameters have changed. + bool lights_changed : 1; // Whether the lights have changed. + bool skeleton_changed : 1; // Whether the skeleton has changed. + bool material_changed : 1; // Whether the material has changed. + bool matrix_changed : 1; // Whether the matrix stack has changed. + }; + uint8_t changed_flags; + }; + + IBL* ibl; + Texture* brdf_integration_map; + + ShaderProgram* shader; // Active shader. Not owned. + + const Material* material; // Active material. Not owned. + + vec3 camera_position; + mat4 camera_rotation; + mat4 view; // Camera view matrix. + mat4 projection; // Camera projection matrix. + R fovy; // Camera vertical field of view. + R aspect; // Aspect ratio. + + // Lights are not const because environment lights store lazily-computed + // irradiance maps. + Light* lights[GFX_LLR_MAX_NUM_LIGHTS]; // Lights stack. + int num_lights; // Number of lights enabled at a given point in time. It + // points to one past the top of the stack. + + size_t num_joints; + mat4 joint_matrices[GFX_MAX_NUM_JOINTS]; + + // The matrix stack contains pre-multiplied matrices. + // It is also never empty. The top of the stack is an identity matrix when the + // stack is "empty" from the user's perspective. + mat4 matrix_stack[GFX_LLR_MAX_NUM_MATRICES]; + int stack_pointer; // Points to the top of the stack. +} LLR; + +/// Create a new immediate mode renderer. +bool gfx_llr_make(LLR*, GfxCore*); + +/// Destroy the immediate mode renderer. +void gfx_llr_destroy(LLR*); -- cgit v1.2.3