summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--assets/shaders/pbr_textured.vert16
-rw-r--r--assets/shaders/skybox.vert11
-rw-r--r--examples/game_demo/game_demo.c38
-rw-r--r--src/core/core.c2
-rw-r--r--src/maths/primitives.c2
-rw-r--r--src/new_render/pbr.c82
-rw-r--r--src/new_render/pbr.h20
-rw-r--r--src/new_render/render.c57
-rw-r--r--src/new_render/render.h4
-rw-r--r--src/new_render/render_types.h37
-rw-r--r--src/new_render/shader_layouts.h55
-rw-r--r--src/new_render/shadows.c21
-rw-r--r--src/new_render/shadows.h6
-rw-r--r--src/new_render/skybox.c61
-rw-r--r--src/new_render/skybox.h46
-rw-r--r--src/ral/backends/opengl/backend_opengl.c18
-rw-r--r--src/ral/ral_impl.h1
-rw-r--r--src/ral/ral_types.h8
-rw-r--r--src/render/ral.h184
-rw-r--r--src/render/render_types.h181
-rw-r--r--src/resources/gltf.c8
-rw-r--r--src/resources/loaders.h4
-rw-r--r--src/std/mem.c2
24 files changed, 430 insertions, 439 deletions
diff --git a/.gitignore b/.gitignore
index 605c5e9..0487669 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,7 @@ _temp
.clangd
.DS_Store
compile_commands.json
-node_modules/ \ No newline at end of file
+node_modules/
+
+# in case we accidentally use something not licensed properly, we will keep demo game assets ignored.
+assets/demo/
diff --git a/assets/shaders/pbr_textured.vert b/assets/shaders/pbr_textured.vert
index d0f8fd5..391cef3 100644
--- a/assets/shaders/pbr_textured.vert
+++ b/assets/shaders/pbr_textured.vert
@@ -5,12 +5,14 @@ layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoords;
-// Uniforms
-uniform MVP_Matrices {
- mat4 model; // TODO: make model a push constant/raw uniform
+uniform Camera {
mat4 view;
mat4 proj;
-} mvp;
+} cam;
+
+uniform Model {
+ mat4 inner;
+} model;
// Outputs
layout(location = 0) out vec3 fragWorldPos;
@@ -18,9 +20,9 @@ layout(location = 1) out vec3 fragNormal;
layout(location = 2) out vec2 fragTexCoords;
void main() {
- fragWorldPos = vec3(mvp.model * vec4(inPosition, 1.0));
- fragNormal = mat3(transpose(inverse(mvp.model))) * inNormal; // world-space normal
+ fragWorldPos = vec3(model.inner * vec4(inPosition, 1.0));
+ fragNormal = mat3(transpose(inverse(model.inner))) * inNormal; // world-space normal
fragTexCoords = inTexCoords;
- gl_Position = mvp.proj * mvp.view * mvp.model * vec4(inPosition, 1.0);
+ gl_Position = cam.proj * cam.view * model.inner * vec4(inPosition, 1.0);
}
diff --git a/assets/shaders/skybox.vert b/assets/shaders/skybox.vert
new file mode 100644
index 0000000..e9149d8
--- /dev/null
+++ b/assets/shaders/skybox.vert
@@ -0,0 +1,11 @@
+#version 410 core
+
+layout(location = 0) in vec3 inPos;
+
+uniform In {
+ vec3 textureDir;
+} inc;
+
+void main() {
+
+} \ No newline at end of file
diff --git a/examples/game_demo/game_demo.c b/examples/game_demo/game_demo.c
index ef72cc6..10dd2be 100644
--- a/examples/game_demo/game_demo.c
+++ b/examples/game_demo/game_demo.c
@@ -6,7 +6,10 @@
#include <assert.h>
#include "camera.h"
#include "core.h"
+#include "loaders.h"
#include "maths.h"
+#include "primitives.h"
+#include "ral_types.h"
#include "render.h"
#include "render_scene.h"
#include "render_types.h"
@@ -15,9 +18,9 @@
#include "terrain.h"
#include "transform_hierarchy.h"
-static const char* faces[6] = { "assets/demo/skybox/left.jpg", "assets/demo/skybox/right.jpg",
- "assets/demo/skybox/front.jpg", "assets/demo/skybox/back.jpg",
- "assets/demo/skybox/top.jpg", "assets/demo/skybox/bottom.jpg" };
+static const char* faces[6] = { "assets/demo/skybox/right.jpg", "assets/demo/skybox/left.jpg",
+ "assets/demo/skybox/top.jpg", "assets/demo/skybox/bottom.jpg",
+ "assets/demo/skybox/back.jpg", "assets/demo/skybox/front.jpg" };
int main() {
Core_Bringup();
@@ -44,11 +47,34 @@ int main() {
// assert(Terrain_IsActive());
// --- Skybox
- // Skybox skybox = Skybox_Create(faces, 6);
+ Skybox skybox = Skybox_Create(faces, 6);
// --- Models
- // ModelHandle player_model = ModelLoad("Player Model", "assets/demo/player.gltf");
+ // ModelHandle player_model = ModelLoad_gltf("Player Model", "assets/demo/player.gltf");
// ModelHandle sword_model = ModelLoad("Sword Model", "assets/demo/sword.gltf");
+ // create a wooden crate
+ Geometry cube_geo = Geo_CreateCuboid(f32x3(2.0, 2.0, 2.0));
+ Mesh crate_mesh = Mesh_Create(&cube_geo, false); // dont free as we may use later
+ TextureHandle albedo_map = TextureLoadFromFile("assets/demo/crate/Wood_Crate_001_basecolor.jpg");
+ TextureHandle roughness_map =
+ TextureLoadFromFile("assets/demo/crate/Wood_Crate_001_roughness.jpg");
+ TextureHandle normal_map = TextureLoadFromFile("assets/demo/crate/Wood_Crate_001_normal.jpg");
+ TextureHandle ao_map =
+ TextureLoadFromFile("assets/demo/crate/Wood_Crate_001_ambientOcclusion.jpg");
+ Material crate_mat = { .name = "Wood_Crate",
+ .kind = MAT_PBR,
+ .metal_roughness_combined = true,
+ .pbr_albedo_map = albedo_map,
+ .pbr_metallic_map = roughness_map,
+ .pbr_normal_map = normal_map,
+ .pbr_ao_map = ao_map };
+
+ RenderEnt crate_renderable = {
+ .mesh = &crate_mesh, .material = &crate_mat, .affine = mat4_ident(), .casts_shadows = true
+ };
+
+ RenderEnt entities[] = { crate_renderable };
+ size_t entity_count = 1;
// --- Transforms
// TransformHierarchy* scene_tree = TransformHierarchy_Create();
@@ -65,7 +91,7 @@ int main() {
// BEGIN Draw calls
// draw the player model with shadows
- // Render_RenderEntities(entities, 1);
+ Render_RenderEntities(entities, entity_count);
// Render_DrawTerrain();
// Skybox_Draw(&skybox);
diff --git a/src/core/core.c b/src/core/core.c
index de67b56..9945083 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -44,7 +44,7 @@ void Core_Bringup() {
size_t model_data_max = 1024 * 1024 * 1024;
arena model_arena = arena_create(malloc(model_data_max), model_data_max);
- // model_pool model_pool = model_pool_create(&model_arena, 256, sizeof(model));
+ Model_pool model_pool = Model_pool_create(&model_arena, 256, sizeof(Model));
// g_core.models = model_pool;
// INFO("Created model pool allocator");
diff --git a/src/maths/primitives.c b/src/maths/primitives.c
index e74afcb..04977a6 100644
--- a/src/maths/primitives.c
+++ b/src/maths/primitives.c
@@ -62,7 +62,7 @@ static const Vec3 FRONT_BOT_RIGHT = (Vec3){ 1, 0, 1 };
static const Vec3 FRONT_TOP_LEFT = (Vec3){ 0, 1, 1 };
static const Vec3 FRONT_TOP_RIGHT = (Vec3){ 1, 1, 1 };
-Geometry geo_create_cuboid(f32x3 extents) {
+Geometry Geo_CreateCuboid(f32x3 extents) {
Vertex_darray* vertices = Vertex_darray_new(36);
// back faces
diff --git a/src/new_render/pbr.c b/src/new_render/pbr.c
new file mode 100644
index 0000000..b1ca005
--- /dev/null
+++ b/src/new_render/pbr.c
@@ -0,0 +1,82 @@
+#include "pbr.h"
+#include "file.h"
+#include "log.h"
+#include "ral_common.h"
+#include "ral_impl.h"
+#include "ral_types.h"
+#include "shader_layouts.h"
+
+void PBR_Init(PBR_Storage* storage) {
+ INFO("PBR shaders init");
+ storage->pbr_pass = PBR_RPassCreate();
+ storage->pbr_pipeline = PBR_PipelineCreate(storage->pbr_pass);
+}
+
+GPU_Renderpass* PBR_RPassCreate() {
+ GPU_RenderpassDesc desc = { .default_framebuffer = true };
+ return GPU_Renderpass_Create(desc);
+}
+
+GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass) {
+ arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
+
+ Str8 vert_path = str8("assets/shaders/pbr_textured.vert");
+ Str8 frag_path = str8("assets/shaders/pbr_textured.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 camera_data = { .get_layout = &Binding_Camera_GetLayout };
+ ShaderData model_data = { .get_layout = &Binding_Model_GetLayout };
+ ShaderData material_data = { .get_layout = &PBRMaterial_GetLayout };
+
+ GraphicsPipelineDesc desc = {
+ .debug_name = "PBR Pipeline",
+ .vertex_desc = static_3d_vertex_description(),
+ .data_layouts = {camera_data,model_data,material_data},
+ .data_layouts_count = 3,
+ .vs = { .debug_name = "PBR (textured) Vertex Shader",
+ .filepath = vert_path,
+ .code = vertex_shader.contents },
+ .fs = { .debug_name = "PBR (textured) Fragment Shader",
+ .filepath = frag_path,
+ .code = fragment_shader.contents,
+ },
+ .depth_test = true,
+ .wireframe = false,
+ };
+ return GPU_GraphicsPipeline_Create(desc, rpass);
+}
+
+ShaderDataLayout PBRMaterial_GetLayout(void* data) {
+ PBRMaterialUniforms* d = (PBRMaterialUniforms*)data;
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "albedoMap",
+ .kind = BINDING_TEXTURE,
+ };
+ ShaderBinding b2 = {
+ .label = "metallicRoughnessMap",
+ .kind = BINDING_TEXTURE,
+ };
+ ShaderBinding b3 = {
+ .label = "aoMap",
+ .kind = BINDING_TEXTURE,
+ };
+ ShaderBinding b4 = {
+ .label = "normalMap",
+ .kind = BINDING_TEXTURE,
+ };
+
+ if (has_data) {
+ b1.data.texture.handle = d->mat.pbr_albedo_map;
+ b2.data.texture.handle = d->mat.pbr_metallic_map;
+ b3.data.texture.handle = d->mat.pbr_ao_map;
+ b4.data.texture.handle = d->mat.pbr_normal_map;
+ }
+
+ return (ShaderDataLayout){ .bindings = { b1, b2, b3, b4 }, .binding_count = 4 };
+} \ No newline at end of file
diff --git a/src/new_render/pbr.h b/src/new_render/pbr.h
index 7573563..4ee6810 100644
--- a/src/new_render/pbr.h
+++ b/src/new_render/pbr.h
@@ -4,16 +4,23 @@
*/
#pragma once
+#include "backend_opengl.h"
#include "defines.h"
#include "camera.h"
#include "maths_types.h"
-#include "ral/ral.h"
-#include "ral/ral_common.h"
-
-// PBR;
+#include "ral_types.h"
+#include "render_types.h"
// --- Public API
-typedef struct PBR_Storage PBR_Storage; // Stores all necessary data and handles
+typedef struct PBR_Storage {
+ GPU_Renderpass* pbr_pass;
+ GPU_Pipeline* pbr_pipeline;
+
+} PBR_Storage; // Stores all necessary data and handles
+
+typedef struct PBRMaterialUniforms {
+ Material mat;
+} PBRMaterialUniforms;
PUB void PBR_Init(PBR_Storage* storage);
@@ -45,7 +52,6 @@ typedef struct PBR_Textures {
// --- Internal
typedef struct MaterialMap MaterialMap;
-typedef struct RenderEnt RenderEnt;
GPU_Renderpass* PBR_RPassCreate();
GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass);
@@ -59,4 +65,4 @@ void PBR_Execute(
);
-// Internally this will need to update material parameters
+ShaderDataLayout PBRMaterial_GetLayout(void* data); \ No newline at end of file
diff --git a/src/new_render/render.c b/src/new_render/render.c
index 1fef610..1213f1d 100644
--- a/src/new_render/render.c
+++ b/src/new_render/render.c
@@ -18,6 +18,9 @@
#include "render_types.h"
#include "shadows.h"
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+
extern Core g_core;
struct Renderer {
@@ -91,6 +94,9 @@ bool Renderer_Init(RendererConfig config, Renderer* ren, GLFWwindow** out_window
ren->shadows = malloc(sizeof(Shadow_Storage));
Shadow_Init(ren->shadows, u32x2(512, 512));
+ ren->pbr = malloc(sizeof(PBR_Storage));
+ PBR_Init(ren->pbr);
+
return true;
}
@@ -118,13 +124,50 @@ void Render_RenderEntities(RenderEnt* entities, size_t entity_count) {
Renderer* ren = get_renderer();
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);
+ // TOOD: -- 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);
+}
+
+TextureData TextureDataLoad(const char* path, bool invert_y) {
+ TRACE("Load texture %s", path);
+
+ // load the file data
+ int width, height, num_channels;
+ stbi_set_flip_vertically_on_load(invert_y);
+
+#pragma GCC diagnostic ignored "-Wpointer-sign"
+ char* data = stbi_load(path, &width, &height, &num_channels, STBI_rgb_alpha);
+ if (data) {
+ DEBUG("loaded texture: %s", path);
+ } else {
+ WARN("failed to load texture");
+ }
+
+ unsigned int channel_type;
+ GPU_TextureFormat format;
+ if (num_channels == 4) {
+ channel_type = GL_RGBA;
+ format = TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM;
+ } else {
+ channel_type = GL_RGB;
+ format = TEXTURE_FORMAT_8_8_8_RGB_UNORM;
+ }
+ TextureDesc desc = { .extents = { width, height },
+ .format = format,
+ .tex_type = TEXTURE_TYPE_2D };
+
+ return (TextureData){ .description = desc, .image_data = data };
+}
+
+TextureHandle TextureLoadFromFile(const char* path) {
+ TextureData tex_data = TextureDataLoad(path, false);
+ TextureHandle h = GPU_TextureCreate(tex_data.description, true, tex_data.image_data);
+ return h;
}
Mesh Mesh_Create(Geometry* geometry, bool free_on_upload) {
diff --git a/src/new_render/render.h b/src/new_render/render.h
index fa05fec..de84eda 100644
--- a/src/new_render/render.h
+++ b/src/new_render/render.h
@@ -41,7 +41,9 @@ PUB void Render_RenderEntities(RenderEnt* entities, size_t entity_count);
// --- Resources
-PUB TextureHandle TextureUpload();
+PUB TextureData TextureDataLoad(const char* path, bool invert_y);
+PUB void TextureUpload(TextureHandle handle, size_t n_bytes, const void* data);
+PUB TextureHandle TextureLoadFromFile(const char* path);
PUB ModelHandle ModelLoad(const char* debug_name, const char* filepath);
// --- Rendering Data
diff --git a/src/new_render/render_types.h b/src/new_render/render_types.h
index 81cf1c3..376e512 100644
--- a/src/new_render/render_types.h
+++ b/src/new_render/render_types.h
@@ -30,6 +30,7 @@ typedef struct Mesh {
BufferHandle vertex_buffer;
BufferHandle index_buffer;
Geometry* geometry; // NULL means it has been freed CPU-side
+ i32 material_index; // -1 => no material
bool is_uploaded; // has the data been uploaded to the GPU
} Mesh;
#ifndef TYPED_MESH_ARRAY
@@ -44,8 +45,8 @@ typedef struct TextureData {
// --- Supported materials
typedef enum MaterialKind {
- MAT_BLINN_PHONG,
- MAT_PBR,
+ MAT_BLINN_PHONG, // NOTE: we're dropping support for this
+ MAT_PBR, // uses textures for PBR properties
MAT_PBR_PARAMS, // uses float values to represent a surface uniformly
MAT_COUNT
} MaterialKind;
@@ -54,13 +55,35 @@ static const char* material_kind_names[] = { "Blinn Phong", "PBR (Textures)", "P
typedef struct Material {
char name[64];
+ MaterialKind kind;
+ // parameterised pbr
+ Vec3 param_albedo;
+ f32 param_metallic;
+ f32 param_roughness;
+ f32 param_ao;
+ // textured pbr
+ TextureHandle pbr_albedo_map;
+ TextureHandle pbr_normal_map;
+ bool metal_roughness_combined;
+ TextureHandle pbr_metallic_map;
+ TextureHandle pbr_roughness_map;
+ TextureHandle pbr_ao_map;
} Material;
+#ifndef TYPED_MATERIAL_ARRAY
+KITC_DECL_TYPED_ARRAY(Material)
+#define TYPED_MATERIAL_ARRAY
+#endif
typedef struct Model {
+ Str8 name;
// meshes
Mesh_darray* meshes;
- // materials
+ Material_darray* materials;
} Model;
+#ifndef TYPED_MODEL_ARRAY
+KITC_DECL_TYPED_ARRAY(Model)
+#define TYPED_MODEL_ARRAY
+#endif
// TODO: function to create a model from a single mesh (like when using primitives)
@@ -84,8 +107,14 @@ typedef struct DirectionalLight {
// A renderable 'thing'
typedef struct RenderEnt {
- ModelHandle model;
+ Mesh* mesh;
+ Material* material;
Mat4 affine; // In the future this should be updated by the transform graph
// Bbox_3D bounding_box;
bool casts_shadows;
} RenderEnt;
+
+#ifndef TYPED_RENDERENT_ARRAY
+KITC_DECL_TYPED_ARRAY(RenderEnt)
+#define TYPED_RENDERENT_ARRAY
+#endif \ No newline at end of file
diff --git a/src/new_render/shader_layouts.h b/src/new_render/shader_layouts.h
index d1ed1cc..e34e790 100644
--- a/src/new_render/shader_layouts.h
+++ b/src/new_render/shader_layouts.h
@@ -1,3 +1,58 @@
#pragma once
#include "maths_types.h"
#include "ral_types.h"
+
+/** @brief shader layout for camera matrices */
+typedef struct Binding_Camera {
+ Mat4 view;
+ Mat4 projection;
+} Binding_Camera;
+
+typedef struct Binding_Model {
+ Mat4 model;
+} Binding_Model;
+
+/** @brief data that is handy to have in any shader */
+typedef struct Binding_Globals {
+
+} Binding_Globals;
+
+typedef struct pbr_point_light {
+ Vec3 pos;
+ f32 pad;
+ Vec3 color;
+ f32 pad2;
+} pbr_point_light;
+
+typedef struct Binding_PointLights {
+ pbr_point_light pointLights[4];
+ Vec4 viewPos;
+} Binding_PointLights;
+
+static ShaderDataLayout Binding_Camera_GetLayout(void* data) {
+ Binding_Camera* d = data;
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "Camera",
+ .kind = BINDING_BYTES
+ };
+ if (has_data) {
+ b1.data.bytes.data = d;
+ }
+ return (ShaderDataLayout) {.bindings = {b1 }, .binding_count = 1};
+}
+
+static ShaderDataLayout Binding_Model_GetLayout(void* data) {
+ Binding_Model* d = data;
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "Model",
+ .kind = BINDING_BYTES
+ };
+ if (has_data) {
+ b1.data.bytes.data = d;
+ }
+ return (ShaderDataLayout) {.bindings = {b1 }, .binding_count = 1};
+} \ No newline at end of file
diff --git a/src/new_render/shadows.c b/src/new_render/shadows.c
index 612fd34..24bfb57 100644
--- a/src/new_render/shadows.c
+++ b/src/new_render/shadows.c
@@ -11,11 +11,6 @@
#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;
@@ -102,19 +97,15 @@ void Shadow_ShadowmapExecute(Shadow_Storage* storage, Mat4 light_space_transform
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);
+ // 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);
- }
+ Mesh* mesh = renderable.mesh;
+ 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);
}
}
diff --git a/src/new_render/shadows.h b/src/new_render/shadows.h
index 4dc20e2..9e8a6ad 100644
--- a/src/new_render/shadows.h
+++ b/src/new_render/shadows.h
@@ -5,7 +5,6 @@
#pragma once
#include "defines.h"
-#include "ral.h"
#include "ral_impl.h"
#include "ral_types.h"
#include "render_types.h"
@@ -18,6 +17,11 @@ typedef struct Shadow_Storage {
// TODO: Some statistics tracking
} Shadow_Storage;
+typedef struct ShadowUniforms {
+ Mat4 light_space;
+ Mat4 model;
+} ShadowUniforms;
+
typedef struct Camera Camera;
typedef struct Mat4 Mat4;
diff --git a/src/new_render/skybox.c b/src/new_render/skybox.c
new file mode 100644
index 0000000..6afefc3
--- /dev/null
+++ b/src/new_render/skybox.c
@@ -0,0 +1,61 @@
+#include "skybox.h"
+#include <assert.h>
+#include "glad/glad.h"
+#include "ral_common.h"
+#include "ral_impl.h"
+#include "ral_types.h"
+#include "render.h"
+#include "render_types.h"
+
+Skybox Skybox_Create(const char** face_paths, int n) {
+ assert(n == 6); // ! we're only supporting a full cubemap for now
+
+ // -- cubemap texture
+ TextureHandle handle;
+ GPU_Texture* tex = GPU_TextureAlloc(&handle);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, tex->id);
+
+ int width, height, nrChannels;
+ // unsigned char *data;
+ for (unsigned int i = 0; i < n; i++) {
+ TextureData data = TextureDataLoad(
+ face_paths[i],
+ false); // stbi_load(textures_faces[i].c_str(), &width, &height, &nrChannels, 0);
+ assert(data.description.format == TEXTURE_FORMAT_8_8_8_RGB_UNORM);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, data.description.extents.x,
+ data.description.extents.y, 0, GL_RGB, GL_UNSIGNED_BYTE, data.image_data);
+ }
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ // shader pipeline
+
+ VertexDescription pos_only = { .debug_label = "Position only verts" };
+ VertexDesc_AddAttr(&pos_only, "inPos", ATTR_F32x3);
+ pos_only.use_full_vertex_size = true;
+
+ ShaderData shader_data = { .data = NULL, .get_layout = &Skybox_GetLayout };
+
+ GraphicsPipelineDesc pipeline_desc = {
+ .debug_name = "Skybox pipeline",
+ .vertex_desc = pos_only,
+ .data_layouts = { shader_data },
+ .data_layouts_count = 1,
+ .vs = {
+
+ },
+ .fs = {
+
+ },
+ .wireframe = false,
+ .depth_test = true,
+ };
+
+ return (Skybox){
+ .texture = handle,
+
+ };
+} \ No newline at end of file
diff --git a/src/new_render/skybox.h b/src/new_render/skybox.h
index 9bdc2ec..ec06658 100644
--- a/src/new_render/skybox.h
+++ b/src/new_render/skybox.h
@@ -7,20 +7,6 @@
#include "defines.h"
#include "ral_types.h"
-typedef struct CubeMapData {
- void* top_image_data;
- void* bottom_image_data;
- void* left_image_data;
- void* right_image_data;
- void* front_image_data;
- void* back_image_data;
- u32 width, height, num_channels;
-} CubeMapData;
-
-PUB void CubeMapData_Load(const char** face_paths, int n); // should always pass n = 6 for now
-PUB void CubeMapData_Free(CubeMapData* cubemap); // Frees all the image data for a cubemap
-PUB TextureHandle CubeMapData_Upload(CubeMapData* cubemap);
-
typedef struct Skybox {
BufferHandle vertex_buffer;
TextureHandle texture;
@@ -30,3 +16,35 @@ typedef struct Skybox {
PUB Skybox Skybox_Create(const char** face_paths, int n); // should always pass n = 6 for now
PUB void Skybox_Draw(Skybox* skybox);
+
+typedef struct SkyboxUniforms {
+ Vec3 in_pos;
+ TextureHandle cubemap;
+} SkyboxUniforms;
+
+static ShaderDataLayout Skybox_GetLayout(void* data) {
+ SkyboxUniforms* d = (SkyboxUniforms*)data; // cold cast
+ bool has_data = data != NULL;
+
+ ShaderBinding b1 = {
+ .label = "In",
+ .vis = VISIBILITY_VERTEX,
+ .kind = BINDING_BYTES,
+ .data = {.bytes = {.size = sizeof(Vec3)}}
+ };
+
+ ShaderBinding b2 = {
+ .label = "cubemap",
+ .vis = VISIBILITY_FRAGMENT,
+ .kind = BINDING_SAMPLER,
+ };
+
+ if (has_data) {
+ b1.data.bytes.data = &d->in_pos;
+ b2.data.texture.handle = d->cubemap;
+ }
+ return (ShaderDataLayout) {
+ .bindings = { b1, b2},
+ .binding_count = 2
+ };
+} \ No newline at end of file
diff --git a/src/ral/backends/opengl/backend_opengl.c b/src/ral/backends/opengl/backend_opengl.c
index cbfd855..ecf0e80 100644
--- a/src/ral/backends/opengl/backend_opengl.c
+++ b/src/ral/backends/opengl/backend_opengl.c
@@ -174,7 +174,7 @@ BufferHandle GPU_BufferCreate(u64 size, GPU_BufferType buf_type, GPU_BufferFlags
const void* data) {
// "allocating" the cpu-side buffer struct
BufferHandle handle;
- GPU_Buffer* buffer = Buffer_pool_alloc(&context.resource_pools, &handle);
+ GPU_Buffer* buffer = Buffer_pool_alloc(&context.resource_pools->buffers, &handle);
buffer->size = size;
buffer->vao = 0;
@@ -269,6 +269,22 @@ TextureHandle GPU_TextureCreate(TextureDesc desc, bool create_view, const void*
return handle;
}
+GPU_Texture* GPU_TextureAlloc(TextureHandle* out_handle) {
+ TextureHandle handle;
+ GPU_Texture* texture = Texture_pool_alloc(&context.resource_pools->textures, &handle);
+ DEBUG("Allocated texture with handle %d", handle.raw);
+
+ GLuint gl_texture_id;
+ glGenTextures(1, &gl_texture_id);
+ texture->id = gl_texture_id;
+
+ if (out_handle != NULL) {
+ *out_handle = handle;
+ }
+
+ return texture;
+}
+
void GPU_TextureDestroy(TextureHandle handle) { glDeleteTextures(1, &handle.raw); }
// TODO: void GPU_TextureUpload(TextureHandle handle, size_t n_bytes, const void* data)
diff --git a/src/ral/ral_impl.h b/src/ral/ral_impl.h
index 7cc9459..9343962 100644
--- a/src/ral/ral_impl.h
+++ b/src/ral/ral_impl.h
@@ -52,6 +52,7 @@ PUB void GPU_BufferUpload(BufferHandle buffer, size_t n_bytes, const void* data)
// --- Textures
PUB TextureHandle GPU_TextureCreate(TextureDesc desc, bool create_view, const void* data);
+PUB GPU_Texture* GPU_TextureAlloc(TextureHandle* out_handle);
PUB void GPU_TextureDestroy(TextureHandle handle);
PUB void GPU_TextureUpload(TextureHandle handle, size_t n_bytes, const void* data);
diff --git a/src/ral/ral_types.h b/src/ral/ral_types.h
index ffcc2cd..092bb2b 100644
--- a/src/ral/ral_types.h
+++ b/src/ral/ral_types.h
@@ -55,6 +55,7 @@ typedef enum GPU_TextureType {
typedef enum GPU_TextureFormat {
TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
+ TEXTURE_FORMAT_8_8_8_RGB_UNORM,
TEXTURE_FORMAT_DEPTH_DEFAULT,
TEXTURE_FORMAT_COUNT
} GPU_TextureFormat;
@@ -144,6 +145,11 @@ typedef struct VertexDescription {
} VertexDescription;
// --- Shaders
+typedef enum PipelineKind {
+ PIPELINE_GRAPHICS,
+ PIPELINE_COMPUTE,
+} PipelineKind;
+
typedef enum ShaderVisibility {
VISIBILITY_VERTEX = 1 << 0,
VISIBILITY_FRAGMENT = 1 << 1,
@@ -164,7 +170,7 @@ typedef enum ShaderBindingKind {
BINDING_BUFFER_ARRAY,
BINDING_TEXTURE,
BINDING_TEXTURE_ARRAY,
- // TODO: sampler
+ BINDING_SAMPLER,
BINDING_COUNT
} ShaderBindingKind;
diff --git a/src/render/ral.h b/src/render/ral.h
deleted file mode 100644
index fc3c96c..0000000
--- a/src/render/ral.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/**
- * @file ral.h
- * @author your name (you@domain.com)
- * @brief Render Abstraction Layer
- * @details API that a graphics backend *must* implement
- * @version 0.1
- * @date 2024-03-31
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include "buf.h"
-#include "defines.h"
-#include "mem.h"
-#include "ral_types.h"
-#include "str.h"
-
-// Unrelated forward declares
-struct GLFWwindow;
-
-// Forward declare structs - these must be defined in the backend implementation
-typedef struct gpu_swapchain gpu_swapchain;
-typedef struct gpu_device gpu_device;
-typedef struct gpu_pipeline_layout gpu_pipeline_layout;
-typedef struct gpu_pipeline gpu_pipeline;
-typedef struct gpu_renderpass gpu_renderpass;
-typedef struct gpu_cmd_encoder gpu_cmd_encoder; // Recording
-typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission
-typedef struct gpu_buffer gpu_buffer;
-typedef struct gpu_texture gpu_texture;
-
-// #define MAX_SHADER_DATA_LAYOUTS 5
-// #define MAX_BUFFERS 256
-// #define MAX_TEXTURES 256
-// #define MAX_PIPELINES 128
-// #define MAX_RENDERPASSES 128
-
-// TYPED_POOL(gpu_buffer, buffer);
-// TYPED_POOL(gpu_texture, texture);
-
-// TYPED_POOL(gpu_pipeline_layout, pipeline_layout);
-// TYPED_POOL(gpu_pipeline, pipeline);
-// TYPED_POOL(gpu_renderpass, renderpass);
-
-// // --- Handy macros
-// #define BUFFER_GET(h) (buffer_pool_get(&context.resource_pools->buffers, h))
-// #define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h))
-
-// --- Pools
-// typedef struct gpu_backend_pools {
-// pipeline_pool pipelines;
-// pipeline_layout_pool pipeline_layouts;
-// renderpass_pool renderpasses;
-// } gpu_backend_pools;
-// void backend_pools_init(arena* a, gpu_backend_pools* backend_pools);
-
-// struct resource_pools {
-// buffer_pool buffers;
-// texture_pool textures;
-// };
-// void resource_pools_init(arena* a, struct resource_pools* res_pools);
-
-// --- Pipeline description
-typedef enum pipeline_kind {
- PIPELINE_GRAPHICS,
- PIPELINE_COMPUTE,
-} pipeline_kind;
-
-typedef struct shader_desc {
- const char* debug_name;
- str8 filepath; // Where it came from
- str8 code; // Either GLSL or SPIRV bytecode
- bool is_spirv;
- bool is_combined_vert_frag; // Contains both vertex and fragment stages
-} shader_desc;
-
-shader_desc shader_quick_load(const char* filepath);
-/** @brief Hot reloads shaders for the given pipeline. Returns how long it took in milliseconds */
-u64 gpu_pipeline_reload_shaders(gpu_pipeline* pipeline); // TODO
-
-struct graphics_pipeline_desc {
- const char* debug_name;
- vertex_description vertex_desc;
- shader_desc vs; /** @brief Vertex shader stage */
- shader_desc fs; /** @brief Fragment shader stage */
-
- // Roughly equivalent to a descriptor set layout each. each layout can have multiple bindings
- // examples:
- // - uniform buffer reprensenting view projection matrix
- // - texture for shadow map
- shader_data data_layouts[MAX_SHADER_DATA_LAYOUTS];
- u32 data_layouts_count;
-
- // gpu_pipeline_layout* layout;
- gpu_renderpass* renderpass;
-
- bool wireframe;
- bool depth_test;
-};
-
-typedef struct gpu_renderpass_desc {
- bool default_framebuffer;
- bool has_color_target;
- texture_handle color_target; // for now only support one
- bool has_depth_stencil;
- texture_handle depth_stencil;
-} gpu_renderpass_desc;
-
-// --- Lifecycle functions
-// bool gpu_backend_init(const char* window_name, struct GLFWwindow* window);
-// void gpu_backend_shutdown();
-void resource_pools_init(arena* a, struct resource_pools* res_pools);
-
-// bool gpu_device_create(gpu_device* out_device);
-// void gpu_device_destroy();
-
-// // --- Render Pipeline
-// gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description);
-// void gpu_pipeline_destroy(gpu_pipeline* pipeline);
-
-// // --- Renderpass
-// gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description);
-// void gpu_renderpass_destroy(gpu_renderpass* pass);
-
-// // --- Swapchain
-// bool gpu_swapchain_create(gpu_swapchain* out_swapchain);
-// void gpu_swapchain_destroy(gpu_swapchain* swapchain);
-
-// --- Command buffer
-gpu_cmd_encoder gpu_cmd_encoder_create();
-void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder);
-void gpu_cmd_encoder_begin(gpu_cmd_encoder encoder);
-void gpu_cmd_encoder_begin_render(gpu_cmd_encoder* encoder, gpu_renderpass* renderpass);
-void gpu_cmd_encoder_end_render(gpu_cmd_encoder* encoder);
-void gpu_cmd_encoder_begin_compute();
-gpu_cmd_encoder* gpu_get_default_cmd_encoder();
-
-/** @brief Finish recording and return a command buffer that can be submitted to a queue */
-gpu_cmd_buffer gpu_cmd_encoder_finish(gpu_cmd_encoder* encoder);
-
-void gpu_queue_submit(gpu_cmd_buffer* buffer);
-
-// --- Data copy commands
-/** @brief Copy data from one buffer to another */
-void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset,
- buffer_handle dst, u64 dst_offset, u64 copy_size);
-/** @brief Upload CPU-side data as array of bytes to a GPU buffer */
-void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size);
-
-/** @brief Copy data from buffer to buffer using a one time submit command buffer and a wait */
-void copy_buffer_to_buffer_oneshot(buffer_handle src, u64 src_offset, buffer_handle dst,
- u64 dst_offset, u64 copy_size);
-/** @brief Copy data from buffer to an image using a one time submit command buffer */
-void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst);
-
-// --- Render commands
-void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipeline* pipeline);
-void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data);
-void encode_set_default_settings(gpu_cmd_encoder* encoder);
-void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
-void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
-void encode_set_bind_group(); // TODO
-void encode_draw(gpu_cmd_encoder* encoder, u64 count);
-void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count);
-void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
-
-// --- Buffers
-// --- Vertex formats
-bytebuffer vertices_as_bytebuffer(arena* a, vertex_format format, vertex_darray* vertices);
-
-void vertex_desc_add(vertex_description* builder, const char* name, vertex_attrib_type type);
-
-// --- TEMP
-bool gpu_backend_begin_frame();
-void gpu_backend_end_frame();
-void gpu_temp_draw(size_t n_verts);
-
-// TODO: --- Compute
-
-// --- Helpers
-vertex_description static_3d_vertex_description();
-size_t vertex_attrib_size(vertex_attrib_type attr);
diff --git a/src/render/render_types.h b/src/render/render_types.h
deleted file mode 100644
index b25fa14..0000000
--- a/src/render/render_types.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * @file render_types.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-04-27
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include "colours.h"
-#include "defines.h"
-#include "ral.h"
-#include "ral_types.h"
-#if defined(CEL_PLATFORM_WINDOWS)
-// #include "backend_dx11.h"
-#endif
-#if defined(CEL_REND_BACKEND_VULKAN)
-#include "backend_vulkan.h"
-#elif defined(CEL_REND_BACKEND_METAL)
-#include "backend_metal.h"
-#elif defined(CEL_REND_BACKEND_OPENGL)
-#include "backend_opengl.h"
-#endif
-
-struct GLFWwindow;
-
-typedef struct geometry_data {
- vertex_format format;
- vertex_darray* vertices; // TODO: make it not a pointer
- bool has_indices;
- u32_darray* indices;
- rgba colour; /** Optional: set vertex colours */
-} geometry_data;
-
-typedef struct u32_opt {
- u32 value;
- bool has_value;
-} u32_opt;
-
-// 'Upload' a geometry_data (to GPU) -> get back a mesh
-typedef struct mesh {
- buffer_handle vertex_buffer;
- buffer_handle index_buffer;
- geometry_data* geometry; // NULL means it has been freed
- u32_opt material_index;
- bool is_uploaded;
- bool is_latent;
-} mesh;
-
-#ifndef TYPED_MESH_ARRAY
-KITC_DECL_TYPED_ARRAY(mesh)
-#define TYPED_MESH_ARRAY
-#endif
-
-/* Hot reloading:
-C side - reload_model():
- - load model from disk using existing loader
- - remove from transform graph so it isnt tried to be drawn
-*/
-
-typedef struct texture {
-} texture;
-
-typedef struct texture_data {
- texture_desc description;
- void* image_data;
-} texture_data;
-
-typedef enum material_kind {
- MAT_BLINN_PHONG,
- MAT_PBR,
- MAT_PBR_PARAMS, // uses float values to represent a surface uniformly
- MAT_COUNT
-} material_kind;
-static const char* material_kind_names[] = { "Blinn Phong", "PBR (Textures)", "PBR (Params)",
- "Count (This should be an error)" };
-
-typedef struct blinn_phong_material {
- char name[256];
- texture diffuse_texture;
- char diffuse_tex_path[256];
- texture specular_texture;
- char specular_tex_path[256];
- vec3 ambient_colour;
- vec3 diffuse;
- vec3 specular;
- f32 spec_exponent;
- bool is_loaded;
- bool is_uploaded;
-} blinn_phong_material;
-// typedef blinn_phong_material material;
-
-typedef struct pbr_parameters {
- vec3 albedo;
- f32 metallic;
- f32 roughness;
- f32 ao;
-} pbr_parameters;
-
-typedef struct pbr_material {
- texture_handle albedo_map;
- texture_handle normal_map;
- bool metal_roughness_combined;
- texture_handle metallic_map;
- texture_handle roughness_map;
- texture_handle ao_map;
-} pbr_material;
-
-typedef struct material {
- material_kind kind;
- union {
- blinn_phong_material blinn_phong;
- pbr_parameters pbr_params;
- pbr_material pbr;
- } mat_data;
- char* name;
-} material;
-
-#ifndef TYPED_MATERIAL_ARRAY
-KITC_DECL_TYPED_ARRAY(material)
-#define TYPED_MATERIAL_ARRAY
-#endif
-
-CORE_DEFINE_HANDLE(model_handle);
-
-typedef struct model {
- str8 name;
- mesh_darray* meshes;
- material_darray* materials;
-} model;
-
-TYPED_POOL(model, model)
-
-// FIXME: the default blinn-phong material. MUST be initialised with the function below
-// FIXME: extern material DEFAULT_MATERIAL;
-void default_material_init();
-
-#ifndef TYPED_MODEL_ARRAY
-KITC_DECL_TYPED_ARRAY(model)
-#define TYPED_MODEL_ARRAY
-#endif
-
-#ifndef TYPED_ANIMATION_CLIP_ARRAY
-#include "animation.h"
-KITC_DECL_TYPED_ARRAY(animation_clip)
-#define TYPED_ANIMATION_CLIP_ARRAY
-#endif
-
-/** @brief Describes all the data required for the renderer to start executing draws */
-typedef struct render_entity {
- /* buffer_handle index_buffer; */
- /* u32 index_count; */
- /* u32 index_offset; */
- /* buffer_handle vertex_buffer; */
- model_handle model;
- transform tf;
-} render_entity;
-
-#ifndef TYPED_RENDER_ENTITY_ARRAY
-KITC_DECL_TYPED_ARRAY(render_entity)
-#define TYPED_RENDER_ENTITY_ARRAY
-#endif
-
-// --- Lights
-typedef struct point_light {
- vec3 position;
- f32 constant, linear, quadratic;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
-} point_light;
-
-typedef struct directional_light {
- vec3 direction;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
-} directional_light;
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
index 69ae9e1..56d5660 100644
--- a/src/resources/gltf.c
+++ b/src/resources/gltf.c
@@ -50,10 +50,10 @@ ModelHandle model_load_gltf(const char *path, bool invert_texture_y) {
const char *file_string = string_from_file(path);
ModelHandle handle;
- // Model *model = model_pool_alloc(&g_core.models, &handle);
- // model->name = str8_cstr_view(path);
- // model->meshes = mesh_darray_new(1);
- // model->materials = material_darray_new(1);
+ Model *model = Model_pool_alloc(&g_core.models, &handle);
+ model->name = Str8_cstr_view(path);
+ model->meshes = Mesh_darray_new(1);
+ model->materials = Material_darray_new(1);
// bool success =
// model_load_gltf_str(file_string, path, relative_path.path, model, invert_texture_y);
diff --git a/src/resources/loaders.h b/src/resources/loaders.h
index 3ec41fa..677e2a7 100644
--- a/src/resources/loaders.h
+++ b/src/resources/loaders.h
@@ -5,8 +5,8 @@
#include "str.h"
// --- Public API
-PUB ModelHandle Model_Load_obj(const char *path, bool invert_texture_y);
-PUB ModelHandle Model_Load_gltf(const char *path, bool invert_texture_y);
+PUB ModelHandle ModelLoad_obj(const char *path, bool invert_texture_y);
+PUB ModelHandle ModelLoad_gltf(const char *path, bool invert_texture_y);
// --- Internal
bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 relative_path,
diff --git a/src/std/mem.c b/src/std/mem.c
index 5cc4304..4a4454a 100644
--- a/src/std/mem.c
+++ b/src/std/mem.c
@@ -93,7 +93,7 @@ void* void_pool_alloc(void_pool* pool, u32* out_raw_handle) {
return NULL;
}
if (pool->free_list_head == NULL) {
- ERROR("Pool is full (head = null)");
+ ERROR("%s Pool is full (head = null)", pool->debug_label);
return NULL;
}
void_pool_header* free_node = pool->free_list_head;