From b37b5398a6afa940acd1138bde922a70838f33af Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 4 Jul 2025 10:37:01 -0700 Subject: Add the new low-level renderer, shared between the imm and scene graph renderer. LLR integration with the scene graph renderer not yet done. --- src/renderer/renderer.c | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'src/renderer/renderer.c') diff --git a/src/renderer/renderer.c b/src/renderer/renderer.c index c2a7dda..0c1fe78 100644 --- a/src/renderer/renderer.c +++ b/src/renderer/renderer.c @@ -1,10 +1,10 @@ #include "renderer_impl.h" +#include "llr/light_impl.h" +#include "llr/material_impl.h" +#include "llr/mesh_impl.h" #include "scene/animation_impl.h" #include "scene/camera_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" @@ -12,16 +12,18 @@ #include "scene/scene_memory.h" #include +#include #include #include -#include +// #include +#include "gfx/gfx.h" + #include #include #include -// TODO: Move to a header like "constants.h". static const int IRRADIANCE_MAP_WIDTH = 1024; static const int IRRADIANCE_MAP_HEIGHT = 1024; static const int PREFILTERED_ENVIRONMENT_MAP_WIDTH = 128; @@ -29,16 +31,18 @@ static const int PREFILTERED_ENVIRONMENT_MAP_HEIGHT = 128; static const int BRDF_INTEGRATION_MAP_WIDTH = 512; static const int BRDF_INTEGRATION_MAP_HEIGHT = 512; -bool renderer_make(Renderer* renderer, GfxCore* gfxcore) { +bool gfx_renderer_make(Renderer* renderer, LLR* llr, GfxCore* gfxcore) { assert(renderer); + assert(llr); assert(gfxcore); renderer->gfxcore = gfxcore; + renderer->llr = llr; return true; } -void renderer_destroy(Renderer* renderer) { +void gfx_renderer_destroy(Renderer* renderer) { if (!renderer) { return; } @@ -117,9 +121,9 @@ static ShaderProgram* load_shader(Renderer* renderer, RenderSceneMode mode) { // } // } -/// Computes irradiance and prefiltered environment maps for the light if they +/// Compute irradiance and prefiltered environment maps for the light if they /// have not been already computed. -static bool setup_environment_light( +static bool set_up_environment_light( Renderer* renderer, GfxCore* gfxcore, EnvironmentLight* light) { assert(renderer); assert(light); @@ -168,6 +172,7 @@ cleanup: typedef struct RenderState { GfxCore* gfxcore; + LLR* llr; Renderer* renderer; ShaderProgram* shader; // Null to use scene shaders. const Scene* scene; @@ -209,6 +214,7 @@ static void draw_recursively( // Anima. if (node->type == AnimaNode) { + // Save the anima so that we can animate objects. state->anima = gfx_get_node_anima(node); } // Activate light. @@ -217,7 +223,7 @@ static void draw_recursively( assert(light); if (light->type == EnvironmentLightType) { - bool result = setup_environment_light( + bool result = set_up_environment_light( state->renderer, state->gfxcore, &light->environment); // TODO: Handle the result in a better way. assert(result); @@ -238,11 +244,13 @@ static void draw_recursively( // TODO: Here we would frustum-cull the object. // TODO: Avoid computing matrices like Modelview or MVP if the shader does - // not use them. + // not use them. const mat4 model_matrix = node_transform; const mat4 modelview = mat4_mul(*state->view_matrix, model_matrix); const mat4 mvp = mat4_mul(*state->projection, modelview); + // A model/anima can have many skeletons. We need to animate the given + // object using its skeleton, not just any skeleton of the anima. if (object->skeleton.val) { load_skeleton(state, object->skeleton); } @@ -260,9 +268,11 @@ static void draw_recursively( assert(mesh->material); // TODO: Here we would frustum-cull the mesh. The AABB would have to be - // transformed by the model matrix. Rotation would make the AABB - // relatively large, but still, the culling would be conservative. + // transformed by the model matrix. Rotation would make the AABB + // relatively large, but still, the culling would be conservative. + // TODO: Make sure we strictly set only the uniforms that are required by + // mesh rendering. See the other item below. // Apply common shader uniforms not captured by materials. ShaderProgram* shader = state->shader ? state->shader : mesh->shader; gfx_set_mat4_uniform(shader, "ModelMatrix", &model_matrix); @@ -270,7 +280,10 @@ static void draw_recursively( gfx_set_mat4_uniform(shader, "View", state->view_matrix); gfx_set_mat4_uniform(shader, "Projection", state->projection); gfx_set_mat4_uniform(shader, "MVP", &mvp); + // TODO: CameraRotation is only used by the skyquad and cubemap_filtering + // shaders, not mesh rendering. gfx_set_mat4_uniform(shader, "CameraRotation", state->camera_rotation); + // TODO: Fovy and Aspect are only used by the skyquad, not necessary here. gfx_set_float_uniform(shader, "Fovy", state->fovy); gfx_set_float_uniform(shader, "Aspect", state->aspect); if (state->camera) { @@ -297,9 +310,9 @@ static void draw_recursively( shader, "PrefilteredEnvironmentMap", light->prefiltered_environment_map); gfx_set_float_uniform( - shader, "MaxReflectionLOD", light->max_reflection_lod); + shader, "MaxReflectionLOD", (float)light->max_reflection_lod); } - material_activate(shader, mesh->material); + gfx_material_activate(shader, mesh->material); gfx_activate_shader_program(shader); gfx_apply_uniforms(shader); gfx_render_geometry(mesh->geometry); @@ -327,7 +340,7 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) { const Scene* scene = params->scene; const SceneCamera* camera = params->camera; - GfxCore* gfxcore = renderer->gfxcore; + GfxCore* const gfxcore = renderer->gfxcore; mat4 projection, camera_rotation, view_matrix; if (camera) { @@ -347,6 +360,7 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) { RenderState state = { .gfxcore = gfxcore, + .llr = renderer->llr, .renderer = renderer, .shader = shader, .scene = scene, -- cgit v1.2.3