summaryrefslogtreecommitdiff
path: root/src/new_render
diff options
context:
space:
mode:
Diffstat (limited to 'src/new_render')
-rw-r--r--src/new_render/render.c117
-rw-r--r--src/new_render/render_scene.h2
-rw-r--r--src/new_render/render_types.h5
-rw-r--r--src/new_render/shader_layouts.h3
-rw-r--r--src/new_render/shadows.c125
-rw-r--r--src/new_render/shadows.h13
6 files changed, 209 insertions, 56 deletions
diff --git a/src/new_render/render.c b/src/new_render/render.c
index cfd0b11..21046ea 100644
--- a/src/new_render/render.c
+++ b/src/new_render/render.c
@@ -2,17 +2,18 @@
* @brief
*/
-#include <glfw3.h>
#include "render.h"
-#include "core.h"
+#include <glfw3.h>
#include "camera.h"
#include "colours.h"
+#include "core.h"
#include "log.h"
#include "maths.h"
#include "maths_types.h"
#include "pbr.h"
#include "ral_common.h"
#include "ral_impl.h"
+#include "ral_types.h"
#include "render_scene.h"
#include "render_types.h"
#include "shadows.h"
@@ -35,30 +36,30 @@ struct Renderer {
};
bool Renderer_Init(RendererConfig config, Renderer* ren) {
- INFO("Renderer init");
+ INFO("Renderer init");
- // init resource pools
- DEBUG("Initialise GPU resource pools");
- arena pool_arena = arena_create(malloc(1024 * 1024), 1024 * 1024);
- ren->resource_pools = arena_alloc(&pool_arena, sizeof(struct ResourcePools));
- ResourcePools_Init(&pool_arena, ren->resource_pools);
+ // init resource pools
+ DEBUG("Initialise GPU resource pools");
+ arena pool_arena = arena_create(malloc(1024 * 1024), 1024 * 1024);
+ ren->resource_pools = arena_alloc(&pool_arena, sizeof(struct ResourcePools));
+ ResourcePools_Init(&pool_arena, ren->resource_pools);
// GLFW window creation
// NOTE: all platforms use GLFW at the moment but thats subject to change
glfwInit();
- #if defined(CEL_REND_BACKEND_OPENGL)
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- #elif defined(CEL_REND_BACKEND_VULKAN)
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- #endif
-
- GLFWwindow* window = glfwCreateWindow(config.scr_width, config.scr_height,
- config.window_name, NULL, NULL);
+#if defined(CEL_REND_BACKEND_OPENGL)
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+#elif defined(CEL_REND_BACKEND_VULKAN)
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+#endif
+
+ GLFWwindow* window =
+ glfwCreateWindow(config.scr_width, config.scr_height, config.window_name, NULL, NULL);
if (window == NULL) {
ERROR("Failed to create GLFW window\n");
glfwTerminate();
@@ -76,7 +77,6 @@ bool Renderer_Init(RendererConfig config, Renderer* ren) {
GPU_Device_Create(&ren->device);
GPU_Swapchain_Create(&ren->swapchain);
-
// set up default scene
Camera default_cam =
Camera_Create(vec3(0.0, 2.0, 4.0), vec3_normalise(vec3(0.0, -2.0, -4.0)), VEC3_Y, 45.0);
@@ -90,46 +90,57 @@ bool Renderer_Init(RendererConfig config, Renderer* ren) {
return true;
}
-void Renderer_Shutdown(Renderer* renderer) { }
+void Renderer_Shutdown(Renderer* ren) {}
size_t Renderer_GetMemReqs() { return sizeof(Renderer); }
-void Render_FrameBegin(Renderer *renderer) {
- renderer->frame_aborted = false;
- if (GPU_Backend)
-
+void Render_FrameBegin(Renderer* ren) {
+ ren->frame_aborted = false;
+ if (!GPU_Backend_BeginFrame()) {
+ ren->frame_aborted = true;
+ WARN("Frame aborted");
+ return;
+ }
}
-void Render_FrameEnd(Renderer* renderer) {
+void Render_FrameEnd(Renderer* ren) {
+ if (ren->frame_aborted) {
+ return;
+ }
+ GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
}
void Render_RenderEntities(RenderEnt* entities, size_t entity_count) {
- Renderer* ren = Core_GetRenderer(&g_core);
-
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
- // bind shadow
- GPU_EncodeBindPipeline(enc, ren->shadows)
-
+ Renderer* ren = Core_GetRenderer(&g_core);
+ RenderScene scene = ren->scene;
+
+ // -- Shadows
+ f32 near_plane = 1.0, far_plane = 10.0;
+ Mat4 light_projection = mat4_orthographic(-10.0, 10.0, -10.0, 10.0, near_plane, far_plane);
+ Vec3 pos = vec3_negate(scene.sun.direction);
+ Mat4 light_view = mat4_look_at(pos, VEC3_ZERO, VEC3_Y);
+ Mat4 light_space_matrix = mat4_mult(light_view, light_projection);
+ Shadow_ShadowmapExecute(ren->shadows, light_space_matrix, entities, entity_count);
}
Mesh Mesh_Create(Geometry* geometry, bool free_on_upload) {
- Mesh m = { 0 };
-
- // Create and upload vertex buffer
- size_t vert_bytes = geometry->vertices->len * sizeof(Vertex);
- INFO("Creating vertex buffer with size %d (%d x %d)", vert_bytes, geometry->vertices->len,
- sizeof(Vertex));
- m.vertex_buffer = GPU_BufferCreate(vert_bytes, BUFFER_VERTEX, BUFFER_FLAG_GPU,
- geometry->vertices->data);
-
- // Create and upload index buffer
- size_t index_bytes = geometry->indices->len * sizeof(u32);
- INFO("Creating index buffer with size %d (len: %d)", index_bytes, geometry->indices->len);
- m.index_buffer = GPU_BufferCreate(index_bytes, BUFFER_INDEX, BUFFER_FLAG_GPU,
- geometry->indices->data);
-
- m.is_uploaded = true;
- m.geometry = geometry;
- if (free_on_upload) {
- Geometry_Destroy(geometry);
- }
- return m;
+ Mesh m = { 0 };
+
+ // Create and upload vertex buffer
+ size_t vert_bytes = geometry->vertices->len * sizeof(Vertex);
+ INFO("Creating vertex buffer with size %d (%d x %d)", vert_bytes, geometry->vertices->len,
+ sizeof(Vertex));
+ m.vertex_buffer =
+ GPU_BufferCreate(vert_bytes, BUFFER_VERTEX, BUFFER_FLAG_GPU, geometry->vertices->data);
+
+ // Create and upload index buffer
+ size_t index_bytes = geometry->indices->len * sizeof(u32);
+ INFO("Creating index buffer with size %d (len: %d)", index_bytes, geometry->indices->len);
+ m.index_buffer =
+ GPU_BufferCreate(index_bytes, BUFFER_INDEX, BUFFER_FLAG_GPU, geometry->indices->data);
+
+ m.is_uploaded = true;
+ m.geometry = geometry;
+ if (free_on_upload) {
+ Geometry_Destroy(geometry);
+ }
+ return m;
}
diff --git a/src/new_render/render_scene.h b/src/new_render/render_scene.h
index 7591d8f..791e862 100644
--- a/src/new_render/render_scene.h
+++ b/src/new_render/render_scene.h
@@ -11,7 +11,7 @@
* Whenever you call draw functions you can think of this as an implicit parameter. */
typedef struct RenderScene {
Camera camera;
- PointLight light;
+ DirectionalLight sun;
} RenderScene;
// --- Public APIs
diff --git a/src/new_render/render_types.h b/src/new_render/render_types.h
index 1cf6c7e..81cf1c3 100644
--- a/src/new_render/render_types.h
+++ b/src/new_render/render_types.h
@@ -32,6 +32,10 @@ typedef struct Mesh {
Geometry* geometry; // NULL means it has been freed CPU-side
bool is_uploaded; // has the data been uploaded to the GPU
} Mesh;
+#ifndef TYPED_MESH_ARRAY
+KITC_DECL_TYPED_ARRAY(Mesh)
+#define TYPED_MESH_ARRAY
+#endif
typedef struct TextureData {
TextureDesc description;
@@ -54,6 +58,7 @@ typedef struct Material {
typedef struct Model {
// meshes
+ Mesh_darray* meshes;
// materials
} Model;
diff --git a/src/new_render/shader_layouts.h b/src/new_render/shader_layouts.h
new file mode 100644
index 0000000..d1ed1cc
--- /dev/null
+++ b/src/new_render/shader_layouts.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "maths_types.h"
+#include "ral_types.h"
diff --git a/src/new_render/shadows.c b/src/new_render/shadows.c
new file mode 100644
index 0000000..df836b4
--- /dev/null
+++ b/src/new_render/shadows.c
@@ -0,0 +1,125 @@
+#include <string.h>
+#include "shadows.h"
+#include "core.h"
+#include "log.h"
+#include "maths.h"
+#include "ral_common.h"
+#include "ral_impl.h"
+#include "ral_types.h"
+#include "render.h"
+#include "render_scene.h"
+#include "render_types.h"
+
+typedef struct ShadowUniforms {
+ Mat4 light_space;
+ Mat4 model;
+} ShadowUniforms;
+
+ShaderDataLayout ShadowUniforms_GetLayout(void* data) {
+ ShadowUniforms* d = (ShadowUniforms*)data;
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "ShadowUniforms",
+ .kind = BINDING_BYTES,
+ .vis = VISIBILITY_VERTEX,
+ .data = { .bytes = { .size = sizeof(ShadowUniforms) } }
+ // TODO: split this into two bindings so we can update model matrix independently
+ };
+
+ if (has_data) {
+ b1.data.bytes.data = data;
+ }
+
+ return (ShaderDataLayout){ .binding_count = 1, .bindings = { b1 } };
+}
+
+void Shadow_Init(Shadow_Storage* storage, u32x2 shadowmap_extents) {
+ memset(storage, 0, sizeof(Shadow_Storage));
+ arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
+
+ TextureDesc depthmap_desc = { .extents = shadowmap_extents,
+ .format = TEXTURE_FORMAT_DEPTH_DEFAULT,
+ .tex_type = TEXTURE_TYPE_2D };
+ TextureHandle depthmap = GPU_TextureCreate(depthmap_desc, false, NULL);
+ storage->depth_texture = depthmap;
+
+ GPU_RenderpassDesc rpass_desc = { .default_framebuffer = false,
+ .has_color_target = false,
+ .has_depth_stencil = true,
+ .depth_stencil = depthmap };
+
+ storage->shadowmap_pass = GPU_Renderpass_Create(rpass_desc);
+
+ Str8 vert_path = str8("assets/shaders/shadows.vert");
+ Str8 frag_path = str8("assets/shaders/shadows.frag");
+ str8_opt vertex_shader = str8_from_file(&scratch, vert_path);
+ str8_opt 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 uniforms = { .data = NULL, .get_layout = &ShadowUniforms_GetLayout };
+
+ GraphicsPipelineDesc pipeline_desc = {
+ .debug_name = "Shadows Pipeline",
+ .vertex_desc = static_3d_vertex_description(),
+ .data_layouts = { uniforms },
+ .data_layouts_count = 1,
+ .vs = { .debug_name = "Shadows Vert shader",
+ .filepath = vert_path,
+ .code = vertex_shader.contents,
+ .is_spirv = false },
+ .fs = { .debug_name = "Shadows Frag shader",
+ .filepath = frag_path,
+ .code = fragment_shader.contents,
+ .is_spirv = false },
+ };
+ storage->pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, storage->shadowmap_pass);
+
+ arena_free_storage(&scratch);
+}
+
+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");
+
+ GPU_EncodeBindPipeline(&shadow_encoder, storage->pipeline);
+
+ ShadowUniforms uniforms = {
+ .light_space = light_space_transform,
+ .model = mat4_ident() // this will be overwritten for each Model
+ };
+ ShaderData shader_data = {
+ .data = &uniforms,
+ .get_layout = &ShadowUniforms_GetLayout,
+ };
+
+ for (size_t ent_i = 0; ent_i < entity_count; ent_i++) {
+ RenderEnt renderable = entities[ent_i];
+ if (renderable.casts_shadows) {
+ Model* model = MODEL_GET(renderable.model);
+
+ uniforms.model = renderable.affine; // update the model transform
+
+ size_t num_meshes = Mesh_darray_len(model->meshes);
+ for (u32 mesh_i = 0; mesh_i < num_meshes; mesh_i++) {
+ Mesh mesh = model->meshes->data[mesh_i];
+
+ GPU_EncodeBindShaderData(&shadow_encoder, 0, shader_data);
+ GPU_EncodeSetVertexBuffer(&shadow_encoder, mesh.vertex_buffer);
+ GPU_EncodeSetIndexBuffer(&shadow_encoder, mesh.index_buffer);
+ GPU_EncodeDrawIndexed(&shadow_encoder, mesh.geometry->indices->len);
+ }
+ }
+ }
+
+ GPU_CmdEncoder_EndRender(&shadow_encoder); // end renderpass
+}
+
+Handle Shadow_GetShadowMapTexture(Shadow_Storage* storage) {
+ return (Handle){ .raw = storage->depth_texture.raw };
+}
diff --git a/src/new_render/shadows.h b/src/new_render/shadows.h
index 82ded5c..81711de 100644
--- a/src/new_render/shadows.h
+++ b/src/new_render/shadows.h
@@ -6,9 +6,17 @@
#pragma once
#include "defines.h"
#include "ral.h"
+#include "ral_impl.h"
+#include "ral_types.h"
#include "render_types.h"
-typedef struct Shadow_Storage Shadow_Storage;
+typedef struct Shadow_Storage {
+ GPU_Renderpass* shadowmap_pass;
+ GPU_Pipeline* pipeline;
+ bool debug_quad_enabled;
+ TextureHandle depth_texture;
+ // TODO: Some statistics tracking
+} Shadow_Storage;
typedef struct Camera Camera;
typedef struct Mat4 Mat4;
@@ -26,4 +34,5 @@ PUB Handle Shadow_GetShadowMapTexture(Shadow_Storage* storage);
// --- Internal
GPU_Renderpass* Shadow_RPassCreate(); // Creates the render pass
GPU_Pipeline* Shadow_PipelineCreate(GPU_Renderpass* rpass); // Creates the pipeline
-void Shadow_ShadowmapExecute(Shadow_Storage* storage, Mat4 light_space_transform, RenderEnt* entites, size_t entity_count);
+void Shadow_ShadowmapExecute(Shadow_Storage* storage, Mat4 light_space_transform, RenderEnt* entities, size_t entity_count);
+void Shadow_RenderDebugQuad();