summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-07-20 21:17:46 +1000
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-07-20 21:17:46 +1000
commitdc8952e6650aae6297915bf118e1f7b1259d235d (patch)
tree98ef132262fa0e01c7df5cac7f73c825a65d09ed
parent58a748dcd77d0caacc9d6ef7a7e7e073ac849ad3 (diff)
fixing shadows.
-rw-r--r--examples/game_demo/game_demo.c23
-rw-r--r--src/core/core.c2
-rw-r--r--src/maths/primitives.c2
-rw-r--r--src/new_render/render.c16
-rw-r--r--src/new_render/render.h9
-rw-r--r--src/new_render/shadows.c109
-rw-r--r--src/new_render/shadows.h13
-rw-r--r--src/new_render/skybox.c2
-rw-r--r--src/ral/backends/opengl/backend_opengl.c23
9 files changed, 176 insertions, 23 deletions
diff --git a/examples/game_demo/game_demo.c b/examples/game_demo/game_demo.c
index f4cf643..734bff1 100644
--- a/examples/game_demo/game_demo.c
+++ b/examples/game_demo/game_demo.c
@@ -6,12 +6,15 @@
#include <assert.h>
#include "camera.h"
#include "core.h"
+#include "input.h"
+#include "keys.h"
#include "maths.h"
#include "primitives.h"
#include "ral_types.h"
#include "render.h"
#include "render_scene.h"
#include "render_types.h"
+#include "shadows.h"
#include "skybox.h"
static const char* faces[6] = { "assets/demo/skybox/right.jpg", "assets/demo/skybox/left.jpg",
@@ -83,17 +86,29 @@ int main() {
// RenderEnt entities[] = { player_r };
+ bool draw_debug = true;
+
while (!ShouldExit()) {
Frame_Begin();
+ if (key_just_released(KEYCODE_TAB)) {
+ draw_debug = !draw_debug;
+ }
+
Camera_Update(&cam);
SetCamera(cam);
// BEGIN Draw calls
- // draw the player model with shadows
- Render_RenderEntities(entities, entity_count);
- // Render_DrawTerrain();
- Skybox_Draw(&skybox, cam);
+ Shadow_Run(entities, entity_count);
+
+ if (draw_debug) {
+ // draw the player model with shadows
+ Render_RenderEntities(entities, entity_count);
+ // Render_DrawTerrain();
+ Skybox_Draw(&skybox, cam);
+ } else {
+ Shadow_DrawDebugQuad();
+ }
// END Draw calls
Frame_Draw();
diff --git a/src/core/core.c b/src/core/core.c
index 9945083..fcb03a1 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -68,3 +68,5 @@ void Frame_Begin() {
}
void Frame_Draw() {}
void Frame_End() { Render_FrameEnd(g_core.renderer); }
+
+struct Renderer* Core_GetRenderer(Core* core) { return core->renderer; } \ No newline at end of file
diff --git a/src/maths/primitives.c b/src/maths/primitives.c
index 233a7e0..32e7919 100644
--- a/src/maths/primitives.c
+++ b/src/maths/primitives.c
@@ -25,7 +25,7 @@ Vec3 plane_vertex_positions[] = {
(Vec3){ 0.5, 0, 0.5 },
};
-Geometry geo_create_plane(f32x2 extents) {
+Geometry Geo_CreatePlane(f32x2 extents) {
Vertex_darray* vertices = Vertex_darray_new(4);
u32_darray* indices = u32_darray_new(vertices->len);
diff --git a/src/new_render/render.c b/src/new_render/render.c
index 11f7e0a..386a356 100644
--- a/src/new_render/render.c
+++ b/src/new_render/render.c
@@ -5,11 +5,9 @@
#include "render.h"
#include <glfw3.h>
#include "camera.h"
-#include "colours.h"
#include "core.h"
#include "log.h"
#include "maths.h"
-#include "maths_types.h"
#include "mem.h"
#include "pbr.h"
#include "ral_common.h"
@@ -101,7 +99,7 @@ bool Renderer_Init(RendererConfig config, Renderer* ren, GLFWwindow** out_window
// create our renderpasses
ren->shadows = malloc(sizeof(Shadow_Storage));
- Shadow_Init(ren->shadows, u32x2(512, 512));
+ Shadow_Init(ren->shadows, 1024, 1024);
ren->pbr = malloc(sizeof(PBR_Storage));
PBR_Init(ren->pbr);
@@ -235,4 +233,14 @@ void Geometry_Destroy(Geometry* geometry) {
void SetCamera(Camera camera) { g_core.renderer->scene.camera = camera; }
void SetMainLight(DirectionalLight light) { g_core.renderer->scene.sun = light; }
-arena* GetRenderFrameArena(Renderer* r) { return &r->frame_arena; } \ No newline at end of file
+arena* GetRenderFrameArena(Renderer* r) { return &r->frame_arena; }
+
+RenderScene* Render_GetScene() {
+ Renderer* ren = Core_GetRenderer(&g_core);
+ return &ren->scene;
+}
+
+Shadow_Storage* Render_GetShadowStorage() {
+ Renderer* ren = Core_GetRenderer(&g_core);
+ return ren->shadows;
+} \ No newline at end of file
diff --git a/src/new_render/render.h b/src/new_render/render.h
index 52aecfc..0231975 100644
--- a/src/new_render/render.h
+++ b/src/new_render/render.h
@@ -7,6 +7,7 @@
#include "maths_types.h"
#include "ral_types.h"
#include "render_types.h"
+#include "shadows.h"
typedef struct Renderer Renderer;
typedef struct GLFWwindow GLFWwindow;
@@ -67,4 +68,10 @@ PUB void DrawMesh(Mesh* mesh, Material* material, Mat4 model);
PUB void Render_DrawTerrain();
// --- Getters (not in love with this but I'm finding keeping Renderer internals private to be okay)
-arena* GetRenderFrameArena(Renderer* r); \ No newline at end of file
+arena* GetRenderFrameArena(Renderer* r);
+
+typedef struct Shadow_Storage Shadow_Storage;
+typedef struct RenderScene RenderScene;
+
+RenderScene* Render_GetScene();
+Shadow_Storage* Render_GetShadowStorage(); \ No newline at end of file
diff --git a/src/new_render/shadows.c b/src/new_render/shadows.c
index 9a44e55..758a969 100644
--- a/src/new_render/shadows.c
+++ b/src/new_render/shadows.c
@@ -2,8 +2,10 @@
#include <string.h>
#include "core.h"
#include "file.h"
+#include "glad/glad.h"
#include "log.h"
-#include "maths.h"
+#include "maths_types.h"
+#include "primitives.h"
#include "ral_common.h"
#include "ral_impl.h"
#include "ral_types.h"
@@ -30,16 +32,34 @@ ShaderDataLayout ShadowUniforms_GetLayout(void* data) {
return (ShaderDataLayout){ .binding_count = 1, .bindings = { b1 } };
}
-void Shadow_Init(Shadow_Storage* storage, u32x2 shadowmap_extents) {
+ShaderDataLayout ShadowDebugQuad_GetLayout(void* data) {
+ TextureHandle* handle = data;
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "depthMap",
+ .kind = BINDING_TEXTURE,
+ .vis = VISIBILITY_FRAGMENT,
+ };
+
+ if (has_data) {
+ b1.data.texture.handle = *handle;
+ }
+
+ return (ShaderDataLayout){ .binding_count = 1, .bindings = { b1 } };
+}
+
+void Shadow_Init(Shadow_Storage* storage, u32 shadowmap_width, u32 shadowmap_height) {
memset(storage, 0, sizeof(Shadow_Storage));
arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
- TextureDesc depthmap_desc = { .extents = shadowmap_extents,
+ TextureDesc depthmap_desc = { .extents = u32x2(shadowmap_width, shadowmap_height),
.format = TEXTURE_FORMAT_DEPTH_DEFAULT,
.tex_type = TEXTURE_TYPE_2D };
TextureHandle depthmap = GPU_TextureCreate(depthmap_desc, false, NULL);
storage->depth_texture = depthmap;
+ // -- shadowmap drawing pass
GPU_RenderpassDesc rpass_desc = { .default_framebuffer = false,
.has_color_target = false,
.has_depth_stencil = true,
@@ -71,19 +91,96 @@ void Shadow_Init(Shadow_Storage* storage, u32x2 shadowmap_extents) {
.code = fragment_shader.contents,
.is_spirv = false },
};
- storage->pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, storage->shadowmap_pass);
+ storage->shadowmap_pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, storage->shadowmap_pass);
+
+ // -- debug quad pipeline
+ GPU_RenderpassDesc debug_pass_desc = { .default_framebuffer = true };
+ storage->debugquad_pass = GPU_Renderpass_Create(debug_pass_desc);
+
+ vert_path = str8("assets/shaders/debug_quad.vert");
+ frag_path = str8("assets/shaders/debug_quad.frag");
+ vertex_shader = str8_from_file(&scratch, vert_path);
+ fragment_shader = str8_from_file(&scratch, frag_path);
+ if (!vertex_shader.has_value || !fragment_shader.has_value) {
+ ERROR_EXIT("Failed to load shaders from disk");
+ }
+
+ ShaderData debugquad_uniforms = { .data = NULL, .get_layout = &ShadowDebugQuad_GetLayout };
+
+ GraphicsPipelineDesc debugquad_pipeline_desc = {
+ .debug_name = "Shadows debug quad Pipeline",
+ .vertex_desc = static_3d_vertex_description(),
+ .data_layouts = { debugquad_uniforms },
+ .data_layouts_count = 1,
+ .vs = { .debug_name = "depth debug quad vert shader",
+ .filepath = vert_path,
+ .code = vertex_shader.contents,
+ .is_spirv = false },
+ .fs = { .debug_name = "depth debug quad frag shader",
+ .filepath = frag_path,
+ .code = fragment_shader.contents,
+ .is_spirv = false },
+ };
+ storage->debugquad_pipeline =
+ GPU_GraphicsPipeline_Create(debugquad_pipeline_desc, storage->debugquad_pass);
+
+ Geometry quad_geo = Geo_CreatePlane(f32x2(1, 1));
+ // HACK: Swap vertices to make it face us
+ Vertex top0 = quad_geo.vertices->data[0];
+ quad_geo.vertices->data[0] = quad_geo.vertices->data[2];
+ quad_geo.vertices->data[2] = top0;
+ Vertex top1 = quad_geo.vertices->data[1];
+ quad_geo.vertices->data[1] = quad_geo.vertices->data[3];
+ quad_geo.vertices->data[3] = top1;
+ storage->quad = Mesh_Create(&quad_geo, false);
arena_free_storage(&scratch);
}
+void Shadow_Run(RenderEnt* entities, size_t entity_count) {
+ Shadow_Storage* shadow_storage = Render_GetShadowStorage();
+
+ // calculations
+ RenderScene* render_scene = Render_GetScene();
+ f32 near_plane = 1.0, far_plane = 10.0;
+ // -- Not sure about how we want to handle lights
+ Vec3 light_position = { 1, 4, -1 };
+ // --
+ Mat4 light_projection = mat4_orthographic(-10.0, 10.0, -10.0, 10.0, near_plane, far_plane);
+ Mat4 light_view = mat4_look_at(light_position, VEC3_ZERO, VEC3_Y);
+ Mat4 light_space_matrix = mat4_mult(light_view, light_projection);
+
+ Shadow_ShadowmapExecute(shadow_storage, light_space_matrix, entities, entity_count);
+}
+
+void Shadow_DrawDebugQuad() {
+ Shadow_Storage* shadow_storage = Render_GetShadowStorage();
+
+ GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
+ GPU_CmdEncoder_BeginRender(enc, shadow_storage->debugquad_pass);
+
+ GPU_EncodeBindPipeline(enc, shadow_storage->debugquad_pipeline);
+ ShaderData quad_data = { .data = &shadow_storage->depth_texture,
+ .get_layout = ShadowDebugQuad_GetLayout };
+ GPU_EncodeBindShaderData(enc, 0, quad_data);
+ GPU_EncodeSetVertexBuffer(enc, shadow_storage->quad.vertex_buffer);
+ GPU_EncodeSetIndexBuffer(enc, shadow_storage->quad.index_buffer);
+ GPU_EncodeDrawIndexed(enc, shadow_storage->quad.geometry.indices->len);
+
+ GPU_CmdEncoder_EndRender(enc);
+}
+
void Shadow_ShadowmapExecute(Shadow_Storage* storage, Mat4 light_space_transform,
RenderEnt* entities, size_t entity_count) {
GPU_CmdEncoder shadow_encoder = GPU_CmdEncoder_Create();
GPU_CmdEncoder_BeginRender(&shadow_encoder, storage->shadowmap_pass);
- DEBUG("Begin shadowmap renderpass");
+ // DEBUG("Begin shadowmap renderpass");
+
+ // FIXME: shouldnt be gl specific
+ glClear(GL_DEPTH_BUFFER_BIT);
- GPU_EncodeBindPipeline(&shadow_encoder, storage->pipeline);
+ GPU_EncodeBindPipeline(&shadow_encoder, storage->shadowmap_pipeline);
ShadowUniforms uniforms = {
.light_space = light_space_transform,
diff --git a/src/new_render/shadows.h b/src/new_render/shadows.h
index 11fce3b..82439d4 100644
--- a/src/new_render/shadows.h
+++ b/src/new_render/shadows.h
@@ -10,9 +10,12 @@
typedef struct Shadow_Storage {
GPU_Renderpass* shadowmap_pass;
- GPU_Pipeline* pipeline;
- bool debug_quad_enabled;
+ GPU_Pipeline* shadowmap_pipeline;
TextureHandle depth_texture;
+ bool debug_quad_enabled;
+ Mesh quad;
+ GPU_Renderpass* debugquad_pass;
+ GPU_Pipeline* debugquad_pipeline;
// TODO: Some statistics tracking
} Shadow_Storage;
@@ -25,11 +28,13 @@ typedef struct Camera Camera;
typedef struct Mat4 Mat4;
// --- Public API
-PUB void Shadow_Init(Shadow_Storage* storage, u32x2 shadowmap_extents);
+PUB void Shadow_Init(Shadow_Storage* storage, u32 shadowmap_width, u32 shadowmap_height);
/** @brief Run shadow map generation for given entities, and store in a texture.
* @note Uses active directional light for now */
-PUB void Shadow_Run(Shadow_Storage* storage, RenderEnt* entities, size_t entity_count);
+PUB void Shadow_Run(RenderEnt* entities, size_t entity_count);
+
+PUB void Shadow_DrawDebugQuad();
/** @brief Get the shadow texture generated from shadowmap pass */
PUB Handle Shadow_GetShadowMapTexture(Shadow_Storage* storage);
diff --git a/src/new_render/skybox.c b/src/new_render/skybox.c
index b054366..882123d 100644
--- a/src/new_render/skybox.c
+++ b/src/new_render/skybox.c
@@ -109,7 +109,7 @@ Skybox Skybox_Create(const char** face_paths, int n) {
.fs = { .debug_name = "Skybox Fragment Shader",
.filepath = frag_path,
.code = fragment_shader.contents },
- .wireframe = true,
+ .wireframe = false,
.depth_test = true,
};
diff --git a/src/ral/backends/opengl/backend_opengl.c b/src/ral/backends/opengl/backend_opengl.c
index 97c86dd..ec01214 100644
--- a/src/ral/backends/opengl/backend_opengl.c
+++ b/src/ral/backends/opengl/backend_opengl.c
@@ -1,4 +1,5 @@
#include "backend_opengl.h"
+#include "colours.h"
#include "maths_types.h"
#if defined(CEL_REND_BACKEND_OPENGL)
#include <assert.h>
@@ -62,8 +63,20 @@ void GPU_Device_Destroy(GPU_Device* device) {}
bool GPU_Swapchain_Create(GPU_Swapchain* out_swapchain) { return true; }
void GPU_Swapchain_Destroy(GPU_Swapchain* swapchain) {}
void GPU_CmdEncoder_Destroy(GPU_CmdEncoder* encoder) {}
-void GPU_CmdEncoder_BeginRender(GPU_CmdEncoder* encoder, GPU_Renderpass* renderpass) {}
-void GPU_CmdEncoder_EndRender(GPU_CmdEncoder* encoder) {}
+
+void GPU_CmdEncoder_BeginRender(GPU_CmdEncoder* encoder, GPU_Renderpass* renderpass) {
+ glBindFramebuffer(GL_FRAMEBUFFER, renderpass->fbo);
+ // rgba clear_colour = STONE_800;
+ // glClearColor(clear_colour.r, clear_colour.g, clear_colour.b, 1.0f);
+ // if (renderpass->description.has_depth_stencil) {
+ // glClear(GL_DEPTH_BUFFER_BIT);
+ // } else {
+ // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ // }
+}
+
+void GPU_CmdEncoder_EndRender(GPU_CmdEncoder* encoder) { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
+
GPU_CmdEncoder* GPU_GetDefaultEncoder() { return &context.main_encoder; }
void GPU_QueueSubmit(GPU_CmdBuffer* cmd_buffer) {}
@@ -319,6 +332,12 @@ void GPU_EncodeBindPipeline(GPU_CmdEncoder* encoder, GPU_Pipeline* pipeline) {
// In OpenGL binding a pipeline is more or less equivalent to just setting the shader
glUseProgram(pipeline->shader_id);
+
+ if (pipeline->wireframe) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ } else {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
PUB void GPU_EncodeBindShaderData(GPU_CmdEncoder* encoder, u32 group, ShaderData data) {