summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-10-05 12:48:05 +1000
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-10-05 12:48:05 +1000
commitdfb6adbcbcc7d50b770b6d5ea82efdd8f8c32e25 (patch)
treea470b91a90716d7ea46fde53ed395449c24583a2 /src
parent54354e32c6498cc7f8839ab4deb1208d37216cc5 (diff)
delete documentation workflow
Diffstat (limited to 'src')
-rw-r--r--src/animation.c90
-rw-r--r--src/animation.h122
-rw-r--r--src/collision.c9
-rw-r--r--src/colours.h89
-rw-r--r--src/core/README.md3
-rw-r--r--src/core/animation.c0
-rw-r--r--src/core/camera.c90
-rw-r--r--src/core/camera.h39
-rw-r--r--src/core/core.c81
-rw-r--r--src/core/core.h43
-rw-r--r--src/core/input.c0
-rw-r--r--src/core/triggers.h17
-rw-r--r--src/core/vfs.h38
-rw-r--r--src/empty.c3
-rw-r--r--src/log.c56
-rw-r--r--src/log.h84
-rw-r--r--src/logos/README.md6
-rw-r--r--src/logos/tasks.h74
-rw-r--r--src/logos/threadpool.c141
-rw-r--r--src/logos/threadpool.h96
-rw-r--r--src/maths/geometry.h50
-rw-r--r--src/maths/maths.c35
-rw-r--r--src/maths/maths.h321
-rw-r--r--src/maths/maths_types.h84
-rw-r--r--src/maths/primitives.c343
-rw-r--r--src/maths/primitives.h29
-rw-r--r--src/physics.h44
-rw-r--r--src/platform/file.c93
-rw-r--r--src/platform/file.h26
-rw-r--r--src/platform/platform.h37
-rw-r--r--src/platform/platform_unix.c16
-rw-r--r--src/platform/platform_windows.c22
-rw-r--r--src/ral/README.md5
-rw-r--r--src/ral/backends/metal/backend_metal.h0
-rw-r--r--src/ral/backends/opengl/backend_opengl.c449
-rw-r--r--src/ral/backends/opengl/backend_opengl.h109
-rw-r--r--src/ral/backends/opengl/opengl_helpers.h159
-rw-r--r--src/ral/backends/vulkan/backend_vulkan.c0
-rw-r--r--src/ral/backends/vulkan/backend_vulkan.h44
-rw-r--r--src/ral/backends/vulkan/vulkan_glossary.md18
-rw-r--r--src/ral/backends/vulkan/vulkan_helpers.h199
-rw-r--r--src/ral/ral.h5
-rw-r--r--src/ral/ral_common.c70
-rw-r--r--src/ral/ral_common.h61
-rw-r--r--src/ral/ral_impl.h102
-rw-r--r--src/ral/ral_types.h168
-rw-r--r--src/render/archive/backends/backend_test.c1
-rw-r--r--src/render/archive/backends/metal/README.md1
-rw-r--r--src/render/archive/backends/metal/backend_metal.h74
-rw-r--r--src/render/archive/backends/metal/backend_metal.m285
-rw-r--r--src/render/archive/backends/opengl/backend_opengl.c521
-rw-r--r--src/render/archive/backends/opengl/backend_opengl.h68
-rw-r--r--src/render/archive/backends/vulkan/README.md1
-rw-r--r--src/render/archive/backends/vulkan/backend_vulkan.c1705
-rw-r--r--src/render/archive/backends/vulkan/backend_vulkan.h118
-rw-r--r--src/render/immdraw.c176
-rw-r--r--src/render/immdraw.h63
-rw-r--r--src/render/pbr.c266
-rw-r--r--src/render/pbr.h70
-rw-r--r--src/render/render.c359
-rw-r--r--src/render/render.h151
-rw-r--r--src/render/render_types.h138
-rw-r--r--src/render/shader_layouts.h70
-rw-r--r--src/render/shadows.c211
-rw-r--r--src/render/shadows.h48
-rw-r--r--src/render/skybox.c161
-rw-r--r--src/render/skybox.h41
-rw-r--r--src/resources/gltf.c596
-rw-r--r--src/resources/loaders.h17
-rw-r--r--src/resources/obj.c398
-rw-r--r--src/std/buf.h11
-rw-r--r--src/std/containers/container_utils.h17
-rw-r--r--src/std/containers/darray.h151
-rw-r--r--src/std/containers/graphs.h14
-rw-r--r--src/std/containers/hashmap.h27
-rw-r--r--src/std/containers/hashset.h29
-rw-r--r--src/std/containers/ring_queue.c68
-rw-r--r--src/std/containers/ring_queue.h35
-rw-r--r--src/std/containers/stack_array.h19
-rw-r--r--src/std/mem.c135
-rw-r--r--src/std/mem.h96
-rw-r--r--src/std/str.c74
-rw-r--r--src/std/str.h89
-rw-r--r--src/std/utils.h4
-rw-r--r--src/systems/grid.c84
-rw-r--r--src/systems/grid.h21
-rw-r--r--src/systems/input.c105
-rw-r--r--src/systems/input.h53
-rw-r--r--src/systems/keys.h59
-rw-r--r--src/systems/screenspace.h53
-rw-r--r--src/systems/terrain.c204
-rw-r--r--src/systems/terrain.h72
-rw-r--r--src/systems/text.c1
-rw-r--r--src/systems/text.h53
-rw-r--r--src/transform_hierarchy.c185
-rw-r--r--src/transform_hierarchy.h80
96 files changed, 0 insertions, 10848 deletions
diff --git a/src/animation.c b/src/animation.c
deleted file mode 100644
index d7973dc..0000000
--- a/src/animation.c
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "animation.h"
-#include "immdraw.h"
-#include "log.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "ral_types.h"
-
-Keyframe Animation_Sample(AnimationSampler* sampler, f32 t) {
- size_t previous_index = 0;
- f32 previous_time = 0.0;
- // look forwards
- DEBUG("%d\n", keyframe_kind_strings[sampler->animation.values.kind]);
- TRACE("Total timestamps %d", sampler->animation.n_timestamps);
- for (u32 i = 0; i < sampler->animation.n_timestamps; i++) {
- f32 current_time = sampler->animation.timestamps[i];
- if (current_time > t) {
- break;
- }
- previous_time = sampler->animation.timestamps[i];
- previous_index = i;
- }
-
- size_t next_index = (previous_index + 1) % sampler->animation.n_timestamps;
- f32 next_time = sampler->animation.timestamps[next_index];
- printf("%d %f %d %f\n", previous_index, previous_time, next_index, next_time);
-
- Keyframe prev_value = sampler->animation.values.values[previous_index];
- Keyframe next_value = sampler->animation.values.values[next_index];
-
- printf("%d %d\n", previous_index, next_index);
-
- f32 time_diff =
- sampler->animation.timestamps[next_index] - sampler->animation.timestamps[previous_index];
- f32 percent = (t - previous_time) / time_diff;
-
- switch (sampler->animation.values.kind) {
- case KEYFRAME_ROTATION:
- return (Keyframe){ .rotation = quat_slerp(
- sampler->animation.values.values[previous_index].rotation,
- sampler->animation.values.values[next_index].rotation, percent) };
- case KEYFRAME_TRANSLATION:
- case KEYFRAME_SCALE:
- case KEYFRAME_WEIGHTS:
- WARN("TODO: other keyframe kind interpolation");
- return prev_value;
- }
-}
-
-void Animation_Tick(AnimationClip* clip, Armature* armature, f32 time) {
- TRACE("Ticking animation %s", clip->clip_name);
-
- for (u32 c_i = 0; c_i < clip->channels->len; c_i++) {
- AnimationSampler* sampler = clip->channels->data;
-
- // Interpolated keyframe based on time
- Keyframe k = Animation_Sample(sampler, time);
-
- // Get the joint in the armature
- Joint* joint = &armature->joints->data[sampler->target_joint_idx];
- if (sampler->animation.values.kind == KEYFRAME_ROTATION) {
- // Update the joints rotation
- joint->transform_components.rotation = k.rotation;
- } else {
- WARN("not yet implemented animation kind");
- }
- }
-}
-
-void Animation_VisualiseJoints(Armature* armature) {
- for (int j = 0; j < armature->joints->len; j++) {
- Joint joint = armature->joints->data[j];
- Transform tf = joint.transform_components;
- tf.scale = vec3(0.05, 0.05, 0.05);
- Immdraw_Sphere(tf, vec4(0, 1, 1, 1), true);
- }
-}
-
-ShaderDataLayout AnimData_GetLayout(void* data) {
- AnimDataUniform* d = data;
- bool has_data = data != NULL;
-
- ShaderBinding b1 = { .label = "AnimData",
- .kind = BINDING_BYTES,
- .data.bytes.size = sizeof(AnimDataUniform) };
-
- if (has_data) {
- b1.data.bytes.data = d;
- }
- return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 };
-}
diff --git a/src/animation.h b/src/animation.h
deleted file mode 100644
index 5883f13..0000000
--- a/src/animation.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#pragma once
-
-#include "cgltf.h"
-#include "darray.h"
-#include "defines.h"
-#include "maths_types.h"
-#include "ral_types.h"
-
-typedef enum Interpolation {
- INTERPOLATION_STEP,
- INTERPOLATION_LINEAR,
- INTERPOLATION_CUBIC, /** @brief Cubic spline interpolation */
- INTERPOLATION_COUNT
-} Interpolation;
-
-typedef enum KeyframeKind {
- KEYFRAME_ROTATION,
- KEYFRAME_TRANSLATION,
- KEYFRAME_SCALE,
- KEYFRAME_WEIGHTS,
-} KeyframeKind;
-
-static const char* keyframe_kind_strings[4] = { "ROTATION", "TRANSLATION", "SCALE", "WEIGHTS"};
-
-typedef union Keyframe {
- Quat rotation;
- Vec3 translation;
- Vec3 scale;
- f32 weights[4];
-} Keyframe;
-
-typedef struct Keyframes {
- KeyframeKind kind;
- Keyframe* values;
- size_t count;
-} Keyframes;
-
-typedef struct Joint {
- // used instead of pointers later to update correct joints
- size_t node_idx;
- ssize_t parent; // parent bone. -1 means its the root
- size_t children[8]; // children bones, upto 8
- u8 children_count;
- char* debug_label; // optional
- Mat4 inverse_bind_matrix;
- Mat4 local_transform;
- /** @brief holds position, rotation, and scale that will be written to by animation
- samplers every tick of the animation system. */
- Transform transform_components;
-} Joint;
-#ifndef TYPED_JOINT_ARRAY
-KITC_DECL_TYPED_ARRAY(Joint);
-#define TYPED_JOINT_ARRAY
-#endif
-
-typedef u32 JointIdx;
-
-typedef struct Armature {
- char* label;
- Joint_darray* joints;
-} Armature;
-
-// NOTE: I think we will need to topologically sort the joints to store them in array if we want to
-// do linear array traversal
-// when calculating transforms.
-
-typedef struct AnimationSpline {
- f32* timestamps;
- size_t n_timestamps;
- Keyframes values;
- Interpolation interpolation;
-} AnimationSpline;
-
-// combines a sampler and a channel in gltf
-typedef struct AnimationSampler {
- int current_index;
- f32 min;
- f32 max;
- AnimationSpline animation;
- u32 target_joint_idx; // index into the array of joints in an armature
-} AnimationSampler;
-#ifndef TYPED_ANIM_SAMPLER_ARRAY
-KITC_DECL_TYPED_ARRAY(AnimationSampler);
-#define TYPED_ANIM_SAMPLER_ARRAY
-#endif
-
-/** @brief Sample an animation at a given time `t` returning an interpolated keyframe */
-PUB Keyframe Animation_Sample(AnimationSampler* sampler, f32 t);
-
-/** @brief A clip contains one or more animation curves. */
-typedef struct AnimationClip {
- const char* clip_name;
- bool is_playing;
- f32 time;
- AnimationSampler_darray* channels;
-} AnimationClip;
-#ifndef TYPED_ANIM_CLIP_ARRAY
-KITC_DECL_TYPED_ARRAY(AnimationClip);
-#define TYPED_ANIM_CLIP_ARRAY
-#endif
-
-// typedef struct SkinnedAnimation {
-// Mat4* joint_matrices;
-// size_t n_joints;
-// } SkinnedAnimation;
-
-PUB void Animation_Play(AnimationClip* clip);
-
-void Animation_Tick(AnimationClip* clip, Armature* armature, f32 delta_time);
-
-void Animation_VisualiseJoints(Armature* armature);
-
-#define MAX_BONES 100
-
-typedef struct AnimDataUniform {
- Mat4 bone_matrices[MAX_BONES];
-} AnimDataUniform;
-ShaderDataLayout AnimData_GetLayout(void* data);
-
-// Animation Targets:
-// - Mesh
-// - Joint
diff --git a/src/collision.c b/src/collision.c
deleted file mode 100644
index 81cbcfc..0000000
--- a/src/collision.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "immdraw.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "physics.h"
-
-PUB void Debug_DrawOBB(OBB obb) {
- Transform t = transform_create(obb.center, obb.rotation, vec3_sub(obb.bbox.max, obb.bbox.min));
- Immdraw_Cuboid(t, vec4(0.0, 0.8, 0.1, 1.0), true);
-}
diff --git a/src/colours.h b/src/colours.h
deleted file mode 100644
index ac8996a..0000000
--- a/src/colours.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#pragma once
-
-#include "defines.h"
-
-typedef struct rgba {
- f32 r, g, b, a;
-} rgba;
-
-#define COLOUR_BLACK ((rgba){ 0.02, 0.02, 0.0, 1.0 })
-#define COLOUR_IMPERIAL_RED ((rgba){ 0.97, 0.09, 0.21, 1.0 })
-#define COLOUR_TRUE_BLUE ((rgba){ 0.11, 0.41, 0.77, 1.0 })
-#define COLOUR_SEA_GREEN ((rgba){ 0.18, 0.77, 0.71, 1.0 })
-#define COLOUR_WHITE ((rgba){ 1.0, 1.0, 1.0, 1.0 })
-
-#define rgba_to_vec4(color) (vec4(color.r, color.g, color.b, color.a))
-#define rgba_to_vec3(color) (vec3(color.r, color.g, color.b))
-
-// Thanks ChatGPT
-#define STONE_50 ((rgba){ 0.980, 0.980, 0.976, 1.0 })
-#define STONE_100 ((rgba){ 0.961, 0.961, 0.957, 1.0 })
-#define STONE_200 ((rgba){ 0.906, 0.898, 0.894, 1.0 })
-#define STONE_300 ((rgba){ 0.839, 0.827, 0.819, 1.0 })
-#define STONE_400 ((rgba){ 0.659, 0.635, 0.620, 1.0 })
-#define STONE_500 ((rgba){ 0.471, 0.443, 0.424, 1.0 })
-#define STONE_600 ((rgba){ 0.341, 0.325, 0.306, 1.0 })
-#define STONE_700 ((rgba){ 0.267, 0.251, 0.235, 1.0 })
-#define STONE_800 ((rgba){ 0.161, 0.145, 0.141, 1.0 })
-#define STONE_900 ((rgba){ 0.110, 0.098, 0.090, 1.0 })
-#define STONE_950 ((rgba){ 0.047, 0.043, 0.035, 1.0 })
-
-#define CYAN_50 ((rgba){ 0.930, 1.000, 1.000, 1.0 })
-#define CYAN_100 ((rgba){ 0.810, 0.980, 1.000, 1.0 })
-#define CYAN_200 ((rgba){ 0.650, 0.953, 0.988, 1.0 })
-#define CYAN_300 ((rgba){ 0.404, 0.910, 0.976, 1.0 })
-#define CYAN_400 ((rgba){ 0.133, 0.827, 0.933, 1.0 })
-#define CYAN_500 ((rgba){ 0.023, 0.714, 0.831, 1.0 })
-#define CYAN_600 ((rgba){ 0.031, 0.569, 0.698, 1.0 })
-#define CYAN_700 ((rgba){ 0.055, 0.455, 0.565, 1.0 })
-#define CYAN_800 ((rgba){ 0.082, 0.369, 0.459, 1.0 })
-#define CYAN_900 ((rgba){ 0.086, 0.306, 0.388, 1.0 })
-#define CYAN_950 ((rgba){ 0.033, 0.200, 0.263, 1.0 })
-
-#define GRAY_50 ((rgba){ 0.976, 0.980, 0.984, 1.0 })
-#define GRAY_100 ((rgba){ 0.953, 0.957, 0.965, 1.0 })
-#define GRAY_200 ((rgba){ 0.898, 0.906, 0.922, 1.0 })
-#define GRAY_300 ((rgba){ 0.820, 0.835, 0.859, 1.0 })
-#define GRAY_400 ((rgba){ 0.612, 0.639, 0.686, 1.0 })
-#define GRAY_500 ((rgba){ 0.420, 0.447, 0.502, 1.0 })
-#define GRAY_600 ((rgba){ 0.294, 0.333, 0.388, 1.0 })
-#define GRAY_700 ((rgba){ 0.216, 0.255, 0.318, 1.0 })
-#define GRAY_800 ((rgba){ 0.122, 0.161, 0.216, 1.0 })
-#define GRAY_900 ((rgba){ 0.067, 0.094, 0.153, 1.0 })
-#define GRAY_950 ((rgba){ 0.012, 0.027, 0.071, 1.0 })
-
-#define RED_50 ((rgba){ 0.996, 0.949, 0.949, 1.0 })
-#define RED_100 ((rgba){ 0.996, 0.886, 0.886, 1.0 })
-#define RED_200 ((rgba){ 0.996, 0.792, 0.792, 1.0 })
-#define RED_300 ((rgba){ 0.988, 0.647, 0.647, 1.0 })
-#define RED_400 ((rgba){ 0.973, 0.443, 0.443, 1.0 })
-#define RED_500 ((rgba){ 0.937, 0.267, 0.267, 1.0 })
-#define RED_600 ((rgba){ 0.863, 0.149, 0.149, 1.0 })
-#define RED_700 ((rgba){ 0.725, 0.110, 0.110, 1.0 })
-#define RED_800 ((rgba){ 0.600, 0.106, 0.106, 1.0 })
-#define RED_900 ((rgba){ 0.498, 0.114, 0.114, 1.0 })
-#define RED_950 ((rgba){ 0.271, 0.039, 0.039, 1.0 })
-
-#define ORANGE_50 ((rgba){ 1.000, 0.969, 0.929, 1.0 })
-#define ORANGE_100 ((rgba){ 1.000, 0.929, 0.835, 1.0 })
-#define ORANGE_200 ((rgba){ 0.996, 0.843, 0.667, 1.0 })
-#define ORANGE_300 ((rgba){ 0.992, 0.729, 0.455, 1.0 })
-#define ORANGE_400 ((rgba){ 0.984, 0.573, 0.235, 1.0 })
-#define ORANGE_500 ((rgba){ 0.976, 0.451, 0.086, 1.0 })
-#define ORANGE_600 ((rgba){ 0.918, 0.345, 0.047, 1.0 })
-#define ORANGE_700 ((rgba){ 0.761, 0.255, 0.047, 1.0 })
-#define ORANGE_800 ((rgba){ 0.604, 0.204, 0.071, 1.0 })
-#define ORANGE_900 ((rgba){ 0.486, 0.176, 0.071, 1.0 })
-#define ORANGE_950 ((rgba){ 0.263, 0.078, 0.027, 1.0 })
-
-#define AMBER_50 ((rgba){ 1.000, 0.984, 0.922, 1.0 })
-#define AMBER_100 ((rgba){ 0.996, 0.953, 0.780, 1.0 })
-#define AMBER_200 ((rgba){ 0.992, 0.902, 0.541, 1.0 })
-#define AMBER_300 ((rgba){ 0.988, 0.827, 0.302, 1.0 })
-#define AMBER_400 ((rgba){ 0.984, 0.749, 0.141, 1.0 })
-#define AMBER_500 ((rgba){ 0.961, 0.620, 0.043, 1.0 })
-#define AMBER_600 ((rgba){ 0.851, 0.467, 0.024, 1.0 })
-#define AMBER_700 ((rgba){ 0.706, 0.325, 0.035, 1.0 })
-#define AMBER_800 ((rgba){ 0.573, 0.251, 0.055, 1.0 })
-#define AMBER_900 ((rgba){ 0.471, 0.208, 0.059, 1.0 })
-#define AMBER_950 ((rgba){ 0.271, 0.102, 0.012, 1.0 })
diff --git a/src/core/README.md b/src/core/README.md
deleted file mode 100644
index 19cc1d0..0000000
--- a/src/core/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Core
-
-Core engine facilities
diff --git a/src/core/animation.c b/src/core/animation.c
deleted file mode 100644
index e69de29..0000000
--- a/src/core/animation.c
+++ /dev/null
diff --git a/src/core/camera.c b/src/core/camera.c
deleted file mode 100644
index 77ddad6..0000000
--- a/src/core/camera.c
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "camera.h"
-
-#include "input.h"
-#include "keys.h"
-#include "maths.h"
-
-#define CAMERA_SPEED 0.2
-#define CAMERA_SENSITIVITY 0.5
-
-Camera Camera_Create(Vec3 pos, Vec3 front, Vec3 up, f32 fov) {
- Camera c = { .position = pos, .front = front, .up = up, .fov = fov };
- return c;
-}
-
-Mat4 Camera_ViewProj(Camera* c, f32 lens_height, f32 lens_width, Mat4* out_view, Mat4* out_proj) {
- Mat4 proj = mat4_perspective(c->fov, lens_width / lens_height, 0.1, 1000.0);
- Vec3 camera_direction = vec3_add(c->position, c->front);
- Mat4 view = mat4_look_at(c->position, camera_direction, c->up);
- if (out_view) {
- *out_view = view;
- }
- if (out_proj) {
- *out_proj = proj;
- }
- return mat4_mult(view, proj);
-}
-
-void FlyCamera_Update(Camera* camera) {
- static f32 yaw = 0.0;
- static f32 pitch = 0.0;
-
- // Keyboard
- f32 speed = CAMERA_SPEED;
- Vec3 horizontal = vec3_cross(camera->front, camera->up);
- if (key_is_pressed(KEYCODE_A) || key_is_pressed(KEYCODE_KEY_LEFT)) {
- Vec3 displacement = vec3_mult(horizontal, -speed);
- camera->position = vec3_add(camera->position, displacement);
- }
- if (key_is_pressed(KEYCODE_D) || key_is_pressed(KEYCODE_KEY_RIGHT)) {
- Vec3 displacement = vec3_mult(horizontal, speed);
- camera->position = vec3_add(camera->position, displacement);
- }
- if (key_is_pressed(KEYCODE_W) || key_is_pressed(KEYCODE_KEY_UP)) {
- Vec3 displacement = vec3_mult(camera->front, speed);
- camera->position = vec3_add(camera->position, displacement);
- }
- if (key_is_pressed(KEYCODE_S) || key_is_pressed(KEYCODE_KEY_DOWN)) {
- Vec3 displacement = vec3_mult(camera->front, -speed);
- camera->position = vec3_add(camera->position, displacement);
- }
- if (key_is_pressed(KEYCODE_Q)) {
- Vec3 displacement = vec3_mult(camera->up, speed);
- camera->position = vec3_add(camera->position, displacement);
- }
- if (key_is_pressed(KEYCODE_E)) {
- Vec3 displacement = vec3_mult(camera->up, -speed);
- camera->position = vec3_add(camera->position, displacement);
- }
-
- // Mouse
- if (MouseBtn_Held(MOUSEBTN_LEFT)) {
- mouse_state mouse = Input_GetMouseState();
- // printf("Delta x: %d Delta y %d\n",mouse.x_delta, mouse.y_delta );
-
- f32 x_offset = mouse.x_delta;
- f32 y_offset = -mouse.y_delta;
-
- f32 sensitivity = CAMERA_SENSITIVITY; // change this value to your liking
- x_offset *= sensitivity;
- y_offset *= sensitivity;
-
- yaw += x_offset;
- pitch += y_offset;
-
- // make sure that when pitch is out of bounds, screen doesn't get flipped
- if (pitch > 89.0f) pitch = 89.0f;
- if (pitch < -89.0f) pitch = -89.0f;
-
- Vec3 front;
- front.x = cos(deg_to_rad(yaw) * cos(deg_to_rad(pitch)));
- front.y = sin(deg_to_rad(pitch));
- front.z = sin(deg_to_rad(yaw)) * cos(deg_to_rad(pitch));
- front = vec3_normalise(front);
- camera->front.x = front.x;
- camera->front.y = front.y;
- camera->front.z = front.z;
- }
-
- // TODO: Right mouse => pan in screen space
-}
diff --git a/src/core/camera.h b/src/core/camera.h
deleted file mode 100644
index 4300f87..0000000
--- a/src/core/camera.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include "defines.h"
-#include "maths_types.h"
-
-// TODO: swap to position + quaternion
-
-typedef struct Camera {
- Vec3 position;
- Vec3 front;
- Vec3 up;
- f32 fov;
-} Camera;
-
-/** @brief create a camera */
-PUB Camera Camera_Create(Vec3 pos, Vec3 front, Vec3 up, f32 fov);
-
-/**
- * @brief Get 3D camera transform matrix
- * @param out_view optionally stores just the view matrix
- * @param out_proj optionally stores just the projection matrix
- * @returns the camera's view projection matrix pre-multiplied
- */
-PUB Mat4 Camera_ViewProj(Camera* c, f32 lens_height, f32 lens_width, Mat4* out_view,
- Mat4* out_proj);
-
-/** @brief Get 2D camera transform matrix */
-PUB Mat4 Camera_View2D(Camera* c); // TODO: 2D cameras
-
-struct Input_State;
-
-PUB void FlyCamera_Update(Camera* camera);
-
-// TODO: (HIGH) Basic reusable camera controls
-/*
-Right click + move = pan
-Left click = orbit camera
-WASD = forward/backward/left/right
-*/
diff --git a/src/core/core.c b/src/core/core.c
deleted file mode 100644
index 64f59f3..0000000
--- a/src/core/core.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "core.h"
-
-#include <stdlib.h>
-
-#include "glfw3.h"
-#include "input.h"
-#include "keys.h"
-#include "log.h"
-#include "mem.h"
-#include "render.h"
-#include "render_types.h"
-
-// These are only the initial window dimensions
-#define SCR_WIDTH 1000
-#define SCR_HEIGHT 1000
-
-Core g_core; /** @brief global `Core` that other files can use */
-
-/** @brief Gets the global `Core` singleton */
-inline Core* GetCore() { return &g_core; }
-
-void Core_Bringup(const char* window_name, struct GLFWwindow* optional_window) {
- INFO("Initiate Core bringup");
- memset(&g_core, 0, sizeof(Core));
-
- RendererConfig conf = { .window_name = window_name,
- .scr_width = SCR_WIDTH,
- .scr_height = SCR_HEIGHT,
- .clear_colour = (Vec3){ .08, .08, .1 } };
-
- g_core.renderer = malloc(Renderer_GetMemReqs());
-
- // Initialise all subsystems
-
- // renderer config, renderer ptr, ptr to store a window, and optional preexisting glfw window
- if (!Renderer_Init(conf, g_core.renderer, &g_core.window, optional_window)) {
- // FATAL("Failed to start renderer");
- ERROR_EXIT("Failed to start renderer\n");
- }
- if (optional_window != NULL) {
- g_core.window = optional_window;
- }
-
- if (!Input_Init(&g_core.input, g_core.window)) {
- // the input system needs the glfw window which is created by the renderer
- // hence the order here is important
- ERROR_EXIT("Failed to start input system\n");
- }
-
- 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));
- g_core.models = model_pool;
- INFO("Created model pool allocator");
-}
-
-void Core_Shutdown() {
- Input_Shutdown(&g_core.input);
- Renderer_Shutdown(g_core.renderer);
- free(g_core.renderer);
-}
-
-bool ShouldExit() {
- return key_just_released(KEYCODE_ESCAPE) || glfwWindowShouldClose(g_core.window);
-}
-
-void Frame_Begin() {
- Input_Update(&g_core.input);
- Render_FrameBegin(g_core.renderer);
-}
-void Frame_Draw() {}
-void Frame_End() { Render_FrameEnd(g_core.renderer); }
-
-Core* get_global_core() { return &g_core; }
-
-GLFWwindow* Core_GetGlfwWindowPtr(Core* core) { return g_core.window; }
-
-struct Renderer* Core_GetRenderer(Core* core) { return core->renderer; }
-
-Model* Model_Get(ModelHandle h) { return Model_pool_get(&g_core.models, h); }
diff --git a/src/core/core.h b/src/core/core.h
deleted file mode 100644
index 14ba65d..0000000
--- a/src/core/core.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-
-#include "input.h"
-#include "mem.h"
-#include "render_types.h"
-#include "screenspace.h"
-#include "terrain.h"
-#include "text.h"
-
-TYPED_POOL(Model, Model)
-#define MODEL_GET(h) (Model_pool_get(&g_core.models, h))
-Model* Model_Get(ModelHandle h);
-
-typedef struct GLFWwindow GLFWwindow;
-
-typedef struct Core {
- const char* app_name;
- GLFWwindow* window;
- Renderer* renderer;
- Input_State input;
- // Model_pool models;
-} Core;
-extern Core g_core;
-
-struct Renderer;
-
-Core* get_global_core();
-
-/**
- @brief Throws error if the core cannot be instantiated
- @param [in] optional_window - Leave NULL if you want Celeritas to instantiate its own window with
- GLFW, if you want to provide the glfw window then pass it in here.
-*/
-void Core_Bringup(const char* window_name, GLFWwindow* optional_window);
-void Core_Shutdown();
-bool ShouldExit();
-
-GLFWwindow* Core_GetGlfwWindowPtr(Core* core);
-struct Renderer* Core_GetRenderer(Core* core);
-
-void Frame_Begin();
-void Frame_Draw();
-void Frame_End();
diff --git a/src/core/input.c b/src/core/input.c
deleted file mode 100644
index e69de29..0000000
--- a/src/core/input.c
+++ /dev/null
diff --git a/src/core/triggers.h b/src/core/triggers.h
deleted file mode 100644
index a823890..0000000
--- a/src/core/triggers.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-#include "defines.h"
-
-// Events/signals that get triggered by certain things that happen
-
-/*
-e.g.
-collider enters volume (collider)
-collider exits volume (collider)
-
-you could create a custom signal that only triggers when a collider has been inside a volume for 3
-seconds listen for Enter, start timer, if hits 3 -> emit signal. Else, reset state
-
-Top-level triggers:
-level loaded
-
-*/ \ No newline at end of file
diff --git a/src/core/vfs.h b/src/core/vfs.h
deleted file mode 100644
index 41033f5..0000000
--- a/src/core/vfs.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-#include "defines.h"
-
-#define MAX_VIRTUAL_FILENAME_LEN 256
-
-typedef struct VFS_Pack VFS_Pack;
-
-const char VFS_OpenErr_DoesNotExist[] = "PATH DOES NOT EXIST";
-
-typedef struct VFS_File {
- size_t n_bytes;
- void* data;
-} VFS_File;
-
-// virtual file open result
-typedef struct VFS_FileRes {
- bool success;
- const char* error_reason;
- VFS_File file;
-} VFS_FileRes;
-
-VFS_Pack* VFS_Open(const char* filepath);
-
-bool VFS_Close(VFS_Pack*);
-
-VFS_FileRes VFS_VirtualRead(VFS_Pack* vfs, const char* unique_path);
-
-typedef struct VFS_PackBuilder {
- const char* pack_filename;
-} VFS_PackBuilder;
-
-typedef struct VFS_FileEntry {
- char filename[MAX_VIRTUAL_FILENAME_LEN];
- size_t offset;
- size_t size;
-} VFS_FileEntry;
-
-VFS_PackBuilder VFS_Pack_Create(); \ No newline at end of file
diff --git a/src/empty.c b/src/empty.c
deleted file mode 100644
index b40cc85..0000000
--- a/src/empty.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// For some reason on Mac we need an empty file so that 'ar' has something
-// to run.
-int add(int a, int b) { return a + b; } \ No newline at end of file
diff --git a/src/log.c b/src/log.c
deleted file mode 100644
index 8bb7a65..0000000
--- a/src/log.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "log.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "defines.h"
-
-// Regular text
-#define BLK "\e[0;30m"
-#define RED "\e[0;31m"
-#define GRN "\e[0;32m"
-#define YEL "\e[0;33m"
-#define BLU "\e[0;34m"
-#define MAG "\e[0;35m"
-#define CYN "\e[0;36m"
-#define WHT "\e[0;37m"
-#define CRESET "\e[0m"
-
-static const char* level_strings[6] = { "[FATAL]: ", "[ERROR]: ", "[WARN]: ",
- "[INFO]: ", "[DEBUG]: ", "[TRACE]: " };
-static const char* level_colours[6] = { RED, RED, YEL, BLU, CYN, MAG };
-
-bool logger_init() {
- // TODO: create log file
- return true;
-}
-
-void logger_shutdown() {
- // does nothing right now
-}
-
-void log_output(log_level level, const char* message, ...) {
- char out_message[32000];
- memset(out_message, 0, sizeof(out_message));
-
- // format original message
- __builtin_va_list arg_ptr;
- va_start(arg_ptr, message);
- vsnprintf(out_message, 32000, message, arg_ptr);
- va_end(arg_ptr);
-
- char out_message2[32006];
- // prepend log level string
- sprintf(out_message2, "%s%s%s%s\n", level_colours[level], level_strings[level], out_message,
- CRESET);
-
- // print message to console
- printf("%s", out_message2);
-}
-
-void report_assertion_failure(const char* expression, const char* message, const char* file,
- int line) {
- log_output(LOG_LEVEL_FATAL, "Assertion failure: %s, message: '%s', in file: %s, on line %d\n",
- expression, message, file, line);
-}
diff --git a/src/log.h b/src/log.h
deleted file mode 100644
index 537cb6e..0000000
--- a/src/log.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma once
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define ERROR_EXIT(...) \
- { \
- fprintf(stderr, __VA_ARGS__); \
- exit(1); \
- }
-
-#define TODO(msg) \
- do { \
- ERROR_EXIT("TODO: %s", msg); \
- } while (0)
-
-#define LOG_WARN_ENABLED 1
-#define LOG_INFO_ENABLED 1
-
-#ifdef CRELEASE
-#define LOG_DEBUG_ENABLED 0
-#define LOG_TRACE_ENABLED 0
-#else
-#define LOG_DEBUG_ENABLED 1
-#define LOG_TRACE_ENABLED 1
-#endif
-
-typedef enum log_level {
- LOG_LEVEL_FATAL = 0,
- LOG_LEVEL_ERROR = 1,
- LOG_LEVEL_WARN = 2,
- LOG_LEVEL_INFO = 3,
- LOG_LEVEL_DEBUG = 4,
- LOG_LEVEL_TRACE = 5,
-} log_level;
-
-bool logger_init();
-void logger_shutdown();
-
-// TODO: macro that outputs logger macros for a specific subsystem or string prefix e.g. "MEMORY" ->
-// logs now have more context potentially have line numbers too?
-
-void log_output(log_level level, const char* message, ...);
-
-#define FATAL(message, ...) log_output(LOG_LEVEL_FATAL, message, ##__VA_ARGS__)
-#define ERROR(message, ...) log_output(LOG_LEVEL_ERROR, message, ##__VA_ARGS__)
-#define WARN(message, ...) log_output(LOG_LEVEL_WARN, message, ##__VA_ARGS__)
-#define INFO(message, ...) log_output(LOG_LEVEL_INFO, message, ##__VA_ARGS__)
-
-#if LOG_DEBUG_ENABLED == 1
-#define DEBUG(message, ...) log_output(LOG_LEVEL_DEBUG, message, ##__VA_ARGS__)
-#else
-#define DEBUG(message, ...)
-#endif
-
-#if LOG_TRACE_ENABLED == 1
-#define TRACE(message, ...) log_output(LOG_LEVEL_TRACE, message, ##__VA_ARGS__)
-#else
-#define TRACE(message, ...)
-#endif
-
-// TODO: Move this to an asserts file
-
-void report_assertion_failure(const char* expression, const char* message, const char* file,
- int line);
-
-#define CASSERT(expr) \
- { \
- if (expr) { \
- } else { \
- report_assertion_failure(#expr, "", __FILE__, __LINE__); \
- __builtin_trap(); \
- } \
- }
-
-#define CASSERT_MSG(expr, msg) \
- { \
- if (expr) { \
- } else { \
- report_assertion_failure(#expr, msg, __FILE__, __LINE__); \
- __builtin_trap(); \
- } \
- } \ No newline at end of file
diff --git a/src/logos/README.md b/src/logos/README.md
deleted file mode 100644
index 25b7bef..0000000
--- a/src/logos/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Logos
-
-Logos is the namespace for threadpool & job system code. This is not a 'system' as it is underlying core unit of the engine.
-
-Threadpool currently gets initialised at core bringup with a set number of threads and results are processed once per frame
-on the main thread. This is subject to change but multithreading is not the highest priority right now. \ No newline at end of file
diff --git a/src/logos/tasks.h b/src/logos/tasks.h
deleted file mode 100644
index 2e3dc53..0000000
--- a/src/logos/tasks.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Common jobs that get run
- */
-#pragma once
-#include "defines.h"
-#include "logos/threadpool.h"
-#include "render_types.h"
-#include "str.h"
-
-typedef enum TaskLifetime {
- /** ephemeral tasks must be finished by the end of the frame and thus we use a leak and clear
- allocation strategy */
- TASK_EPHEMERAL,
- /** multi-frame tasks have a more complex lifetime and must be cleaned up by the caller or in a
- separate cleanup callback */
- TASK_MULTIFRAME,
- TASK_COUNT
-} TaskLifetime;
-
-typedef enum TaskKind {
- TASK_RENDER,
- TASK_PHYSICS,
- TASK_GAMEPLAY,
- TASK_ASSET,
- TASK_USERLAND,
- TASKKIND_COUNT
-} TaskKind;
-
-typedef struct Task {
- char* debug_name;
- void* params;
- bool is_done;
-} Task;
-
-// Macro : give Params and Result structs and it creates a function that knows
-// correct sizes
-
-typedef struct Task_ModelLoad_Params {
- Str8 filepath; // filepath to the model on disk
-} Task_ModelLoad_Params;
-typedef struct Task_ModelLoad_Result {
- Model model;
-} Task_ModelLoad_Result;
-
-// Internally it will allocate data for each
-
-static bool Task_ModelLoad_Typed(Task_ModelLoad_Params* params, Task_ModelLoad_Result* result,
- tpool_task_start run_task, tpool_task_on_complete on_success,
- tpool_task_on_complete on_failure) {
- threadpool_add_task(pool, , tpool_task_on_complete on_success, tpool_task_on_complete on_fail,
- bool buffer_result_for_main_thread, void* param_data, u32 param_data_size,
- u32 result_data_size)
-}
-
-// do task
-// success
-void model_load_success(task_globals* globals, void* result) {
- Task_ModelLoad_Result* load_res = result;
-
- // push into render -> renderables ?
-}
-// fail
-
-// we can define our custom task here that wraps the more verbose function pointers
-static Task Task_ModelLoad(Task_ModelLoad_Params* params, Task_ModelLoad_Result* result) {
- Task task;
- task.debug_name = "Load Model";
- task.params = params;
-
- Task_ModelLoad_Typed(params, result, tpool_task_start run_task, tpool_task_on_complete on_success,
- tpool_task_on_complete on_failure)
-
- return task;
-}
diff --git a/src/logos/threadpool.c b/src/logos/threadpool.c
deleted file mode 100644
index 0e82d98..0000000
--- a/src/logos/threadpool.c
+++ /dev/null
@@ -1,141 +0,0 @@
-#include "threadpool.h"
-
-#include <pthread.h>
-
-#include "defines.h"
-#include "log.h"
-#include "ring_queue.h"
-
-static void* worker_factory(void* arg) {
- threadpool_worker* worker = arg;
- // INFO("Starting job thread %d", worker->id);
-
- // Run forever, waiting for jobs.
- while (true) {
- pthread_mutex_lock(&worker->pool->mutex);
- pthread_cond_wait(&worker->pool->has_tasks, &worker->pool->mutex); // wait for work to be ready
-
- task t;
- if (ring_queue_dequeue(worker->pool->task_queue, &t)) {
- DEBUG("Job thread %d picked up task %d", worker->id, t.task_id);
- } else {
- WARN("Job thread %d didnt pick up a task as queue was empty", worker->id);
- pthread_mutex_unlock(&worker->pool->mutex);
- break;
- }
-
- pthread_mutex_unlock(&worker->pool->mutex);
-
- // Do the work
- bool result = t.do_task(t.params, t.result_data);
-
- // INFO("Task result was %s", result ? "success" : "failure");
- if (result) {
- pthread_mutex_lock(&worker->pool->mutex);
- if (t.buffer_result_for_main_thread) {
- deferred_task_result dtr = { .task_id = t.task_id,
- .callback = t.on_success,
- .result_data = t.result_data,
- .result_data_size = t.result_data_size };
- deferred_task_result_darray_push(worker->pool->results, dtr);
- } else {
- // call on complete from here.
- }
- } else {
- // TODO
- }
- pthread_mutex_unlock(&worker->pool->mutex);
- }
-
- return NULL;
-}
-
-bool threadpool_create(threadpool* pool, u8 thread_count, u32 queue_size) {
- INFO("Threadpool init");
- pool->next_task_id = 0;
- pool->context = NULL;
-
- u8 num_worker_threads = thread_count;
- if (thread_count > MAX_NUM_THREADS) {
- ERROR_EXIT("Threadpool has a hard limit of %d threads, you tried to start one with %d",
- MAX_NUM_THREADS, thread_count)
- num_worker_threads = MAX_NUM_THREADS;
- }
-
- DEBUG("creating task queue with max length %d", queue_size);
- pool->task_queue = ring_queue_new(sizeof(task), queue_size, NULL);
-
- DEBUG("creating mutex and condition");
- pthread_mutex_init(&pool->mutex, NULL);
- pthread_cond_init(&pool->has_tasks, NULL);
-
- pool->results = deferred_task_result_darray_new(256);
-
- DEBUG("Spawning %d threads for the threadpool", thread_count);
- for (u8 i = 0; i < num_worker_threads; i++) {
- pool->workers[i].id = i;
- pool->workers[i].pool = pool;
- if (pthread_create(&pool->workers[i].thread, NULL, worker_factory, &pool->workers[i]) != 0) {
- FATAL("OS error creating job thread");
- return false;
- };
- }
-
- return true;
-}
-
-bool threadpool_add_task(threadpool* pool, tpool_task_start do_task,
- tpool_task_on_complete on_success, tpool_task_on_complete on_fail,
- bool buffer_result_for_main_thread, void* param_data, u32 param_data_size,
- u32 result_data_size) {
- void* result_data = malloc(result_data_size);
-
- task* work_task = malloc(sizeof(task));
- work_task->task_id = 0;
- work_task->do_task = do_task;
- work_task->on_success = on_success;
- work_task->on_failure = on_fail;
- work_task->buffer_result_for_main_thread = buffer_result_for_main_thread;
- work_task->param_size = param_data_size;
- work_task->params = param_data;
- work_task->result_data_size = result_data_size;
- work_task->result_data = result_data;
-
- // START critical section
- if (pthread_mutex_lock(&pool->mutex) != 0) {
- ERROR("Unable to get threadpool lock.");
- return false;
- }
-
- work_task->task_id = pool->next_task_id;
- pool->next_task_id++;
-
- ring_queue_enqueue(pool->task_queue, work_task);
- DEBUG("Enqueued job");
- pthread_cond_broadcast(&pool->has_tasks);
-
- if (pthread_mutex_unlock(&pool->mutex) != 0) {
- ERROR("couldnt unlock threadpool after adding task.");
- return false; // ?
- }
- // END critical section
-
- return true;
-}
-
-void threadpool_process_results(threadpool* pool, int _num_to_process) {
- pthread_mutex_lock(&pool->mutex);
- size_t num_results = deferred_task_result_darray_len(pool->results);
- if (num_results > 0) {
- u32 _size = ((deferred_task_result*)pool->results->data)[num_results].result_data_size;
- deferred_task_result res;
- deferred_task_result_darray_pop(pool->results, &res);
- pthread_mutex_unlock(&pool->mutex);
- task_globals globals = { .pool = pool, .ctx = pool->context };
- res.callback(&globals, res.result_data);
- } else {
- pthread_mutex_unlock(&pool->mutex);
- }
-}
-
-void threadpool_set_ctx(threadpool* pool, void* ctx) { pool->context = ctx; } \ No newline at end of file
diff --git a/src/logos/threadpool.h b/src/logos/threadpool.h
deleted file mode 100644
index 6390a38..0000000
--- a/src/logos/threadpool.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- A Threadpool has a number of "workers", each which process "tasks"
-*/
-#pragma once
-
-#include <pthread.h>
-
-#include "darray.h"
-#include "defines.h"
-#include "ring_queue.h"
-
-#define MAX_NUM_THREADS 16
-
-struct threadpool;
-typedef struct threadpool threadpool;
-
-typedef struct task_globals {
- threadpool* pool;
- void* ctx;
-} task_globals;
-
-/* function pointer */
-typedef bool (*tpool_task_start)(void*, void*);
-
-/* function pointer */
-typedef void (*tpool_task_on_complete)(task_globals*, void*);
-
-typedef struct threadpool_worker {
- u16 id;
- pthread_t thread;
- threadpool* pool; // pointer back to the pool so we can get the mutex and cond
-} threadpool_worker;
-
-typedef enum tpool_task_status {
- TASK_STATUS_READY,
-} task_status;
-
-typedef struct tpool_task {
- u64 task_id;
- tpool_task_start do_task;
- tpool_task_on_complete on_success;
- tpool_task_on_complete on_failure;
- bool buffer_result_for_main_thread;
- /** @brief a pointer to the parameters data that will be passed into the task. */
- void* params;
- u32 param_size;
- void* result_data;
- u32 result_data_size;
-} task;
-
-typedef struct deferred_task_result {
- u64 task_id;
- tpool_task_on_complete callback;
- u32 result_data_size;
- // this gets passed to the void* argument of `tpool_task_on_complete`
- void* result_data;
-} deferred_task_result;
-
-#ifndef TYPED_TASK_RESULT_ARRAY
-KITC_DECL_TYPED_ARRAY(deferred_task_result) // creates "deferred_task_result_darray"
-#define TYPED_TASK_RESULT_ARRAY
-#endif
-
-struct threadpool {
- ring_queue* task_queue;
- pthread_mutex_t mutex;
- pthread_cond_t has_tasks;
- threadpool_worker workers[MAX_NUM_THREADS];
- deferred_task_result_darray* results;
- u64 next_task_id;
-
- void* context;
-};
-
-/**
- * @param pool where to store the created threadpool
- * @param thread_count how many threads to spawn
- * @param queue_size max size of task queue
- */
-bool threadpool_create(threadpool* pool, u8 thread_count, u32 queue_size);
-void threadpool_destroy(threadpool* pool);
-
-/** @brief set a context variable for the threadpool that task data has access to */
-void threadpool_set_ctx(threadpool* pool, void* ctx);
-
-/**
- * @brief Add a task to the threadpool
- */
-bool threadpool_add_task(threadpool* pool, tpool_task_start do_task,
- tpool_task_on_complete on_success, tpool_task_on_complete on_fail,
- bool buffer_result_for_main_thread, void* param_data, u32 param_data_size,
- u32 result_data_size);
-
-void threadpool_process_results(threadpool* pool, int num_to_process);
-
-u32 Tpool_GetNumWorkers(); // how many threads are we using \ No newline at end of file
diff --git a/src/maths/geometry.h b/src/maths/geometry.h
deleted file mode 100644
index 532651c..0000000
--- a/src/maths/geometry.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file geometry.h
- * @author your name (you@domain.com)
- * @brief Shapes and intersections between them
- * @version 0.1
- * @date 2024-02-24
- *
- * @copyright Copyright (c) 2024
- */
-#pragma once
-
-#include "maths.h"
-
-// typedef struct line_3d {
-// vec3 start, end;
-// } line_3d;
-
-// typedef struct plane {
-// vec3 normal;
-// } plane;
-
-typedef struct Cuboid {
- Vec3 half_extents;
-} Cuboid;
-
-typedef struct Sphere {
- f32 radius;
-} Sphere;
-
-// typedef struct cylinder {
-// f32 radius;
-// f32 half_height;
-// } cylinder;
-
-// typedef struct cone {
-// f32 radius;
-// f32 half_height;
-// } cone;
-
-// TODO:
-// capsule
-// torus
-// ray
-// frustum
-// conical frustum
-// wedge
-
-// 2d...
-// line
-// circle
diff --git a/src/maths/maths.c b/src/maths/maths.c
deleted file mode 100644
index 19052fe..0000000
--- a/src/maths/maths.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "maths.h"
-
-#define c_static_inline
-
-c_static_inline Vec3 vec3_create(f32 x, f32 y, f32 z) { return (Vec3){ x, y, z }; }
-c_static_inline Vec3 vec3_add(Vec3 a, Vec3 b) { return (Vec3){ a.x + b.x, a.y + b.y, a.z + b.z }; }
-c_static_inline Vec3 vec3_sub(Vec3 a, Vec3 b) { return (Vec3){ a.x - b.x, a.y - b.y, a.z - b.z }; }
-c_static_inline Vec3 vec3_mult(Vec3 a, f32 s) { return (Vec3){ a.x * s, a.y * s, a.z * s }; }
-c_static_inline Vec3 vec3_div(Vec3 a, f32 s) { return (Vec3){ a.x / s, a.y / s, a.z / s }; }
-
-c_static_inline f32 vec3_len_squared(Vec3 a) { return (a.x * a.x) + (a.y * a.y) + (a.z * a.z); }
-c_static_inline f32 vec3_len(Vec3 a) { return sqrtf(vec3_len_squared(a)); }
-c_static_inline Vec3 vec3_negate(Vec3 a) { return (Vec3){ -a.x, -a.y, -a.z }; }
-PUB c_static_inline Vec3 vec3_normalise(Vec3 a) {
- f32 length = vec3_len(a);
- return vec3_div(a, length);
-}
-
-c_static_inline f32 vec3_dot(Vec3 a, Vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
-c_static_inline Vec3 vec3_cross(Vec3 a, Vec3 b) {
- return (
- Vec3){ .x = a.y * b.z - a.z * b.y, .y = a.z * b.x - a.x * b.z, .z = a.x * b.y - a.y * b.x };
-}
-
-Mat4 mat4_ident() {
- return (Mat4){ .data = { 1.0, 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.0 } };
-}
-
-Mat4 transform_to_mat(Transform* tf) {
- Mat4 scale = mat4_scale(tf->scale);
- Mat4 rotation = mat4_rotation(tf->rotation);
- Mat4 translation = mat4_translation(tf->position);
- // return mat4_mult(translation, mat4_mult(rotation, scale));
- return mat4_mult(mat4_mult(scale, rotation), translation);
-} \ No newline at end of file
diff --git a/src/maths/maths.h b/src/maths/maths.h
deleted file mode 100644
index e77b81a..0000000
--- a/src/maths/maths.h
+++ /dev/null
@@ -1,321 +0,0 @@
-/**
- * @file maths.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-02-24
- * @copyright Copyright (c) 2024
- */
-#pragma once
-
-#include <math.h>
-#include <stdio.h>
-#include "defines.h"
-#include "maths_types.h"
-
-// #undef c_static_inline
-// #define c_static_inline static
-
-// --- Helpers
-#define deg_to_rad(x) (x * 3.14 / 180.0)
-#define MIN(a, b) (a < b ? a : b)
-#define MAX(a, b) (a > b ? a : b)
-
-// --- Vector Implementations
-
-// Dimension 3
-PUB c_static_inline Vec3 vec3_create(f32 x, f32 y, f32 z);
-#define vec3(x, y, z) ((Vec3){ x, y, z })
-PUB c_static_inline Vec3 vec3_add(Vec3 a, Vec3 b);
-PUB c_static_inline Vec3 vec3_sub(Vec3 a, Vec3 b);
-PUB c_static_inline Vec3 vec3_mult(Vec3 a, f32 s);
-PUB c_static_inline Vec3 vec3_div(Vec3 a, f32 s);
-
-PUB c_static_inline f32 vec3_len_squared(Vec3 a);
-PUB c_static_inline f32 vec3_len(Vec3 a);
-PUB c_static_inline Vec3 vec3_negate(Vec3 a);
-PUB c_static_inline Vec3 vec3_normalise(Vec3 a);
-
-PUB c_static_inline f32 vec3_dot(Vec3 a, Vec3 b);
-PUB c_static_inline Vec3 vec3_cross(Vec3 a, Vec3 b);
-
-static const Vec3 VEC3_X = vec3(1.0, 0.0, 0.0);
-static const Vec3 VEC3_NEG_X = vec3(-1.0, 0.0, 0.0);
-static const Vec3 VEC3_Y = vec3(0.0, 1.0, 0.0);
-static const Vec3 VEC3_NEG_Y = vec3(0.0, -1.0, 0.0);
-static const Vec3 VEC3_Z = vec3(0.0, 0.0, 1.0);
-static const Vec3 VEC3_NEG_Z = vec3(0.0, 0.0, -1.0);
-static const Vec3 VEC3_ZERO = vec3(0.0, 0.0, 0.0);
-static const Vec3 VEC3_ONES = vec3(1.0, 1.0, 1.0);
-
-static void print_vec3(Vec3 v) {
- printf("{ x: %f, y: %f, z: %f )\n", (f64)v.x, (f64)v.y, (f64)v.z);
-}
-
-// TODO: Dimension 2
-static Vec2 vec2_create(f32 x, f32 y) { return (Vec2){ x, y }; }
-#define vec2(x, y) ((Vec2){ x, y })
-static Vec2 vec2_div(Vec2 a, f32 s) { return (Vec2){ a.x / s, a.y / s }; }
-
-// TODO: Dimension 4
-static Vec4 vec4_create(f32 x, f32 y, f32 z, f32 w) { return (Vec4){ x, y, z, w }; }
-#define vec4(x, y, z, w) (vec4_create(x, y, z, w))
-#define VEC4_ZERO ((Vec4){ .x = 0.0, .y = 0.0, .z = 0.0, .w = 0.0 })
-
-// --- Quaternion Implementations
-
-static f32 quat_dot(Quat a, Quat b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; }
-
-static Quat quat_normalise(Quat a) {
- f32 length = sqrtf(quat_dot(a, a)); // same as len squared
-
- return (Quat){ a.x / length, a.y / length, a.z / length, a.w / length };
-}
-
-static Quat quat_ident() { return (Quat){ .x = 0.0, .y = 0.0, .z = 0.0, .w = 1.0 }; }
-
-static Quat quat_from_axis_angle(Vec3 axis, f32 angle, bool normalize) {
- const f32 half_angle = 0.5f * angle;
- f32 s = sinf(half_angle);
- f32 c = cosf(half_angle);
-
- Quat q = (Quat){ s * axis.x, s * axis.y, s * axis.z, c };
- if (normalize) {
- return quat_normalise(q);
- }
- return q;
-}
-
-// TODO: grok this.
-static Quat quat_slerp(Quat a, Quat b, f32 percentage) {
- Quat out_quaternion;
-
- Quat q0 = quat_normalise(a);
- Quat q1 = quat_normalise(b);
-
- // Compute the cosine of the angle between the two vectors.
- f32 dot = quat_dot(q0, q1);
-
- // If the dot product is negative, slerp won't take
- // the shorter path. Note that v1 and -v1 are equivalent when
- // the negation is applied to all four components. Fix by
- // reversing one quaternion.
- if (dot < 0.0f) {
- q1.x = -q1.x;
- q1.y = -q1.y;
- q1.z = -q1.z;
- q1.w = -q1.w;
- dot = -dot;
- }
-
- const f32 DOT_THRESHOLD = 0.9995f;
- if (dot > DOT_THRESHOLD) {
- // If the inputs are too close for comfort, linearly interpolate
- // and normalize the result.
- out_quaternion =
- (Quat){ q0.x + ((q1.x - q0.x) * percentage), q0.y + ((q1.y - q0.y) * percentage),
- q0.z + ((q1.z - q0.z) * percentage), q0.w + ((q1.w - q0.w) * percentage) };
-
- return quat_normalise(out_quaternion);
- }
-
- // TODO: Are there math functions that take floats instead of doubles?
-
- // Since dot is in range [0, DOT_THRESHOLD], acos is safe
- f64 theta_0 = cos((f64)dot); // theta_0 = angle between input vectors
- f64 theta = theta_0 * (f64)percentage; // theta = angle between v0 and result
- f64 sin_theta = sin((f64)theta); // compute this value only once
- f64 sin_theta_0 = sin((f64)theta_0); // compute this value only once
-
- f32 s0 =
- cos(theta) - (f64)dot * sin_theta / sin_theta_0; // == sin(theta_0 - theta) / sin(theta_0)
- f32 s1 = sin_theta / sin_theta_0;
-
- return (Quat){ (q0.x * s0) + (q1.x * s1), (q0.y * s0) + (q1.y * s1), (q0.z * s0) + (q1.z * s1),
- (q0.w * s0) + (q1.w * s1) };
-}
-
-// --- Matrix Implementations
-
-Mat4 mat4_ident();
-
-static Mat4 mat4_translation(Vec3 position) {
- Mat4 out_matrix = mat4_ident();
- out_matrix.data[12] = position.x;
- out_matrix.data[13] = position.y;
- out_matrix.data[14] = position.z;
- return out_matrix;
-}
-
-static Mat4 mat4_scale(Vec3 scale) {
- Mat4 out_matrix = mat4_ident();
- out_matrix.data[0] = scale.x;
- out_matrix.data[5] = scale.y;
- out_matrix.data[10] = scale.z;
- return out_matrix;
-}
-
-// TODO: double check this
-static Mat4 mat4_rotation(Quat rotation) {
- Mat4 out_matrix = mat4_ident();
- Quat n = quat_normalise(rotation);
-
- out_matrix.data[0] = 1.0f - 2.0f * n.y * n.y - 2.0f * n.z * n.z;
- out_matrix.data[1] = 2.0f * n.x * n.y - 2.0f * n.z * n.w;
- out_matrix.data[2] = 2.0f * n.x * n.z + 2.0f * n.y * n.w;
-
- out_matrix.data[4] = 2.0f * n.x * n.y + 2.0f * n.z * n.w;
- out_matrix.data[5] = 1.0f - 2.0f * n.x * n.x - 2.0f * n.z * n.z;
- out_matrix.data[6] = 2.0f * n.y * n.z - 2.0f * n.x * n.w;
-
- out_matrix.data[8] = 2.0f * n.x * n.z - 2.0f * n.y * n.w;
- out_matrix.data[9] = 2.0f * n.y * n.z + 2.0f * n.x * n.w;
- out_matrix.data[10] = 1.0f - 2.0f * n.x * n.x - 2.0f * n.y * n.y;
-
- return out_matrix;
-}
-
-static Mat4 mat4_mult(Mat4 lhs, Mat4 rhs) {
- Mat4 out_matrix = mat4_ident();
-
- const f32* m1_ptr = lhs.data;
- const f32* m2_ptr = rhs.data;
- f32* dst_ptr = out_matrix.data;
-
- for (i32 i = 0; i < 4; ++i) {
- for (i32 j = 0; j < 4; ++j) {
- *dst_ptr = m1_ptr[0] * m2_ptr[0 + j] + m1_ptr[1] * m2_ptr[4 + j] + m1_ptr[2] * m2_ptr[8 + j] +
- m1_ptr[3] * m2_ptr[12 + j];
- dst_ptr++;
- }
- m1_ptr += 4;
- }
-
- return out_matrix;
-}
-
-static Mat4 mat4_transposed(Mat4 matrix) {
- Mat4 out_matrix = mat4_ident();
- out_matrix.data[0] = matrix.data[0];
- out_matrix.data[1] = matrix.data[4];
- out_matrix.data[2] = matrix.data[8];
- out_matrix.data[3] = matrix.data[12];
- out_matrix.data[4] = matrix.data[1];
- out_matrix.data[5] = matrix.data[5];
- out_matrix.data[6] = matrix.data[9];
- out_matrix.data[7] = matrix.data[13];
- out_matrix.data[8] = matrix.data[2];
- out_matrix.data[9] = matrix.data[6];
- out_matrix.data[10] = matrix.data[10];
- out_matrix.data[11] = matrix.data[14];
- out_matrix.data[12] = matrix.data[3];
- out_matrix.data[13] = matrix.data[7];
- out_matrix.data[14] = matrix.data[11];
- out_matrix.data[15] = matrix.data[15];
- return out_matrix;
-}
-
-#if defined(CEL_REND_BACKEND_VULKAN)
-/** @brief Creates a perspective projection matrix compatible with Vulkan */
-c_static_inline Mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip,
- f32 far_clip) {
- f32 half_tan_fov = tanf(fov_radians * 0.5f);
- Mat4 out_matrix = { .data = { 0 } };
-
- out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov);
- out_matrix.data[5] = -1.0f / half_tan_fov; // Flip Y-axis for Vulkan
- out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip));
- out_matrix.data[11] = -1.0f;
- out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip));
-
- return out_matrix;
-}
-#else
-/** @brief Creates a perspective projection matrix */
-static inline Mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip,
- f32 far_clip) {
- f32 half_tan_fov = tanf(fov_radians * 0.5f);
- Mat4 out_matrix = { .data = { 0 } };
- out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov);
- out_matrix.data[5] = 1.0f / half_tan_fov;
- out_matrix.data[10] = -((far_clip + near_clip) / (far_clip - near_clip));
- out_matrix.data[11] = -1.0f;
- out_matrix.data[14] = -((2.0f * far_clip * near_clip) / (far_clip - near_clip));
- return out_matrix;
-}
-#endif
-
-/** @brief Creates an orthographic projection matrix */
-static inline Mat4 mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 near_clip,
- f32 far_clip) {
- // source: kohi game engine.
- Mat4 out_matrix = mat4_ident();
-
- f32 lr = 1.0f / (left - right);
- f32 bt = 1.0f / (bottom - top);
- f32 nf = 1.0f / (near_clip - far_clip);
-
- out_matrix.data[0] = -2.0f * lr;
- out_matrix.data[5] = -2.0f * bt;
- out_matrix.data[10] = 2.0f * nf;
-
- out_matrix.data[12] = (left + right) * lr;
- out_matrix.data[13] = (top + bottom) * bt;
- out_matrix.data[14] = (far_clip + near_clip) * nf;
-
- return out_matrix;
-}
-
-static inline Mat4 mat4_look_at(Vec3 position, Vec3 target, Vec3 up) {
- Mat4 out_matrix;
- Vec3 z_axis;
- z_axis.x = target.x - position.x;
- z_axis.y = target.y - position.y;
- z_axis.z = target.z - position.z;
-
- z_axis = vec3_normalise(z_axis);
- Vec3 x_axis = vec3_normalise(vec3_cross(z_axis, up));
- Vec3 y_axis = vec3_cross(x_axis, z_axis);
-
- out_matrix.data[0] = x_axis.x;
- out_matrix.data[1] = y_axis.x;
- out_matrix.data[2] = -z_axis.x;
- out_matrix.data[3] = 0;
- out_matrix.data[4] = x_axis.y;
- out_matrix.data[5] = y_axis.y;
- out_matrix.data[6] = -z_axis.y;
- out_matrix.data[7] = 0;
- out_matrix.data[8] = x_axis.z;
- out_matrix.data[9] = y_axis.z;
- out_matrix.data[10] = -z_axis.z;
- out_matrix.data[11] = 0;
- out_matrix.data[12] = -vec3_dot(x_axis, position);
- out_matrix.data[13] = -vec3_dot(y_axis, position);
- out_matrix.data[14] = vec3_dot(z_axis, position);
- out_matrix.data[15] = 1.0f;
-
- return out_matrix;
-}
-
-// ...
-
-// --- Transform Implementations
-
-#define TRANSFORM_DEFAULT \
- ((Transform){ .position = VEC3_ZERO, \
- .rotation = (Quat){ .x = 0., .y = 0., .z = 0., .w = 1. }, \
- .scale = 1.0, \
- .is_dirty = false })
-
-static Transform transform_create(Vec3 pos, Quat rot, Vec3 scale) {
- return (Transform){ .position = pos, .rotation = rot, .scale = scale, .is_dirty = true };
-}
-
-Mat4 transform_to_mat(Transform* tf);
-
-// --- Sizing asserts
-
-_Static_assert(alignof(Vec3) == 4, "Vec3 is 4 byte aligned");
-_Static_assert(sizeof(Vec3) == 12, "Vec3 is 12 bytes so has no padding");
-
-_Static_assert(alignof(Vec4) == 4, "Vec4 is 4 byte aligned");
diff --git a/src/maths/maths_types.h b/src/maths/maths_types.h
deleted file mode 100644
index 66d260d..0000000
--- a/src/maths/maths_types.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file maths_types.h
- * @author Omniscient
- * @brief Maths types
- * @date 2024-02-24
- * @copyright Copyright (c) 2024
- */
-#pragma once
-
-#include "defines.h"
-
-// --- Constants
-#define PI 3.14159265358979323846
-#define HALF_PI 1.57079632679489661923
-#define TAU (2.0 * PI)
-
-// --- Types
-
-/** @brief 2D Vector */
-typedef struct Vec2 {
- f32 x, y;
-} Vec2;
-
-/** @brief 4x4 Matrix */
-typedef struct Mat4 {
- // TODO: use this format for more readable code: vec4 x_axis, y_axis, z_axis, w_axis;
- f32 data[16];
-} Mat4;
-
-/** @brief Three dimensional bounding box */
-typedef struct Bbox_3D {
- Vec3 min; // minimum point of the box
- Vec3 max; // maximum point of the box
-} Bbox_3D;
-
-/** @brief 3D Axis-aligned bounding box */
-typedef Bbox_3D Aabb_3D;
-
-/** @brief 3D affine transformation */
-typedef struct Transform {
- Vec3 position;
- Quat rotation;
- Vec3 scale;
- bool is_dirty;
-} Transform;
-
-typedef struct Vec4i {
- i32 x, y, z, w;
-} Vec4i;
-
-typedef struct Vec4u {
- u32 x, y, z, w;
-} Vec4u;
-
-// --- Some other types
-typedef struct u32x3 {
- union {
- struct {
- u32 x;
- u32 y;
- u32 z;
- };
- struct {
- u32 r;
- u32 g;
- u32 b;
- };
- };
-} u32x3;
-#define u32x3(x, y, z) ((u32x3){ x, y, z })
-
-typedef struct u32x2 {
- u32 x;
- u32 y;
-} u32x2;
-#define u32x2(x, y) ((u32x2){ x, y })
-
-// Type aliass
-
-typedef struct Vec2 f32x2;
-#define f32x2(x, y) ((f32x2){ x, y })
-
-typedef struct Vec3 f32x3;
-#define f32x3(x, y, z) ((f32x3){ x, y, z })
diff --git a/src/maths/primitives.c b/src/maths/primitives.c
deleted file mode 100644
index c24d1e2..0000000
--- a/src/maths/primitives.c
+++ /dev/null
@@ -1,343 +0,0 @@
-#include "primitives.h"
-#include "colours.h"
-#include "log.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "ral_types.h"
-#include "render_types.h"
-
-// --- Helpers
-
-void push_triangle(u32_darray* arr, u32 i0, u32 i1, u32 i2) {
- u32_darray_push(arr, i0);
- u32_darray_push(arr, i1);
- u32_darray_push(arr, i2);
-}
-
-Vec3 plane_vertex_positions[] = {
- (Vec3){ -0.5, 0, -0.5 },
- (Vec3){ 0.5, 0, -0.5 },
- (Vec3){ -0.5, 0, 0.5 },
- (Vec3){ 0.5, 0, 0.5 },
-};
-
-Geometry Geo_CreatePlane(f32x2 extents, u32 tiling_u, u32 tiling_v) {
- CASSERT(tiling_u >= 1 && tiling_v >= 1);
- Vertex_darray* vertices = Vertex_darray_new(4);
- u32_darray* indices = u32_darray_new(vertices->len);
-
- Vec3 vert_pos[4];
- memcpy(&vert_pos, plane_vertex_positions, sizeof(plane_vertex_positions));
- for (int i = 0; i < 4; i++) {
- vert_pos[i].x *= extents.x;
- vert_pos[i].z *= extents.y;
- }
- VERT_3D(vertices, vert_pos[0], VEC3_Y, vec2(0, 0)); // back left
- VERT_3D(vertices, vert_pos[1], VEC3_Y, vec2(1 * tiling_u, 0 * tiling_v)); // back right
- VERT_3D(vertices, vert_pos[2], VEC3_Y, vec2(0, 1 * tiling_v)); // front left
- VERT_3D(vertices, vert_pos[3], VEC3_Y, vec2(1 * tiling_u, 1 * tiling_v)); // front right
-
- // push_triangle(indices, 0, 1, 2);
- // push_triangle(indices, 2, 1, 3);
- push_triangle(indices, 2, 1, 0);
- push_triangle(indices, 1, 2, 3);
-
- for (int i = 0; i < 4; i++) {
- printf("Vertex %d: (%f, %f, %f)\n", i, vert_pos[i].x, vert_pos[i].y, vert_pos[i].z);
- }
-
- Geometry geo = { .format = VERTEX_STATIC_3D,
- .vertices = vertices,
- .has_indices = true,
- .index_count = indices->len,
- .indices = indices };
-
- return geo;
-}
-
-Geometry Geo_CreateCuboid(f32x3 extents) {
- Vertex_darray* vertices = Vertex_darray_new(36);
-
- // back faces
- VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_NEG_Z, vec2(1, 0));
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_Z, vec2(0, 1));
- VERT_3D(vertices, BACK_TOP_LEFT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_NEG_Z, vec2(1, 0));
- VERT_3D(vertices, BACK_BOT_RIGHT, VEC3_NEG_Z, vec2(1, 1));
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_Z, vec2(0, 1));
-
- // front faces
- VERT_3D(vertices, FRONT_BOT_LEFT, VEC3_Z, vec2(0, 1));
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_Z, vec2(1, 0));
- VERT_3D(vertices, FRONT_TOP_LEFT, VEC3_Z, vec2(0, 0));
- VERT_3D(vertices, FRONT_BOT_LEFT, VEC3_Z, vec2(0, 1));
- VERT_3D(vertices, FRONT_BOT_RIGHT, VEC3_Z, vec2(1, 1));
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_Z, vec2(1, 0));
-
- // top faces
- VERT_3D(vertices, BACK_TOP_LEFT, VEC3_Y, vec2(0, 0));
- VERT_3D(vertices, FRONT_TOP_LEFT, VEC3_Y, vec2(0, 1));
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_Y, vec2(1, 1));
- VERT_3D(vertices, BACK_TOP_LEFT, VEC3_Y, vec2(0, 0));
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_Y, vec2(1, 1));
- VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_Y, vec2(1, 0));
-
- // bottom faces
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_Y, vec2(0, 1));
- VERT_3D(vertices, FRONT_BOT_RIGHT, VEC3_NEG_Y, vec2(1, 1));
- VERT_3D(vertices, FRONT_BOT_LEFT, VEC3_NEG_Y, vec2(0, 1));
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_Y, vec2(0, 1));
- VERT_3D(vertices, BACK_BOT_RIGHT, VEC3_NEG_Y, vec2(1, 1));
- VERT_3D(vertices, FRONT_BOT_RIGHT, VEC3_NEG_Y, vec2(0, 1));
-
- // right faces
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_X, vec2(0, 0));
- VERT_3D(vertices, BACK_BOT_RIGHT, VEC3_X, vec2(1, 1));
- VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_X, vec2(1, 0));
- VERT_3D(vertices, BACK_BOT_RIGHT, VEC3_X, vec2(1, 1));
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_X, vec2(0, 0));
- VERT_3D(vertices, FRONT_BOT_RIGHT, VEC3_X, vec2(0, 1));
-
- // left faces
- VERT_3D(vertices, FRONT_TOP_LEFT, VEC3_NEG_X, vec2(0, 0));
- VERT_3D(vertices, BACK_TOP_LEFT, VEC3_NEG_X, vec2(0, 0));
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_X, vec2(0, 0));
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_X, vec2(0, 0));
- VERT_3D(vertices, FRONT_BOT_LEFT, VEC3_NEG_X, vec2(0, 0));
- VERT_3D(vertices, FRONT_TOP_LEFT, VEC3_NEG_X, vec2(0, 0));
-
- u32_darray* indices = u32_darray_new(vertices->len);
-
- for (u32 i = 0; i < vertices->len; i++) {
- u32_darray_push(indices, i);
- vertices->data[i].static_3d.position =
- vec3_sub(vertices->data[i].static_3d.position,
- vec3(0.5, 0.5, 0.5)); // make center of the cube is the origin of mesh space
- }
-
- Geometry geo = {
- .format = VERTEX_STATIC_3D,
- .vertices = vertices,
- .has_indices = true,
- .index_count = indices->len,
- .indices = indices, // FIXME: make darray methods that return stack allocated struct
- };
-
- return geo;
-}
-
-// --- Spheres
-
-Vec3 spherical_to_cartesian_coords(f32 rho, f32 theta, f32 phi) {
- f32 x = rho * sin(phi) * cos(theta);
- f32 y = rho * cos(phi);
- f32 z = rho * sin(phi) * sin(theta);
- return vec3(x, y, z);
-}
-
-Geometry Geo_CreateUVsphere(f32 radius, u32 north_south_lines, u32 east_west_lines) {
- assert(east_west_lines >= 3); // sphere will be degenerate and look gacked without at least 3
- assert(north_south_lines >= 3);
-
- Vertex_darray* vertices = Vertex_darray_new(2 + (east_west_lines - 1) * north_south_lines);
-
- // Create a UV sphere with spherical coordinates
- // a point P on the unit sphere can be represented P(r, theta, phi)
- // for each vertex we must convert that to a cartesian R3 coordinate
-
- // Top point
- Vertex top = { .static_3d = { .position = vec3(0, radius, 0),
- .normal = vec3_normalise(vec3(0, radius, 0)),
- .tex_coords = vec2(0, 0) } };
- Vertex_darray_push(vertices, top);
-
- // parallels
- for (u32 i = 0; i < (east_west_lines - 1); i++) {
- // phi should range from 0 to pi
- f32 phi = PI * (((f32)i + 1) / (f32)east_west_lines);
-
- // meridians
- for (u32 j = 0; j < east_west_lines; j++) {
- // theta should range from 0 to 2PI
- f32 theta = TAU * ((f32)j / (f32)north_south_lines);
- Vec3 position = spherical_to_cartesian_coords(radius, theta, phi);
- // f32 d = vec3_len(position);
- // print_vec3(position);
- // printf("Phi %f Theta %f d %d\n", phi, theta, d);
- // assert(d == radius); // all points on the sphere should be 'radius' away from the origin
- Vertex v = { .static_3d = {
- .position = position,
- .normal =
- vec3_normalise(position), // normal vector on sphere is same as position
- .tex_coords = vec2(0, 0) // TODO
- } };
- Vertex_darray_push(vertices, v);
- }
- }
-
- // Bottom point
- Vertex bot = { .static_3d = { .position = vec3(0, -radius, 0),
- .normal = vec3_normalise(vec3(0, -radius, 0)),
- .tex_coords = vec2(0, 0) } };
- Vertex_darray_push(vertices, bot);
-
- u32_darray* indices = u32_darray_new(1);
-
- // top bottom rings
- for (u32 i = 0; i < north_south_lines; i++) {
- u32 i1 = i + 1;
- u32 i2 = (i + 1) % north_south_lines + 1;
- push_triangle(indices, 0, i2, i1);
- /* TRACE("Push triangle (%.2f %.2f %.2f)->(%.2f %.2f %.2f)->(%.2f %.2f %.2f)\n", */
- /* vertices->data[0].static_3d.position.x, vertices->data[0].static_3d.position.y, */
- /* vertices->data[0].static_3d.position.z, vertices->data[i1].static_3d.position.x, */
- /* vertices->data[i1].static_3d.position.y, vertices->data[i1].static_3d.position.z, */
- /* vertices->data[i2].static_3d.position.x, vertices->data[i2].static_3d.position.y, */
- /* vertices->data[i2].static_3d.position.z); */
- u32 bot = vertices->len - 1;
- u32 i3 = i + north_south_lines * (east_west_lines - 2) + 1;
- u32 i4 = (i + 1) % north_south_lines + north_south_lines * (east_west_lines - 2) + 1;
- push_triangle(indices, bot, i3, i4);
- }
-
- // quads
- for (u32 i = 0; i < east_west_lines - 2; i++) {
- u32 ring_start = i * north_south_lines + 1;
- u32 next_ring_start = (i + 1) * north_south_lines + 1;
- /* printf("ring start %d next ring start %d\n", ring_start, next_ring_start); */
- /* print_vec3(vertices->data[ring_start].static_3d.position); */
- /* print_vec3(vertices->data[next_ring_start].static_3d.position); */
- for (u32 j = 0; j < north_south_lines; j++) {
- u32 i0 = ring_start + j;
- u32 i1 = next_ring_start + j;
- u32 i2 = ring_start + (j + 1) % north_south_lines;
- u32 i3 = next_ring_start + (j + 1) % north_south_lines;
- push_triangle(indices, i0, i2, i1);
- /* TRACE("Push triangle (%.2f %.2f %.2f)->(%.2f %.2f %.2f)->(%.2f %.2f %.2f)\n", */
- /* vertices->data[i0].static_3d.position.x, vertices->data[i0].static_3d.position.y, */
- /* vertices->data[i0].static_3d.position.z, vertices->data[i1].static_3d.position.x, */
- /* vertices->data[i1].static_3d.position.y, vertices->data[i1].static_3d.position.z, */
- /* vertices->data[i2].static_3d.position.x, vertices->data[i2].static_3d.position.y, */
- /* vertices->data[i2].static_3d.position.z); */
- push_triangle(indices, i1, i2, i3);
- }
- }
-
- Geometry geo = {
- .format = VERTEX_STATIC_3D,
- .vertices = vertices,
- .has_indices = true,
- .index_count = indices->len,
- .indices = indices,
- };
-
- return geo;
-}
-
-Geometry Geo_CreateCone(f32 radius, f32 height, u32 resolution) {
- Vertex_darray* vertices = Vertex_darray_new((resolution + 1) * 2);
- u32_darray* indices = u32_darray_new(resolution * 2 * 3);
-
- // TODO: decide how UVs are unwrapped
-
- // tip
- VERT_3D(vertices, vec3(0.0, height, 0.0), VEC3_Y, vec2(0, 0));
-
- // sides
- f32 step = TAU / resolution;
-
- for (u32 i = 0; i < resolution; i++) {
- f32 x = cos(step * i) * radius;
- f32 z = sin(step * i) * radius;
- Vec3 pos = vec3(x, 0.0, z);
- Vec3 tip_to_vertex = vec3_sub(pos, vertices->data[0].static_3d.position);
- Vec3 center_to_vertex = pos;
- Vec3 tangent = vec3_cross(VEC3_Y, center_to_vertex);
- Vec3 normal_dir = vec3_cross(tangent, tip_to_vertex);
- Vec3 normal = vec3_normalise(normal_dir);
- VERT_3D(vertices, pos, normal, vec2(0, 0));
- }
- for (u32 i = 1; i < resolution; i++) {
- push_triangle(indices, 0, i + 1, i);
- }
- push_triangle(indices, 0, 1, resolution);
-
- // base center
- u32 center_idx = vertices->len;
- VERT_3D(vertices, VEC3_ZERO, VEC3_NEG_Y, vec2(0, 0));
-
- // base circle
- for (u32 i = 0; i < resolution; i++) {
- f32 x = cos(step * i) * radius;
- f32 z = sin(step * i) * radius;
- VERT_3D(vertices, vec3(x, 0.0, z), VEC3_NEG_Z, vec2(0, 0));
- }
- for (u32 i = 1; i < resolution; i++) {
- push_triangle(indices, center_idx, center_idx + i, center_idx + i + 1);
- }
- push_triangle(indices, center_idx, center_idx + resolution, center_idx + 1);
-
- Geometry geo = {
- .format = VERTEX_STATIC_3D,
- .vertices = vertices,
- .has_indices = true,
- .index_count = indices->len,
- .indices = indices,
- };
- return geo;
-}
-
-Geometry Geo_CreateCylinder(f32 radius, f32 height, u32 resolution) {
- Vertex_darray* vertices = Vertex_darray_new(1);
- u32_darray* indices = u32_darray_new(1);
-
- f32 step = TAU / resolution;
-
- // bot cap
- VERT_3D(vertices, VEC3_ZERO, VEC3_NEG_Y, vec2(0, 0));
- for (u32 i = 0; i < resolution; i++) {
- VERT_3D(vertices, vec3(cos(step * i) * radius, 0.0, sin(step * i) * radius), VEC3_NEG_Y,
- vec2(0, 0));
- }
- for (u32 i = 1; i < resolution; i++) {
- push_triangle(indices, 0, i, i + 1);
- }
- push_triangle(indices, 0, resolution, 1);
-
- // top cap
- u32 center_idx = vertices->len;
- VERT_3D(vertices, vec3(0.0, height, 0.0), VEC3_Y, vec2(0, 0));
- for (u32 i = 0; i < resolution; i++) {
- VERT_3D(vertices, vec3(cos(step * i) * radius, height, sin(step * i) * radius), VEC3_Y,
- vec2(0, 0));
- }
- for (u32 i = 1; i < resolution; i++) {
- push_triangle(indices, center_idx, center_idx + i + 1, center_idx + i);
- }
- push_triangle(indices, center_idx, center_idx + 1, center_idx + resolution);
-
- // sides
- u32 sides_start = vertices->len;
- for (u32 i = 0; i < resolution; i++) {
- f32 x = cos(step * i) * radius;
- f32 z = sin(step * i) * radius;
- // top then bottom
- VERT_3D(vertices, vec3(x, height, z), vec3_normalise(vec3(x, 0.0, z)), vec2(0, 0));
- VERT_3D(vertices, vec3(x, 0.0, z), vec3_normalise(vec3(x, 0.0, z)), vec2(0, 0));
- }
- for (u32 i = 0; i < resolution; i++) {
- u32 current = sides_start + i * 2;
- u32 next = sides_start + ((i + 1) % resolution) * 2;
- push_triangle(indices, current, next, current + 1);
- push_triangle(indices, current + 1, next, next + 1);
- }
-
- Geometry geo = {
- .format = VERTEX_STATIC_3D,
- .vertices = vertices,
- .has_indices = true,
- .index_count = indices->len,
- .indices = indices,
- };
- return geo;
-}
diff --git a/src/maths/primitives.h b/src/maths/primitives.h
deleted file mode 100644
index 4965545..0000000
--- a/src/maths/primitives.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <assert.h>
-#include <stdlib.h>
-#include "core.h"
-#include "maths_types.h"
-#include "render_types.h"
-
-Geometry Geo_CreatePlane(f32x2 extents, u32 tiling_u, u32 tiling_v);
-Geometry Geo_CreateCuboid(f32x3 extents);
-Geometry Geo_CreateCylinder(f32 radius, f32 height, u32 resolution);
-Geometry Geo_CreateCone(f32 radius, f32 height, u32 resolution);
-Geometry Geo_CreateUVsphere(f32 radius, u32 north_south_lines, u32 east_west_lines);
-Geometry Geo_CreateIcosphere(f32 radius, f32 n_subdivisions);
-
-static const Vec3 BACK_BOT_LEFT = (Vec3){ 0, 0, 0 };
-static const Vec3 BACK_BOT_RIGHT = (Vec3){ 1, 0, 0 };
-static const Vec3 BACK_TOP_LEFT = (Vec3){ 0, 1, 0 };
-static const Vec3 BACK_TOP_RIGHT = (Vec3){ 1, 1, 0 };
-static const Vec3 FRONT_BOT_LEFT = (Vec3){ 0, 0, 1 };
-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 };
-
-#define VERT_3D(arr, pos, norm, uv) \
- { \
- Vertex v = { .static_3d = { .position = pos, .normal = norm, .tex_coords = uv } }; \
- Vertex_darray_push(arr, v); \
- } \ No newline at end of file
diff --git a/src/physics.h b/src/physics.h
deleted file mode 100644
index 134f08b..0000000
--- a/src/physics.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-#include "geometry.h"
-#include "maths_types.h"
-
-// 'system' means that it gets called per frame
-
-typedef struct physics_settings {
- f32 gravity_strength;
-} physics_settings;
-
-// What else do I need?
-// intersection methods
-
-typedef struct physics_world {
- physics_settings settings;
-} physics_world;
-
-physics_world physics_init(physics_settings settings);
-void physics_shutdown(physics_world* phys_world);
-
-/** @brief perform one or more simulation steps */
-void physics_system_update(physics_world* phys_world, f64 deltatime);
-
-// enum ColliderType {
-// CuboidCollider,
-// SphereCollider,
-// };
-
-/** @brief Oriented Bounding Box */
-typedef struct OBB {
- Vec3 center;
- Bbox_3D bbox;
- Quat rotation;
-} OBB;
-
-PUB void Debug_DrawOBB(OBB obb);
-
-/** @brief generic collider structure */
-typedef struct Collider {
- u64 id; // ? Replace with handle?
- OBB shape; // NOTE: We're only supporting the one collider type for now
- bool on_ground;
-} Collider;
diff --git a/src/platform/file.c b/src/platform/file.c
deleted file mode 100644
index 91daa4f..0000000
--- a/src/platform/file.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "file.h"
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "log.h"
-#include "mem.h"
-#include "str.h"
-
-const char* string_from_file(const char* path) {
- FILE* f = fopen(path, "rb");
- if (f == NULL) {
- ERROR("Error reading file: %s. errno: %d", path, errno);
- return NULL;
- }
- if (ferror(f)) {
- ERROR("Error reading file: %s. errno: %d", path, errno);
- return NULL;
- }
- fseek(f, 0, SEEK_END);
- long fsize = ftell(f);
- rewind(f);
-
- char* string = malloc(fsize + 1);
- fread(string, fsize, 1, f);
- fclose(f);
-
- string[fsize] = '\0';
-
- return string;
-}
-
-str8_opt str8_from_file(arena* a, Str8 path) {
- char* p = cstr(a, path);
- str8_opt result = { .has_value = false };
-
- FILE* f = fopen(p, "rb");
- if (f == NULL) {
- ERROR("Error reading file: %s. errno: %d", path, errno);
- return result;
- }
- if (ferror(f)) {
- ERROR("Error reading file: %s. errno: %d", path, errno);
- return result;
- }
- fseek(f, 0, SEEK_END);
- long fsize = ftell(f);
- rewind(f);
-
- u8* raw = arena_alloc(a, fsize + 1);
- Str8 contents = Str8_create(raw, fsize);
- contents.buf[contents.len] = '\0';
-
- fread(raw, fsize, 1, f);
- fclose(f);
- result.contents = contents;
- result.has_value = true;
-
- return result;
-}
-
-FileData load_spv_file(const char* path) {
- FILE* f = fopen(path, "rb");
- if (f == NULL) {
- perror("Error opening file");
- return (FileData){ NULL, 0 };
- }
-
- fseek(f, 0, SEEK_END);
- long fsize = ftell(f);
- rewind(f);
-
- char* data = (char*)malloc(fsize);
- if (data == NULL) {
- perror("Memory allocation failed");
- fclose(f);
- return (FileData){ NULL, 0 };
- }
-
- size_t bytesRead = fread(data, 1, fsize, f);
- if (bytesRead < fsize) {
- perror("Failed to read the entire file");
- free(data);
- fclose(f);
- return (FileData){ NULL, 0 };
- }
-
- fclose(f);
- return (FileData){ data, bytesRead };
-}
diff --git a/src/platform/file.h b/src/platform/file.h
deleted file mode 100644
index 5e5e1e1..0000000
--- a/src/platform/file.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @file file.h
- * @brief File I/O utilities
- * @date 2024-02-24
- * @copyright Copyright (c) 2024
- */
-#pragma once
-
-#include "defines.h"
-#include "str.h"
-
-typedef struct str8_opt {
- Str8 contents;
- bool has_value;
-} str8_opt;
-
-const char* string_from_file(const char* path);
-
-str8_opt str8_from_file(arena* a, Str8 path);
-
-typedef struct {
- char* data;
- size_t size;
-} FileData;
-
-FileData load_spv_file(const char* path);
diff --git a/src/platform/platform.h b/src/platform/platform.h
deleted file mode 100644
index c2be630..0000000
--- a/src/platform/platform.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include "defines.h"
-#include "str.h"
-
-// -- Paths
-typedef struct path_opt {
- Str8 path;
- bool has_value;
-} path_opt;
-
-// TODO: convert to using str8
-// TODO: use uppercase code style
-path_opt path_parent(arena* a, const char* path);
-
-// --- Threads
-typedef struct CelThread CelThread;
-
-CelThread Thread_Create();
-void Thread_Destroy(CelThread* thread);
-
-// --- Mutexes
-typedef struct CelMutex CelMutex;
-
-CelMutex Mutex_Create();
-void Mutex_Destroy(CelMutex* mutex);
-
-/** @brief Blocks until the mutex can be acquired. if returns false then an error occurred and can
- * be checked (TODO) */
-bool Mutex_Lock(CelMutex* mutex);
-
-/** @brief Tries to acquire the mutex like `mutex_lock` but returns immediately if the mutex has
- * already been locked */
-bool Mutex_TryLock(CelMutex* mutex);
-
-/** @brief Releases a mutex. If it is already unlocked then does nothing */
-void Mutex_Unlock(CelMutex* mutex);
diff --git a/src/platform/platform_unix.c b/src/platform/platform_unix.c
deleted file mode 100644
index 86ac170..0000000
--- a/src/platform/platform_unix.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "platform.h"
-
-#if defined(CEL_PLATFORM_LINUX) || defined(CEL_PLATFORM_MAC)
-
-#include <libgen.h>
-#include <string.h>
-
-path_opt path_parent(arena* a, const char* path) {
- // Duplicate the string because dirname doesnt like const literals
- char* path_copy = arena_alloc(a, strlen(path) + 1);
- strcpy(path_copy, path);
- char* path_dirname = dirname(path_copy);
- return (path_opt){ .path = Str8_cstr_view(path_dirname), .has_value = true };
-}
-
-#endif
diff --git a/src/platform/platform_windows.c b/src/platform/platform_windows.c
deleted file mode 100644
index 21ef359..0000000
--- a/src/platform/platform_windows.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "platform.h"
-
-#if defined(CEL_PLATFORM_WINDOWS)
-
-#include <shlwapi.h>
-#include <windows.h>
-#pragma comment(lib, "Shlwapi.lib")
-
-path_opt path_parent(arena* a, const char* path) {
- // Duplicate the string because PathRemoveFileSpec mutates in-place
- size_t len = strlen(path) + 1;
- char* path_copy = arena_alloc(a, len);
- strcpy_s(path_copy, len, path);
-
- if (PathRemoveFileSpecA(path_copy)) {
- return (path_opt){ .path = Str8_cstr_view(path_copy), .has_value = true };
- } else {
- return (path_opt){ .has_value = false };
- }
-}
-
-#endif
diff --git a/src/ral/README.md b/src/ral/README.md
deleted file mode 100644
index f66b95a..0000000
--- a/src/ral/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# RAL
-
-**Render Abstraction Layer** is a thin abstraction over graphics APIs. Everything in `render` builds on top of the code in
-this folder in order to be API-agnostic. It also makes writing graphics code easier as it smooths over some of the discrepancies
-between APIs like texture/buffer creation and updating shader values. \ No newline at end of file
diff --git a/src/ral/backends/metal/backend_metal.h b/src/ral/backends/metal/backend_metal.h
deleted file mode 100644
index e69de29..0000000
--- a/src/ral/backends/metal/backend_metal.h
+++ /dev/null
diff --git a/src/ral/backends/opengl/backend_opengl.c b/src/ral/backends/opengl/backend_opengl.c
deleted file mode 100644
index 613d7e1..0000000
--- a/src/ral/backends/opengl/backend_opengl.c
+++ /dev/null
@@ -1,449 +0,0 @@
-#include "backend_opengl.h"
-#include "colours.h"
-#include "maths_types.h"
-#if defined(CEL_REND_BACKEND_OPENGL)
-#include <assert.h>
-#include "log.h"
-#include "mem.h"
-#include "opengl_helpers.h"
-#include "ral_common.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-
-#include <glad/glad.h>
-#include <glfw3.h>
-
-typedef struct OpenglCtx {
- GLFWwindow* window;
- arena pool_arena;
- GPU_Swapchain swapchain;
- GPU_CmdEncoder main_encoder;
- GPU_BackendPools gpu_pools;
- ResourcePools* resource_pools;
-} OpenglCtx;
-
-static OpenglCtx context;
-
-bool GPU_Backend_Init(const char* window_name, struct GLFWwindow* window,
- struct ResourcePools* res_pools) {
- INFO("loading OpenGL backend");
-
- memset(&context, 0, sizeof(context));
- context.window = window;
-
- size_t pool_buffer_size = 1024 * 1024;
- context.pool_arena = arena_create(malloc(pool_buffer_size), pool_buffer_size);
-
- BackendPools_Init(&context.pool_arena, &context.gpu_pools);
- context.resource_pools = res_pools;
-
- 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);
-
- // glad: load all opengl function pointers
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- ERROR("Failed to initialise GLAD \n");
- return false;
- }
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
-
- context.swapchain = (GPU_Swapchain){ .dimensions = u32x2(1000, 1000) };
-
- return true;
-}
-
-// All of these are no-ops in OpenGL
-void GPU_Backend_Shutdown() { /* TODO */ }
-bool GPU_Device_Create(GPU_Device* out_device) { return true; }
-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) {
- 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) {}
-
-void GPU_Swapchain_Resize(i32 new_width, i32 new_height) {
- context.swapchain.dimensions = u32x2(new_width, new_height);
-}
-
-u32x2 GPU_Swapchain_GetDimensions() { return context.swapchain.dimensions; }
-
-GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description) {
- // allocate new pass
- GPU_Renderpass* renderpass = Renderpass_pool_alloc(&context.gpu_pools.renderpasses, NULL);
- renderpass->description = description;
-
- if (!description.default_framebuffer) {
- // If we're not using the default framebuffer we need to generate a new one
- GLuint gl_fbo_id;
- glGenFramebuffers(1, &gl_fbo_id);
- renderpass->fbo = gl_fbo_id;
- } else {
- renderpass->fbo = OPENGL_DEFAULT_FRAMEBUFFER;
- assert(!description.has_color_target);
- assert(!description.has_depth_stencil);
- }
- glBindFramebuffer(GL_FRAMEBUFFER, renderpass->fbo);
-
- if (description.has_color_target && !description.default_framebuffer) {
- GPU_Texture* colour_attachment = TEXTURE_GET(description.color_target);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- colour_attachment->id, 0);
- }
- if (description.has_depth_stencil && !description.default_framebuffer) {
- GPU_Texture* depth_attachment = TEXTURE_GET(description.depth_stencil);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_attachment->id,
- 0);
- }
-
- if (description.has_depth_stencil && !description.has_color_target) {
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0); // reset to default framebuffer
-
- return renderpass;
-}
-
-void GPU_Renderpass_Destroy(GPU_Renderpass* pass) { glDeleteFramebuffers(1, &pass->fbo); }
-
-GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description,
- GPU_Renderpass* renderpass) {
- GPU_Pipeline* pipeline = Pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL);
-
- // Create shader program
- u32 shader_id = shader_create_separate(description.vs.filepath.buf, description.fs.filepath.buf);
- pipeline->shader_id = shader_id;
-
- // Vertex format
- pipeline->vertex_desc = description.vertex_desc;
-
- // Allocate uniform buffers if needed
- u32 ubo_count = 0;
- // printf("data layouts %d\n", description.data_layouts_count);
- for (u32 layout_i = 0; layout_i < description.data_layouts_count; layout_i++) {
- ShaderDataLayout sdl = description.data_layouts[layout_i];
- TRACE("Got shader data layout %d's bindings! . found %d", layout_i, sdl.binding_count);
-
- for (u32 binding_j = 0; binding_j < sdl.binding_count; binding_j++) {
- u32 binding_id = binding_j;
- assert(binding_id < MAX_PIPELINE_UNIFORM_BUFFERS);
- ShaderBinding binding = sdl.bindings[binding_j];
- // Do I want Buffer vs Bytes?
- if (binding.kind == BINDING_BYTES) {
- static u32 s_binding_point = 0;
- BufferHandle ubo_handle = GPU_BufferCreate(binding.data.bytes.size, BUFFER_UNIFORM,
- BUFFER_FLAG_GPU, NULL); // no data right now
- pipeline->uniform_bindings[ubo_count++] = ubo_handle;
- GPU_Buffer* ubo_buf = BUFFER_GET(ubo_handle);
-
- i32 blockIndex = glGetUniformBlockIndex(pipeline->shader_id, binding.label);
- printf("Block index for %s: %d", binding.label, blockIndex);
- if (blockIndex < 0) {
- WARN("Couldn't retrieve block index for uniform block '%s'", binding.label);
- } else {
- // DEBUG("Retrived block index %d for %s", blockIndex, binding.label);
- }
- u32 blocksize;
- glGetActiveUniformBlockiv(pipeline->shader_id, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
- &blocksize);
- printf("\t with size %d bytes\n", blocksize);
-
- glBindBufferBase(GL_UNIFORM_BUFFER, s_binding_point, ubo_buf->id.ubo);
- if (blockIndex != GL_INVALID_INDEX) {
- glUniformBlockBinding(pipeline->shader_id, blockIndex, s_binding_point);
- }
- ubo_buf->ubo_binding_point = s_binding_point++;
- ubo_buf->name = binding.label;
- assert(s_binding_point < GL_MAX_UNIFORM_BUFFER_BINDINGS);
- }
- }
- }
- pipeline->uniform_count = ubo_count;
-
- pipeline->renderpass = renderpass;
- pipeline->wireframe = description.wireframe;
-
- return pipeline;
-}
-
-void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline) {}
-
-GPU_CmdEncoder GPU_CmdEncoder_Create() {
- GPU_CmdEncoder encoder = { 0 };
- return encoder;
-}
-
-BufferHandle GPU_BufferCreate(u64 size, GPU_BufferType buf_type, GPU_BufferFlags flags,
- const void* data) {
- // "allocating" the cpu-side buffer struct
- BufferHandle handle;
- GPU_Buffer* buffer = Buffer_pool_alloc(&context.resource_pools->buffers, &handle);
- buffer->size = size;
- buffer->vao = 0;
-
- // Opengl buffer
- GLuint gl_buffer_id;
- glGenBuffers(1, &gl_buffer_id);
-
- GLenum gl_buf_type;
- GLenum gl_buf_usage = GL_STATIC_DRAW;
-
- switch (buf_type) {
- case BUFFER_UNIFORM:
- DEBUG("Creating Uniform buffer");
- gl_buf_type = GL_UNIFORM_BUFFER;
- /* gl_buf_usage = GL_DYNAMIC_DRAW; */
- buffer->id.ubo = gl_buffer_id;
- break;
- case BUFFER_DEFAULT:
- case BUFFER_VERTEX:
- DEBUG("Creating Vertex buffer");
- gl_buf_type = GL_ARRAY_BUFFER;
- buffer->id.vbo = gl_buffer_id;
- break;
- case BUFFER_INDEX:
- DEBUG("Creating Index buffer");
- gl_buf_type = GL_ELEMENT_ARRAY_BUFFER;
- buffer->id.ibo = gl_buffer_id;
- break;
- default:
- WARN("Unimplemented gpu_buffer_type provided %s", buffer_type_names[buf_type]);
- break;
- }
- // bind buffer
- glBindBuffer(gl_buf_type, gl_buffer_id);
-
- if (data) {
- TRACE("Upload data (%d bytes) as part of buffer creation", size);
- glBufferData(gl_buf_type, buffer->size, data, gl_buf_usage);
- } else {
- TRACE("Allocating but not uploading (%d bytes)", size);
- glBufferData(gl_buf_type, buffer->size, NULL, gl_buf_usage);
- }
-
- glBindBuffer(gl_buf_type, 0);
-
- return handle;
-}
-
-void GPU_BufferDestroy(BufferHandle handle) { glDeleteBuffers(1, &handle.raw); }
-
-TextureHandle GPU_TextureCreate(TextureDesc desc, bool create_view, const void* data) {
- // "allocating" the cpu-side struct
- 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;
-
- GLenum gl_tex_type = opengl_tex_type(desc.tex_type);
- texture->type = desc.tex_type;
- printf("Creating texture of type %s\n", texture_type_names[desc.tex_type]);
- glBindTexture(gl_tex_type, gl_texture_id);
-
- GLint internal_format;
- if (desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT) {
- internal_format = GL_DEPTH_COMPONENT;
- } else if (desc.format == TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM) {
- internal_format = GL_RGBA;
- } else {
- internal_format = GL_RGB;
- }
-
- GLint format = internal_format;
- // FIXME: GLint format = desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_DEPTH_COMPONENT :
- // GL_RGBA;
- GLenum data_type = desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_FLOAT : GL_UNSIGNED_BYTE;
-
- if (desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- } else {
- // set the texture wrapping parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- // set texture filtering parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
-
- if (data) {
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.extents.x, desc.extents.y, 0, format,
- data_type, data);
- if (desc.tex_type == TEXTURE_TYPE_2D) {
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- } else {
- WARN("No image data provided");
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.extents.x, desc.extents.y, 0, format,
- data_type, NULL);
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- 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)
-
-void GPU_EncodeBindPipeline(GPU_CmdEncoder* encoder, GPU_Pipeline* pipeline) {
- encoder->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);
- }
-}
-
-void GPU_EncodeBindShaderData(GPU_CmdEncoder* encoder, u32 group, ShaderDataLayout layout) {
- for (u32 binding_i = 0; binding_i < layout.binding_count; binding_i++) {
- ShaderBinding binding = layout.bindings[binding_i];
-
- switch (binding.kind) {
- case BINDING_BYTES: {
-#ifdef RAL_ASSERTS
- CASSERT_MSG(binding.data.bytes.data, "void* data pointer should be non null");
- CASSERT_MSG(binding.data.bytes.size > 0, "size should be greater than 0 bytes");
-#endif
- BufferHandle b;
- GPU_Buffer* ubo_buf;
- bool found = false;
- for (u32 i = 0; i < encoder->pipeline->uniform_count; i++) {
- b = encoder->pipeline->uniform_bindings[i];
- ubo_buf = BUFFER_GET(b);
- assert(ubo_buf->name != NULL);
- if (strcmp(ubo_buf->name, binding.label) == 0) {
- found = true;
- break;
- }
- }
- if (!found) {
- ERROR("Couldnt find uniform buffer object for %s!!", binding.label);
- break;
- }
-
- i32 blockIndex = glGetUniformBlockIndex(encoder->pipeline->shader_id, binding.label);
- if (blockIndex < 0) {
- WARN("Couldn't retrieve block index for uniform block '%s'", binding.label);
- break;
- }
-
- glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_buf->size, binding.data.bytes.data);
- break;
- }
- case BINDING_TEXTURE: {
- GPU_Texture* tex = TEXTURE_GET(binding.data.texture.handle);
- GLint tex_slot = glGetUniformLocation(encoder->pipeline->shader_id, binding.label);
- if (tex_slot == GL_INVALID_VALUE || tex_slot < 0) {
- WARN("Invalid binding label for texture %s - couldn't fetch texture slot uniform",
- binding.label);
- }
- glUniform1i(tex_slot, binding_i);
- glActiveTexture(GL_TEXTURE0 + binding_i);
- glBindTexture(opengl_tex_type(tex->type), tex->id);
- break;
- }
- default:
- WARN("Unsupported binding kind");
- }
- }
-}
-
-void GPU_EncodeSetDefaults(GPU_CmdEncoder* encoder) {}
-
-void GPU_EncodeSetVertexBuffer(GPU_CmdEncoder* encoder, BufferHandle buf) {
- GPU_Buffer* buffer = BUFFER_GET(buf);
- if (buffer->vao == 0) { // if no VAO for this vertex buffer, create it
- INFO("Setting up VAO");
- buffer->vao = opengl_bindcreate_vao(buffer, encoder->pipeline->vertex_desc);
- }
- glBindVertexArray(buffer->vao);
-}
-void GPU_EncodeSetIndexBuffer(GPU_CmdEncoder* encoder, BufferHandle buf) {
- GPU_Buffer* buffer = BUFFER_GET(buf);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->id.ibo);
-}
-void GPU_EncodeDrawTris(GPU_CmdEncoder* encoder, u64 count) {
- glDrawArrays(GL_TRIANGLES, 0, count);
-}
-void GPU_EncodeDrawIndexedTris(GPU_CmdEncoder* encoder, u64 index_count) {
- glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0);
-}
-
-PUB void GPU_EncodeDraw(GPU_CmdEncoder* encoder, PrimitiveTopology topology, u64 count) {
- glDrawArrays(opengl_prim_topology(topology), 0, count);
-}
-PUB void GPU_EncodeDrawIndexed(GPU_CmdEncoder* encoder, PrimitiveTopology topology,
- u64 index_count) {
- glDrawElements(opengl_prim_topology(topology), index_count, GL_UNSIGNED_INT, 0);
-}
-
-PUB void GPU_WriteTextureRegion(GPU_CmdEncoder* encoder, TextureHandle dst, u32 x_offset,
- u32 y_offset, u32 width, u32 height, const void* data) {
- CASSERT_MSG(data, "const void* data must not be NULL");
-
- GPU_Texture* tex = TEXTURE_GET(dst);
-
- glBindTexture(GL_TEXTURE_2D, tex->id);
- glTexSubImage2D(GL_TEXTURE_2D, 0, x_offset, y_offset, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
- data);
-}
-
-bool GPU_Backend_BeginFrame() {
- glViewport(0, 0, context.swapchain.dimensions.x * 2, context.swapchain.dimensions.y * 2);
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- return true;
-}
-
-void GPU_Backend_EndFrame() { glfwSwapBuffers(context.window); }
-
-#endif
diff --git a/src/ral/backends/opengl/backend_opengl.h b/src/ral/backends/opengl/backend_opengl.h
deleted file mode 100644
index 7bd1b81..0000000
--- a/src/ral/backends/opengl/backend_opengl.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#pragma once
-#include "defines.h"
-
-#if defined(CEL_REND_BACKEND_OPENGL)
-
-#include "maths_types.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-
-#define MAX_PIPELINE_UNIFORM_BUFFERS 32
-
-#define OPENGL_DEFAULT_FRAMEBUFFER 0
-
-typedef struct GPU_Swapchain {
- u32x2 dimensions;
-} GPU_Swapchain;
-
-typedef struct GPU_Device {
- u32 pad;
-} GPU_Device;
-
-typedef struct GPU_PipelineLayout {
- void* pad;
-} GPU_PipelineLayout;
-
-typedef struct GPU_Pipeline {
- u32 shader_id;
- GPU_Renderpass* renderpass;
- VertexDescription vertex_desc;
- BufferHandle uniform_bindings[MAX_PIPELINE_UNIFORM_BUFFERS];
- u32 uniform_count;
- bool wireframe;
-} GPU_Pipeline;
-
-typedef struct GPU_Renderpass {
- u32 fbo;
- GPU_RenderpassDesc description;
-} GPU_Renderpass;
-
-typedef struct GPU_CmdEncoder {
- GPU_Pipeline* pipeline;
-} GPU_CmdEncoder; // Recording
-
-typedef struct GPU_CmdBuffer {
- void* pad;
-} GPU_CmdBuffer; // Ready for submission
-
-typedef struct GPU_Buffer {
- union {
- u32 vbo;
- u32 ibo;
- u32 ubo;
- } id;
- union {
- u32 vao;
- u32 ubo_binding_point;
- }; // Optional
- char* name;
- u64 size;
-} GPU_Buffer;
-
-typedef struct GPU_Texture {
- u32 id;
- GPU_TextureType type;
-} GPU_Texture;
-
-typedef struct opengl_support {
- u32 pad;
-} opengl_support;
-
-void uniform_vec3f(u32 program_id, const char* uniform_name, Vec3* value);
-void uniform_f32(u32 program_id, const char* uniform_name, f32 value);
-void uniform_i32(u32 program_id, const char* uniform_name, i32 value);
-void uniform_mat4f(u32 program_id, const char* uniform_name, Mat4* value);
-
-typedef enum GlCommandType {
- GLCMD_DRAW,
- GLCMD_DRAW_INDEXED,
- GLCMD_BIND_VBUF,
- GLCMD_BIND_IBUF,
- GLCMD_SET_PROGRAM,
-} GlCommandType;
-
-typedef struct GlCommand {
- GlCommandType cmd_type;
- union {
- struct {
- PrimitiveTopology topology;
- u32 start_vertex;
- u32 vertex_count;
- // TODO: instance
- } draw;
- struct {
- PrimitiveTopology topology;
- u32 index_count;
- } draw_indexed;
- struct {
- u32 buffer_id;
- } bind_vbuf;
- struct {
- u32 buffer_id;
- } bind_ibuf;
- struct {
- u32 program_id;
- } set_program;
- } data;
-} GlCommand;
-
-#endif
diff --git a/src/ral/backends/opengl/opengl_helpers.h b/src/ral/backends/opengl/opengl_helpers.h
deleted file mode 100644
index 706e2a0..0000000
--- a/src/ral/backends/opengl/opengl_helpers.h
+++ /dev/null
@@ -1,159 +0,0 @@
-#pragma once
-#include "defines.h"
-#include "ral_common.h"
-#include "ral_impl.h"
-#if defined(CEL_REND_BACKEND_OPENGL)
-#include "backend_opengl.h"
-#include "file.h"
-#include "log.h"
-#include "ral_types.h"
-
-#include <glad/glad.h>
-#include <glfw3.h>
-#include "ral_types.h"
-
-typedef struct opengl_vertex_attr {
- u32 count;
- GLenum data_type;
-} opengl_vertex_attr;
-
-static opengl_vertex_attr format_from_vertex_attr(VertexAttribType attr) {
- switch (attr) {
- case ATTR_F32:
- return (opengl_vertex_attr){ .count = 1, .data_type = GL_FLOAT };
- case ATTR_U32:
- return (opengl_vertex_attr){ .count = 1, .data_type = GL_UNSIGNED_INT };
- case ATTR_I32:
- return (opengl_vertex_attr){ .count = 1, .data_type = GL_INT };
- case ATTR_F32x2:
- return (opengl_vertex_attr){ .count = 2, .data_type = GL_FLOAT };
- case ATTR_U32x2:
- // return VK_FORMAT_R32G32_UINT;
- case ATTR_I32x2:
- // return VK_FORMAT_R32G32_UINT;
- case ATTR_F32x3:
- return (opengl_vertex_attr){ .count = 3, .data_type = GL_FLOAT };
- case ATTR_U32x3:
- // return VK_FORMAT_R32G32B32_UINT;
- case ATTR_I32x3:
- // return VK_FORMAT_R32G32B32_SINT;
- case ATTR_F32x4:
- return (opengl_vertex_attr){ .count = 4, .data_type = GL_FLOAT };
- case ATTR_U32x4:
- // return VK_FORMAT_R32G32B32A32_UINT;
- case ATTR_I32x4:
- return (opengl_vertex_attr){ .count = 4, .data_type = GL_INT };
- }
-}
-
-static u32 opengl_bindcreate_vao(GPU_Buffer* buf, VertexDescription desc) {
- DEBUG("Vertex format name %s", desc.debug_label);
- // 1. Bind the buffer
- glBindBuffer(GL_ARRAY_BUFFER, buf->id.vbo);
- // 2. Create new VAO
- u32 vao;
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
-
- // Attributes
- u32 attr_count = desc.attributes_count;
- // printf("N attributes %d\n", attr_count);
- u64 offset = 0;
- size_t vertex_size = desc.use_full_vertex_size ? sizeof(Vertex) : VertexDesc_CalcStride(&desc);
- for (u32 i = 0; i < desc.attributes_count; i++) {
- opengl_vertex_attr format = format_from_vertex_attr(desc.attributes[i]);
- glVertexAttribPointer(i, format.count, format.data_type, GL_FALSE, vertex_size, (void*)offset);
- TRACE(" %d %d %d %d %d %s", i, format.count, format.data_type, vertex_size, offset,
- desc.attr_names[i]);
- glEnableVertexAttribArray(i); // nth index
- size_t this_offset = VertexAttribSize(desc.attributes[i]);
- // printf("offset total %lld this attr %zu\n", offset, this_offset);
- offset += this_offset;
- }
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- return vao;
-}
-
-static u32 shader_create_separate(const char* vert_shader, const char* frag_shader) {
- INFO("Load shaders at %s and %s", vert_shader, frag_shader);
- int success;
- char info_log[512];
-
- u32 vertex = glCreateShader(GL_VERTEX_SHADER);
- const char* vertex_shader_src = string_from_file(vert_shader);
- if (vertex_shader_src == NULL) {
- ERROR("EXIT: couldnt load shader");
- exit(-1);
- }
- glShaderSource(vertex, 1, &vertex_shader_src, NULL);
- glCompileShader(vertex);
- glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
- if (!success) {
- glGetShaderInfoLog(vertex, 512, NULL, info_log);
- printf("%s\n", info_log);
- ERROR("EXIT: vertex shader compilation failed");
- exit(-1);
- }
-
- // fragment shader
- u32 fragment = glCreateShader(GL_FRAGMENT_SHADER);
- const char* fragment_shader_src = string_from_file(frag_shader);
- if (fragment_shader_src == NULL) {
- ERROR("EXIT: couldnt load shader");
- exit(-1);
- }
- glShaderSource(fragment, 1, &fragment_shader_src, NULL);
- glCompileShader(fragment);
- glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
- if (!success) {
- glGetShaderInfoLog(fragment, 512, NULL, info_log);
- printf("%s\n", info_log);
- ERROR("EXIT: fragment shader compilation failed");
- exit(-1);
- }
-
- u32 shader_prog;
- shader_prog = glCreateProgram();
-
- glAttachShader(shader_prog, vertex);
- glAttachShader(shader_prog, fragment);
- glLinkProgram(shader_prog);
- glDeleteShader(vertex);
- glDeleteShader(fragment);
- free((char*)vertex_shader_src);
- free((char*)fragment_shader_src);
-
- return shader_prog;
-}
-
-static GLenum opengl_tex_type(GPU_TextureType tex_type) {
- switch (tex_type) {
- case TEXTURE_TYPE_2D:
- return GL_TEXTURE_2D;
- case TEXTURE_TYPE_CUBE_MAP:
- return GL_TEXTURE_CUBE_MAP;
- default:
- return GL_TEXTURE_2D;
- }
-}
-
-static GLenum opengl_prim_topology(PrimitiveTopology t) {
- switch (t) {
- case CEL_POINT:
- return GL_POINT;
- case CEL_LINE:
- return GL_LINES;
- case CEL_LINE_STRIP:
- return GL_LINE_STRIP;
- case CEL_TRI:
- return GL_TRIANGLES;
- case CEL_TRI_STRIP:
- return GL_TRIANGLE_STRIP;
- case PRIMITIVE_TOPOLOGY_COUNT:
- WARN("Invalid PrimitiveTopology value");
- break;
- }
-}
-
-#endif
diff --git a/src/ral/backends/vulkan/backend_vulkan.c b/src/ral/backends/vulkan/backend_vulkan.c
deleted file mode 100644
index e69de29..0000000
--- a/src/ral/backends/vulkan/backend_vulkan.c
+++ /dev/null
diff --git a/src/ral/backends/vulkan/backend_vulkan.h b/src/ral/backends/vulkan/backend_vulkan.h
deleted file mode 100644
index f31bed2..0000000
--- a/src/ral/backends/vulkan/backend_vulkan.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-#ifdef CEL_REND_BACKEND_VULKAN
-#include "defines.h"
-#include "maths_types.h"
-#include "ral.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-
-#include <vulkan/vk_platform.h>
-#include <vulkan/vulkan.h>
-#include <vulkan/vulkan_core.h>
-
-// Provide definitions for RAL structs
-
-struct GPU_Swapchain {
- VkSwapchainKHR handle;
-};
-
-struct GPU_Device {
- VkPhysicalDevice physical_device;
- VkDevice logical_device;
-};
-
-struct GPU_PipelineLayout {};
-struct GPU_Pipeline {};
-struct GPU_Renderpass {};
-struct GPU_CmdEncoder {};
-struct GPU_CmdBuffer {};
-struct GPU_Buffer {
- VkBuffer handle;
- VkDeviceMemory memory;
- u64 size;
-};
-struct GPU_Texture {
- VkImage handle;
- VkDeviceMemory memory;
- u64 size;
- VkImageView view;
- VkSampler sampler;
- char* debug_label;
-};
-
-#endif
diff --git a/src/ral/backends/vulkan/vulkan_glossary.md b/src/ral/backends/vulkan/vulkan_glossary.md
deleted file mode 100644
index 4214f9d..0000000
--- a/src/ral/backends/vulkan/vulkan_glossary.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Vulkan Glossary
-
-*from https://vkguide.dev/docs/introduction/vulkan_execution/*
-
-- **VkInstance**: The Vulkan context, used to access drivers.
-- **VkPhysicalDevice**: A GPU. Used to query physical GPU details, like features, capabilities, memory size, etc.
-- **VkDevice**: The “logical” GPU context that you actually execute things on.
-- **VkBuffer**: A chunk of GPU visible memory.
-- **VkImage**: A texture you can write to and read from.
-- **VkPipeline**: Holds the state of the gpu needed to draw. For example: shaders, rasterization options, depth settings.
-- **VkRenderPass**: Holds information about the images you are rendering into. All drawing commands have to be done inside a renderpass. Only used in legacy vkguide.
-- **VkFrameBuffer**: Holds the target images for a renderpass. Only used in legacy vkguide.
-- **VkCommandBuffer**: Encodes GPU commands. All execution that is performed on the GPU itself (not in the driver) has to be encoded in a VkCommandBuffer.
-- **VkQueue**: Execution “port” for commands. GPUs will have a set of queues with different properties. Some allow only graphics commands, others only allow memory commands, etc. Command buffers are executed by submitting them into a queue, which will copy the rendering commands onto the GPU for execution.
-- **VkDescriptorSet**: Holds the binding information that connects shader inputs to data such as VkBuffer resources and VkImage textures. Think of it as a set of gpu-side pointers that you bind once.
-- **VkSwapchainKHR**: Holds the images for the screen. It allows you to render things into a visible window. The KHR suffix shows that it comes from an extension, which in this case is VK_KHR_swapchain.
-- **VkSemaphore**: Synchronizes GPU to GPU execution of commands. Used for syncing multiple command buffer submissions one after another.
-- **VkFence**: Synchronizes GPU to CPU execution of commands. Used to know if a command buffer has finished being executed on the GPU.
diff --git a/src/ral/backends/vulkan/vulkan_helpers.h b/src/ral/backends/vulkan/vulkan_helpers.h
deleted file mode 100644
index 23666c6..0000000
--- a/src/ral/backends/vulkan/vulkan_helpers.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#pragma once
-
-#include <assert.h>
-#include <vulkan/vulkan.h>
-#include <vulkan/vulkan_core.h>
-
-#include "darray.h"
-#include "defines.h"
-#include "log.h"
-#include "str.h"
-
-#define VULKAN_PHYS_DEVICE_MAX_EXTENSION_NAMES 36
-
-DECL_TYPED_ARRAY(const char*, cstr)
-
-static void plat_get_required_extension_names(cstr_darray* extensions) {
-#ifdef CEL_PLATFORM_LINUX
- cstr_darray_push(extensions, "VK_KHR_xcb_surface");
-#endif
-}
-
-// TODO(omni): port to using internal assert functions
-#define VK_CHECK(vulkan_expr) \
- do { \
- VkResult res = vulkan_expr; \
- if (res != VK_SUCCESS) { \
- ERROR_EXIT("Vulkan error: %u (%s:%d)", res, __FILE__, __LINE__); \
- } \
- } while (0)
-
-// TODO: typedef struct vk_debugger {} vk_debugger;
-
-typedef struct vulkan_physical_device_requirements {
- bool graphics;
- bool present;
- bool compute;
- bool transfer;
- str8 device_ext_names[VULKAN_PHYS_DEVICE_MAX_EXTENSION_NAMES];
- size_t device_ext_name_count;
- bool sampler_anistropy;
- bool discrete_gpu;
-} vulkan_physical_device_requirements;
-
-#define VULKAN_MAX_DEFAULT 32
-
-typedef struct vulkan_swapchain_support_info {
- VkSurfaceCapabilitiesKHR capabilities;
- VkSurfaceFormatKHR formats[VULKAN_MAX_DEFAULT];
- u32 format_count;
- VkPresentModeKHR present_modes[VULKAN_MAX_DEFAULT];
- u32 mode_count;
-} vulkan_swapchain_support_info;
-
-VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_callback(
- VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT flags,
- const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data);
-
-static void vulkan_device_query_swapchain_support(VkPhysicalDevice device, VkSurfaceKHR surface,
- vulkan_swapchain_support_info* out_support_info) {
- // TODO: add VK_CHECK to these calls!
-
- // Surface capabilities
- vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &out_support_info->capabilities);
-
- // Surface formats
- vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &out_support_info->format_count,
- 0); // Get number of formats
- if (out_support_info->format_count > 0) {
- vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &out_support_info->format_count,
- out_support_info->formats);
- }
-
- // Present Modes
- vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &out_support_info->mode_count,
- 0); // Get number of formats
- if (out_support_info->mode_count > 0) {
- vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &out_support_info->mode_count,
- out_support_info->present_modes);
- }
-}
-
-static VkSurfaceFormatKHR choose_swapchain_format(
- vulkan_swapchain_support_info* swapchain_support) {
- assert(swapchain_support->format_count > 0);
- // find a format
- for (u32 i = 0; i < swapchain_support->format_count; i++) {
- VkSurfaceFormatKHR format = swapchain_support->formats[i];
- if (format.format == VK_FORMAT_B8G8R8A8_SRGB &&
- format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
- return format;
- }
- }
- return swapchain_support->formats[0];
-}
-
-// static bool physical_device_meets_requirements(
-// VkPhysicalDevice device, VkSurfaceKHR surface, const VkPhysicalDeviceProperties* properties,
-// const VkPhysicalDeviceFeatures* features,
-// const vulkan_physical_device_requirements* requirements,
-// vulkan_physical_device_queue_family_info* out_queue_info,
-// vulkan_swapchain_support_info* out_swapchain_support) {
-// // TODO: pass in an arena
-
-// out_queue_info->graphics_family_index = -1;
-// out_queue_info->present_family_index = -1;
-// out_queue_info->compute_family_index = -1;
-// out_queue_info->transfer_family_index = -1;
-
-// if (requirements->discrete_gpu) {
-// if (properties->deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
-// TRACE("Device is not a physical GPU. Skipping.");
-// return false;
-// }
-// }
-
-// u32 queue_family_count = 0;
-// vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, 0);
-// VkQueueFamilyProperties queue_families[queue_family_count];
-// vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families);
-
-// INFO("Graphics | Present | Compute | Transfer | Name");
-// u8 min_transfer_score = 255;
-// for (u32 i = 0; i < queue_family_count; i++) {
-// u8 current_transfer_score = 0;
-
-// // Graphics queue
-// if (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
-// out_queue_info->graphics_family_index = i;
-// current_transfer_score++;
-// }
-
-// // Compute queue
-// if (queue_families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
-// out_queue_info->compute_family_index = i;
-// current_transfer_score++;
-// }
-
-// // Transfer queue
-// if (queue_families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) {
-// // always take the lowest score transfer index
-// if (current_transfer_score <= min_transfer_score) {
-// min_transfer_score = current_transfer_score;
-// out_queue_info->transfer_family_index = i;
-// }
-// }
-
-// // Present Queue
-// VkBool32 supports_present = VK_FALSE;
-// vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &supports_present);
-// if (supports_present) {
-// out_queue_info->present_family_index = i;
-// }
-// }
-
-// INFO(" %d | %d | %d | %d | %s",
-// out_queue_info->graphics_family_index != -1, out_queue_info->present_family_index != -1,
-// out_queue_info->compute_family_index != -1, out_queue_info->transfer_family_index != -1,
-// properties->deviceName);
-// TRACE("Graphics Family queue index: %d", out_queue_info->graphics_family_index);
-// TRACE("Present Family queue index: %d", out_queue_info->present_family_index);
-// TRACE("Compute Family queue index: %d", out_queue_info->compute_family_index);
-// TRACE("Transfer Family queue index: %d", out_queue_info->transfer_family_index);
-
-// if ((!requirements->graphics ||
-// (requirements->graphics && out_queue_info->graphics_family_index != -1))) {
-// INFO("Physical device meets our requirements! Proceed.");
-
-// vulkan_device_query_swapchain_support(
-// device, surface, out_swapchain_support
-
-// // TODO: error handling i.e. format count = 0 or present mode = 0
-
-// );
-// return true;
-// }
-
-// return false;
-// }
-
-VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_callback(
- VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT flags,
- const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
- switch (severity) {
- default:
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
- ERROR("%s", callback_data->pMessage);
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
- WARN("%s", callback_data->pMessage);
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
- INFO("%s", callback_data->pMessage);
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
- TRACE("%s", callback_data->pMessage);
- break;
- }
- return VK_FALSE;
-} \ No newline at end of file
diff --git a/src/ral/ral.h b/src/ral/ral.h
deleted file mode 100644
index fdbadd3..0000000
--- a/src/ral/ral.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-#include "ral_common.h"
-#include "ral_impl.h"
-#include "ral_types.h" \ No newline at end of file
diff --git a/src/ral/ral_common.c b/src/ral/ral_common.c
deleted file mode 100644
index d921ac4..0000000
--- a/src/ral/ral_common.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "ral_common.h"
-#include "ral_impl.h"
-
-void BackendPools_Init(arena* a, GPU_BackendPools* backend_pools) {
- PipelineLayout_pool pipeline_layout_pool =
- PipelineLayout_pool_create(a, MAX_PIPELINES, sizeof(GPU_PipelineLayout));
- backend_pools->pipeline_layouts = pipeline_layout_pool;
- Pipeline_pool pipeline_pool = Pipeline_pool_create(a, MAX_PIPELINES, sizeof(GPU_Pipeline));
- backend_pools->pipelines = pipeline_pool;
- Renderpass_pool rpass_pool = Renderpass_pool_create(a, MAX_RENDERPASSES, sizeof(GPU_Renderpass));
- backend_pools->renderpasses = rpass_pool;
-}
-
-void ResourcePools_Init(arena* a, struct ResourcePools* res_pools) {
- Buffer_pool buf_pool = Buffer_pool_create(a, MAX_BUFFERS, sizeof(GPU_Buffer));
- res_pools->buffers = buf_pool;
- Texture_pool tex_pool = Texture_pool_create(a, MAX_TEXTURES, sizeof(GPU_Texture));
- res_pools->textures = tex_pool;
-}
-
-VertexDescription static_3d_vertex_description() {
- VertexDescription builder = { .debug_label = "Standard static 3d vertex format" };
- VertexDesc_AddAttr(&builder, "inPosition", ATTR_F32x3);
- VertexDesc_AddAttr(&builder, "inNormal", ATTR_F32x3);
- VertexDesc_AddAttr(&builder, "inTexCoords", ATTR_F32x2);
- builder.use_full_vertex_size = true;
- return builder;
-}
-
-void VertexDesc_AddAttr(VertexDescription* builder, const char* name, VertexAttribType type) {
- u32 i = builder->attributes_count;
-
- size_t size = VertexAttribSize(type);
- builder->attributes[i] = type;
- // builder->stride += size;
- builder->attr_names[i] = name;
-
- builder->attributes_count++;
-}
-
-size_t VertexAttribSize(VertexAttribType attr) {
- switch (attr) {
- case ATTR_F32:
- case ATTR_U32:
- case ATTR_I32:
- return 4;
- case ATTR_F32x2:
- case ATTR_U32x2:
- case ATTR_I32x2:
- return 8;
- case ATTR_F32x3:
- case ATTR_U32x3:
- case ATTR_I32x3:
- return 12;
- case ATTR_F32x4:
- case ATTR_U32x4:
- case ATTR_I32x4:
- return 16;
- break;
- }
-}
-
-size_t VertexDesc_CalcStride(VertexDescription* desc) {
- size_t stride = 0;
- for (int i = 0; i < desc->attributes_count; i++) {
- size_t size = VertexAttribSize(desc->attributes[i]);
- stride += size;
- }
- return stride;
-}
diff --git a/src/ral/ral_common.h b/src/ral/ral_common.h
deleted file mode 100644
index 5a797e5..0000000
--- a/src/ral/ral_common.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @brief Common functions that don't actually depend on the specific backend
- */
-#pragma once
-#include "buf.h"
-#include "defines.h"
-#include "mem.h"
-#include "ral_types.h"
-// #include "ral_impl.h"
-
-// Concrete implementation
-#if defined(CEL_REND_BACKEND_OPENGL)
-#include "backend_opengl.h"
-#endif
-
-TYPED_POOL(GPU_Buffer, Buffer);
-TYPED_POOL(GPU_Texture, Texture);
-TYPED_POOL(GPU_PipelineLayout, PipelineLayout);
-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))
-
-// --- Views
-typedef struct GPU_BufferView {
- BufferHandle buf;
- size_t offset;
- size_t bytes;
-} GPU_BufferView;
-
-// --- Pools
-typedef struct GPU_BackendPools {
- Pipeline_pool pipelines;
- PipelineLayout_pool pipeline_layouts;
- Renderpass_pool renderpasses;
-} GPU_BackendPools;
-void BackendPools_Init(arena* a, GPU_BackendPools* backend_pools);
-
-struct ResourcePools {
- Buffer_pool buffers;
- Texture_pool textures;
-};
-typedef struct ResourcePools ResourcePools;
-void ResourcePools_Init(arena* a, struct ResourcePools* res_pools);
-
-PUB GPU_Renderpass* GPU_GetDefaultRenderpass(); // returns a renderpass that draws directly to
- // default framebuffer with default depth
-
-// --
-// window resize callback
-void GPU_WindowResizedCallback(u32 x, u32 y);
-
-// --- Vertex formats
-VertexDescription static_3d_vertex_description();
-
-void VertexDesc_AddAttr(VertexDescription* builder, const char* name, VertexAttribType type);
-size_t VertexDesc_CalcStride(VertexDescription* desc);
-
-size_t VertexAttribSize(VertexAttribType attr);
diff --git a/src/ral/ral_impl.h b/src/ral/ral_impl.h
deleted file mode 100644
index 16c9767..0000000
--- a/src/ral/ral_impl.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * @brief
- */
-#pragma once
-#include "buf.h"
-#include "defines.h"
-#include "ral_types.h"
-
-struct GLFWwindow;
-struct ResourcePools;
-
-// 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_PipelineLayout GPU_PipelineLayout;
-typedef struct GPU_Pipeline GPU_Pipeline;
-typedef struct GPU_Renderpass GPU_Renderpass;
-typedef struct GPU_CmdEncoder GPU_CmdEncoder; // Recording
-typedef struct GPU_CmdBuffer GPU_CmdBuffer; // Ready for submission
-typedef struct GPU_Buffer GPU_Buffer;
-typedef struct GPU_Texture GPU_Texture;
-
-bool GPU_Backend_Init(const char* window_name, struct GLFWwindow* window,
- struct ResourcePools* res_pools);
-void GPU_Backend_Shutdown();
-
-bool GPU_Device_Create(GPU_Device* out_device);
-void GPU_Device_Destroy(GPU_Device* device);
-
-bool GPU_Swapchain_Create(GPU_Swapchain* out_swapchain);
-void GPU_Swapchain_Destroy(GPU_Swapchain* swapchain);
-void GPU_Swapchain_Resize(i32 new_width, i32 new_height);
-u32x2 GPU_Swapchain_GetDimensions();
-
-PUB GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description);
-PUB void GPU_Renderpass_Destroy(GPU_Renderpass* pass);
-
-PUB GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description,
- GPU_Renderpass* renderpass);
-PUB void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline);
-
-// --- Command buffer
-PUB GPU_CmdEncoder GPU_CmdEncoder_Create();
-PUB void GPU_CmdEncoder_Destroy(GPU_CmdEncoder* encoder);
-PUB void GPU_CmdEncoder_Begin(GPU_CmdEncoder* encoder);
-PUB void GPU_CmdEncoder_Finish(GPU_CmdEncoder* encoder);
-PUB void GPU_CmdEncoder_BeginRender(GPU_CmdEncoder* encoder, GPU_Renderpass* renderpass);
-PUB void GPU_CmdEncoder_EndRender(GPU_CmdEncoder* encoder);
-PUB GPU_CmdEncoder* GPU_GetDefaultEncoder();
-PUB void GPU_QueueSubmit(GPU_CmdBuffer* cmd_buffer);
-
-// --- Buffers
-PUB BufferHandle GPU_BufferCreate(u64 size, GPU_BufferType buf_type, GPU_BufferFlags flags,
- const void* data);
-PUB void GPU_BufferDestroy(BufferHandle handle);
-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);
-
-// --- Data copy commands
-PUB void GPU_EncodeCopyBufToBuf(GPU_CmdEncoder* encoder, BufferHandle src, u64 src_offset,
- BufferHandle dst, u64 dst_offset, u64 copy_size);
-
-// PUB void GPU_EncodeCopyBufToTex(GPU_CmdEncoder* encoder, BufferHandle src, TextureHandle dst,
-// u32 x_offset, u32 y_offset, u32 width, u32 height, const void* data);
-/** @brief Convenience method for writing data directly into a texture. Staging memory is handled
- * internally. */
-PUB void GPU_WriteTextureRegion(GPU_CmdEncoder* encoder, TextureHandle dst, u32 x_offset,
- u32 y_offset, u32 width, u32 height, const void* data);
-PUB void GPU_WriteBuffer(GPU_CmdEncoder* encoder, BufferHandle buf, u64 offset, u64 size,
- const void* data);
-
-// --- Render commands
-PUB void GPU_EncodeBindPipeline(GPU_CmdEncoder* encoder, GPU_Pipeline* pipeline);
-PUB void GPU_EncodeBindShaderData(GPU_CmdEncoder* encoder, u32 group, ShaderDataLayout layout);
-void GPU_EncodeSetDefaults(GPU_CmdEncoder* encoder);
-PUB void GPU_EncodeSetVertexBuffer(GPU_CmdEncoder* encoder, BufferHandle buf);
-PUB void GPU_EncodeSetIndexBuffer(GPU_CmdEncoder* encoder, BufferHandle buf);
-
-PUB void GPU_EncodeDraw(GPU_CmdEncoder* encoder, PrimitiveTopology topology, u64 count);
-PUB void GPU_EncodeDrawIndexed(GPU_CmdEncoder* encoder, PrimitiveTopology topology,
- u64 index_count);
-// convenience versions of the above
-PUB void GPU_EncodeDrawTris(GPU_CmdEncoder* encoder, u64 count);
-PUB void GPU_EncodeDrawIndexedTris(GPU_CmdEncoder* encoder, u64 index_count);
-PUB void GPU_EncodeDrawInstanced(GPU_CmdEncoder* encoder, u64 index_count,
- u64 instance_count); // TODO: implement instanced rendering
-
-// --- Frame cycle
-PUB bool GPU_Backend_BeginFrame();
-PUB void GPU_Backend_EndFrame();
-
-// Concrete implementation
-#if defined(CEL_REND_BACKEND_OPENGL)
-#include "backend_opengl.h"
-#elif defined(CEL_REND_BACKEND_VULKAN)
-#include "backend_vulkan.h"
-#endif
diff --git a/src/ral/ral_types.h b/src/ral/ral_types.h
deleted file mode 100644
index fde3bed..0000000
--- a/src/ral/ral_types.h
+++ /dev/null
@@ -1,168 +0,0 @@
-#pragma once
-#include "darray.h"
-#include "defines.h"
-#include "maths_types.h"
-#include "str.h"
-
-// --- Max size constants
-#define MAX_SHADER_DATA_LAYOUTS 8
-#define MAX_SHADER_BINDINGS 8
-#define MAX_BUFFERS 256
-#define MAX_TEXTURES 256
-#define MAX_PIPELINES 128
-#define MAX_RENDERPASSES 128
-#define MAX_VERTEX_ATTRIBUTES 16
-
-// --- Handle types
-CORE_DEFINE_HANDLE(BufferHandle);
-CORE_DEFINE_HANDLE(TextureHandle);
-CORE_DEFINE_HANDLE(SamplerHandle);
-CORE_DEFINE_HANDLE(ShaderHandle);
-CORE_DEFINE_HANDLE(PipelineLayoutHandle);
-CORE_DEFINE_HANDLE(PipelineHandle);
-CORE_DEFINE_HANDLE(RenderpassHandle);
-#define INVALID_TEX_HANDLE ((TextureHandle){ .raw = 9999981 })
-
-// --- Buffers
-typedef enum GPU_BufferType {
- BUFFER_DEFAULT, // on Vulkan this would be a storage buffer?
- BUFFER_VERTEX,
- BUFFER_INDEX,
- BUFFER_UNIFORM,
- BUFFER_COUNT
-} GPU_BufferType;
-
-static const char* buffer_type_names[] = {
- "RAL Buffer Default", "RAL Buffer Vertex", "RAL Buffer Index",
- "RAL Buffer Uniform", "RAL Buffer Count",
-};
-
-typedef enum GPU_BufferFlag {
- BUFFER_FLAG_CPU = 1 << 0,
- BUFFER_FLAG_GPU = 1 << 1,
- BUFFER_FLAG_STORAGE = 1 << 2,
- BUFFER_FLAG_COUNT
-} GPU_BufferFlag;
-typedef u32 GPU_BufferFlags;
-
-static const char* texture_type_names[] = {
- "RAL Texture 2D", "RAL Texture 3D", "RAL Texture 2D Array",
- "RAL Texture Cubemap", "RAL Texture Count",
-};
-
-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;
-
-// --- Vertices
-
-typedef enum VertexFormat {
- VERTEX_STATIC_3D,
- VERTEX_SPRITE,
- VERTEX_SKINNED,
- VERTEX_COLOURED_STATIC_3D,
- VERTEX_RAW_POS_COLOUR,
- VERTEX_POS_ONLY,
- VERTEX_COUNT
-} VertexFormat;
-
-#ifndef TYPED_VERTEX_ARRAY
-KITC_DECL_TYPED_ARRAY(Vertex);
-KITC_DECL_TYPED_ARRAY(u32)
-#define TYPED_VERTEX_ARRAY
-#endif
-
-/// @strip_prefix(ATTR_)
-typedef enum VertexAttribType {
- ATTR_F32,
- ATTR_F32x2,
- ATTR_F32x3,
- ATTR_F32x4,
- ATTR_U32,
- ATTR_U32x2,
- ATTR_U32x3,
- ATTR_U32x4,
- ATTR_I32,
- ATTR_I32x2,
- ATTR_I32x3,
- ATTR_I32x4,
-} VertexAttribType;
-
-typedef struct VertexDescription {
- const char* debug_label;
- const char* attr_names[MAX_VERTEX_ATTRIBUTES];
- VertexAttribType attributes[MAX_VERTEX_ATTRIBUTES];
- u32 attributes_count;
- // size_t stride;
- bool use_full_vertex_size;
-} VertexDescription;
-
-// --- Shaders
-typedef enum PipelineKind {
- PIPELINE_GRAPHICS,
- PIPELINE_COMPUTE,
-} PipelineKind;
-
-typedef struct ShaderDesc {
- 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
-} ShaderDesc;
-
-typedef ShaderDataLayout (*FN_GetBindingLayout)(void* data);
-
-/** @brief takes a `ShaderDataLayout` without data, and puts the correct data into each binding */
-typedef void (*FN_BindShaderData)(ShaderDataLayout* layout, const void* data);
-
-// typedef struct ShaderData {
-// FN_GetBindingLayout get_layout;
-// void* data;
-// } ShaderData;
-
-typedef enum PrimitiveTopology {
-#ifdef TOPOLOGY_SHORT_NAMES
- CEL_POINT,
- CEL_LINE,
- CEL_LINE_STRIP,
- CEL_TRI,
- CEL_TRI_STRIP,
- PRIMITIVE_TOPOLOGY_COUNT
-#else
- PRIMITIVE_TOPOLOGY_POINT,
- PRIMITIVE_TOPOLOGY_LINE,
- PRIMITIVE_TOPOLOGY_LINE_STRIP,
- PRIMITIVE_TOPOLOGY_TRIANGLE,
- PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
- PRIMITIVE_TOPOLOGY_COUNT
-#endif
-} PrimitiveTopology;
-
-typedef enum Winding { WINDING_CCW, WINDING_CW } Winding;
-
-// based on https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthFunc.xhtml
-typedef enum CompareFunc {
- COMPARE_NEVER,
- COMPARE_LESS,
- COMPARE_EQUAL,
- COMPARE_LESS_EQUAL,
- COMPARE_GREATER,
- COMPARE_NOT_EQUAL,
- COMPARE_GREATER_EQUAL,
- COMPARE_ALWAYS,
- COMPARE_COUNT
-} CompareFunc;
-
-bool GraphicsPipelineDesc_AddShaderDataLayout(GraphicsPipelineDesc* desc, ShaderDataLayout layout);
-
-typedef struct GPU_RenderpassDesc {
- bool default_framebuffer;
- bool has_color_target;
- TextureHandle color_target; // for now only support one
- bool has_depth_stencil;
- TextureHandle depth_stencil;
-} GPU_RenderpassDesc;
diff --git a/src/render/archive/backends/backend_test.c b/src/render/archive/backends/backend_test.c
deleted file mode 100644
index 6347e27..0000000
--- a/src/render/archive/backends/backend_test.c
+++ /dev/null
@@ -1 +0,0 @@
-// #FUTURE \ No newline at end of file
diff --git a/src/render/archive/backends/metal/README.md b/src/render/archive/backends/metal/README.md
deleted file mode 100644
index f87f5c1..0000000
--- a/src/render/archive/backends/metal/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# TODO \ No newline at end of file
diff --git a/src/render/archive/backends/metal/backend_metal.h b/src/render/archive/backends/metal/backend_metal.h
deleted file mode 100644
index 9561bb6..0000000
--- a/src/render/archive/backends/metal/backend_metal.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#pragma once
-// #define CEL_REND_BACKEND_METAL
-#if defined(CEL_REND_BACKEND_METAL)
-
-#include "defines.h"
-#include "maths_types.h"
-#ifdef __OBJC__
-#import <Foundation/Foundation.h>
-#import <Metal/Metal.h>
-#import <MetalKit/MetalKit.h>
-#import <QuartzCore/CAMetalLayer.h>
-#else
-typedef void* id;
-#endif
-
-typedef struct gpu_swapchain {
- u32x2 dimensions;
-#ifdef __OBJC__
- CAMetalLayer* swapchain;
-#else
- void* swapchain;
-#endif
-} gpu_swapchain;
-typedef struct gpu_device {
-/** @brief `device` gives us access to our GPU */
-#ifdef __OBJC__
- id<MTLDevice> id;
-#else
- void* id;
-#endif
-} gpu_device;
-typedef struct gpu_pipeline_layout {
- void* pad;
-} gpu_pipeline_layout;
-typedef struct gpu_pipeline {
-#ifdef __OBJC__
- id<MTLRenderPipelineState> pipeline_state;
-#else
- void* pipeline_state;
-#endif
-} gpu_pipeline;
-typedef struct gpu_renderpass {
-#ifdef __OBJC__
- MTLRenderPassDescriptor* rpass_descriptor;
-#else
- void* rpass_descriptor;
-#endif
-} gpu_renderpass;
-typedef struct gpu_cmd_encoder {
-#ifdef __OBJC__
- id<MTLCommandBuffer> cmd_buffer;
- id<MTLRenderCommandEncoder> render_encoder;
-#else
- void* cmd_buffer;
- void* render_encoder;
-#endif
-} gpu_cmd_encoder;
-typedef struct gpu_cmd_buffer {
- void* pad;
-} gpu_cmd_buffer;
-
-typedef struct gpu_buffer {
-#ifdef __OBJC__
- id<MTLBuffer> id;
-#else
- void* id;
-#endif
- u64 size;
-} gpu_buffer;
-typedef struct gpu_texture {
- void* pad;
-} gpu_texture;
-
-#endif \ No newline at end of file
diff --git a/src/render/archive/backends/metal/backend_metal.m b/src/render/archive/backends/metal/backend_metal.m
deleted file mode 100644
index 4787755..0000000
--- a/src/render/archive/backends/metal/backend_metal.m
+++ /dev/null
@@ -1,285 +0,0 @@
-#include <assert.h>
-// #define CEL_REND_BACKEND_METAL
-#if defined(CEL_REND_BACKEND_METAL)
-#include <stddef.h>
-#include "ral_types.h"
-#include "colours.h"
-#include <stdlib.h>
-#include "camera.h"
-#include "defines.h"
-#include "file.h"
-#include "log.h"
-#include "maths_types.h"
-#include "ral.h"
-
-#define GLFW_INCLUDE_NONE
-#define GLFW_EXPOSE_NATIVE_COCOA
-
-#include <GLFW/glfw3.h>
-#include <GLFW/glfw3native.h>
-
-#import <Foundation/Foundation.h>
-#import <Metal/Metal.h>
-#import <MetalKit/MetalKit.h>
-#import <QuartzCore/CAMetalLayer.h>
-#include "backend_metal.h"
-
-// --- 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))
-
-typedef struct metal_context {
- GLFWwindow* window;
- NSWindow* metal_window;
- arena pool_arena;
-
- gpu_device* device;
- gpu_swapchain* swapchain;
- id<CAMetalDrawable> surface;
-
- id<MTLCommandQueue> command_queue;
- gpu_cmd_encoder main_command_buf;
- gpu_backend_pools gpu_pools;
- struct resource_pools* resource_pools;
-} metal_context;
-
-static metal_context context;
-
-struct GLFWwindow;
-
-bool gpu_backend_init(const char *window_name, struct GLFWwindow *window) {
- INFO("loading Metal backend");
-
- memset(&context, 0, sizeof(metal_context));
- context.window = window;
-
- size_t pool_buffer_size = 1024 * 1024;
- context.pool_arena = arena_create(malloc(pool_buffer_size), pool_buffer_size);
-
- backend_pools_init(&context.pool_arena, &context.gpu_pools);
- context.resource_pools = malloc(sizeof(struct resource_pools));
- resource_pools_init(&context.pool_arena, context.resource_pools);
-
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
-
- glfwMakeContextCurrent(window);
- // FIXME: glfwSetFramebufferSizeCallback(ren->window, framebuffer_size_callback);
-
- // get a NSWindow pointer from GLFWwindow
- NSWindow *nswindow = glfwGetCocoaWindow(window);
- context.metal_window = nswindow;
-
- // const id<MTLCommandQueue> queue = [gpu newCommandQueue];
- // CAMetalLayer *swapchain = [CAMetalLayer layer];
- // swapchain.device = gpu;
- // swapchain.opaque = YES;
-
- // // set swapchain for the window
- // nswindow.contentView.layer = swapchain;
- // nswindow.contentView.wantsLayer = YES;
-
- // MTLClearColor color = MTLClearColorMake(0.7, 0.1, 0.2, 1.0);
-
- // // set all our state properties
- // state->device = gpu;
- // state->cmd_queue = queue;
- // state->swapchain = swapchain;
- // state->clear_color = color;
-
- // NSError *err = 0x0; // TEMPORARY
-
- // WARN("About to try loading metallib");
- // id<MTLLibrary> defaultLibrary = [state->device newLibraryWithFile: @"build/gfx.metallib" error:&err];
- // CASSERT(defaultLibrary);
- // state->default_lib = defaultLibrary;
- // if (!state->default_lib) {
- // NSLog(@"Failed to load library");
- // exit(0);
- // }
-
- // create_render_pipeline(state);
-
- return true;
-}
-
-void gpu_backend_shutdown() {}
-
-bool gpu_device_create(gpu_device* out_device) {
- TRACE("GPU Device creation");
- const id<MTLDevice> gpu = MTLCreateSystemDefaultDevice();
- out_device->id = gpu;
- context.device = out_device;
-
- const id<MTLCommandQueue> queue = [gpu newCommandQueue];
- context.command_queue = queue;
-
- return true;
-}
-void gpu_device_destroy() {}
-
-// --- Render Pipeline
-gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description) {
- TRACE("GPU Graphics Pipeline creation");
- // Allocate
- // gpu_pipeline_layout* layout =
- // pipeline_layout_pool_alloc(&context.gpu_pools.pipeline_layouts, NULL);
- gpu_pipeline* pipeline = pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL);
-
- WARN("About to try loading metallib");
- assert(description.vs.is_combined_vert_frag);
- // Ignore fragment shader data, as vert shader data contains both
- NSError *err = 0x0; // TEMPORARY
- NSString *myNSString = [NSString stringWithUTF8String:(char*)description.vs.filepath.buf];
- id<MTLLibrary> default_library = [context.device->id newLibraryWithFile:myNSString error:&err];
- assert(default_library);
-
- // setup vertex and fragment shaders
- id<MTLFunction> ren_vert = [default_library newFunctionWithName:@"basic_vertex"];
- assert(ren_vert);
- id<MTLFunction> ren_frag = [default_library newFunctionWithName:@"basic_fragment"];
- assert(ren_frag);
-
- // create pipeline descriptor
- @autoreleasepool {
- NSError *err = 0x0;
- MTLRenderPipelineDescriptor *pld = [[MTLRenderPipelineDescriptor alloc] init];
- NSString *pipeline_name = [NSString stringWithUTF8String: description.debug_name];
- pld.label = pipeline_name;
- pld.vertexFunction = ren_vert;
- pld.fragmentFunction = ren_frag;
- pld.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
- pld.colorAttachments[0].blendingEnabled = YES;
-
- MTLDepthStencilDescriptor *depthStencilDescriptor = [MTLDepthStencilDescriptor new];
- depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionLess;
- depthStencilDescriptor.depthWriteEnabled = YES;
- pld.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
-
- id<MTLDepthStencilState> depth_descriptor = [context.device->id newDepthStencilStateWithDescriptor:depthStencilDescriptor];
- // FIXME: state->depth_state = depth_descriptor;
-
- id<MTLRenderPipelineState> pipeline_state = [context.device->id newRenderPipelineStateWithDescriptor:pld error:&err];
- TRACE("created renderpipelinestate");
- pipeline->pipeline_state = pipeline_state;
-
- }
-
- return pipeline;
-}
-void gpu_pipeline_destroy(gpu_pipeline* pipeline) {}
-
-// --- Renderpass
-gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description) {
- gpu_renderpass* renderpass = renderpass_pool_alloc(&context.gpu_pools.renderpasses, NULL);
-
- // TODO: Configure based on description
- // set up render pass
- context.surface = [context.swapchain->swapchain nextDrawable];
- MTLRenderPassDescriptor *renderPassDescriptor = [[MTLRenderPassDescriptor alloc] init];
- MTLRenderPassColorAttachmentDescriptor *cd = renderPassDescriptor.colorAttachments[0];
- [cd setTexture:context.surface.texture];
- [cd setLoadAction:MTLLoadActionClear];
- MTLClearColor clearColor = MTLClearColorMake(0.1, 0.1, 0.0, 1.0);
- [cd setClearColor:clearColor];
- [cd setStoreAction:MTLStoreActionStore];
-
- renderpass->rpass_descriptor = renderPassDescriptor;
-
- return renderpass;
-}
-
-void gpu_renderpass_destroy(gpu_renderpass* pass) {}
-
-// --- Swapchain
-bool gpu_swapchain_create(gpu_swapchain* out_swapchain) {
- TRACE("GPU Swapchain creation");
- CAMetalLayer *swapchain = [CAMetalLayer layer];
- swapchain.device = context.device->id;
- swapchain.opaque = YES;
- out_swapchain->swapchain = swapchain;
-
- // set swapchain for the window
- context.metal_window.contentView.layer = swapchain;
- context.metal_window.contentView.wantsLayer = YES;
-
- context.swapchain = out_swapchain;
- return true;
-}
-void gpu_swapchain_destroy(gpu_swapchain* swapchain) {}
-
-// --- Command buffer
-gpu_cmd_encoder gpu_cmd_encoder_create() {
- id <MTLCommandBuffer> cmd_buffer = [context.command_queue commandBuffer];
-
- return (gpu_cmd_encoder) {
- .cmd_buffer = cmd_buffer
- };
-}
-void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder) {}
-void gpu_cmd_encoder_begin(gpu_cmd_encoder encoder) { /* no-op */ }
-void gpu_cmd_encoder_begin_render(gpu_cmd_encoder* encoder, gpu_renderpass* renderpass) {
- DEBUG("Create Render Command Encoder");
- id<MTLRenderCommandEncoder> render_encoder = [encoder->cmd_buffer renderCommandEncoderWithDescriptor:renderpass->rpass_descriptor];
- encoder->render_encoder = render_encoder;
- // [encoder setDepthStencilState:state->depth_state];
-}
-void gpu_cmd_encoder_end_render(gpu_cmd_encoder* encoder) {}
-void gpu_cmd_encoder_begin_compute() {}
-gpu_cmd_encoder* gpu_get_default_cmd_encoder() {
- return &context.main_command_buf;
-}
-
-/** @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) {}
-
-void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset,
- buffer_handle dst, u64 dst_offset, u64 copy_size);
-void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size);
-
-void copy_buffer_to_buffer_oneshot(buffer_handle src, u64 src_offset, buffer_handle dst,
- u64 dst_offset, u64 copy_size);
-void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst);
-
-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) {
- [encoder->render_encoder setCullMode:MTLCullModeBack];
-}
-void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
- gpu_buffer* vertex_buf = BUFFER_GET(buf);
- [encoder->render_encoder setVertexBuffer:vertex_buf->id offset:0 atIndex:0];
-}
-void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {}
-void encode_set_bind_group() {}
-void encode_draw(gpu_cmd_encoder* encoder) {}
-void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count) {}
-void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {}
-
-buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags,
- const void* data) {
- buffer_handle handle;
- gpu_buffer* buffer = buffer_pool_alloc(&context.resource_pools->buffers, &handle);
- buffer->size = size;
-
- id<MTLBuffer> mtl_vert_buf = [context.device->id newBufferWithBytes:data
- length: size
- options:MTLResourceStorageModeShared];
- return handle;
-}
-void gpu_buffer_destroy(buffer_handle buffer) {}
-void gpu_buffer_upload(const void* data) {}
-
-texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) {}
-void gpu_texture_destroy(texture_handle) {}
-void gpu_texture_upload(texture_handle texture, const void* data) {}
-
-bool gpu_backend_begin_frame() {
- context.main_command_buf.cmd_buffer = [context.command_queue commandBuffer];
- return true;
- }
-void gpu_backend_end_frame() {}
-void gpu_temp_draw(size_t n_verts) {}
-
-#endif \ No newline at end of file
diff --git a/src/render/archive/backends/opengl/backend_opengl.c b/src/render/archive/backends/opengl/backend_opengl.c
deleted file mode 100644
index 43105e2..0000000
--- a/src/render/archive/backends/opengl/backend_opengl.c
+++ /dev/null
@@ -1,521 +0,0 @@
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include "colours.h"
-#include "maths.h"
-#include "opengl_helpers.h"
-#include "ral_types.h"
-#define CEL_REND_BACKEND_OPENGL
-#if defined(CEL_REND_BACKEND_OPENGL)
-#include <assert.h>
-#include <stdlib.h>
-
-#include "backend_opengl.h"
-#include "defines.h"
-#include "file.h"
-#include "log.h"
-#include "maths_types.h"
-#include "ral.h"
-
-#include <glad/glad.h>
-#include <glfw3.h>
-
-typedef struct opengl_context {
- GLFWwindow* window;
- arena pool_arena;
- gpu_cmd_encoder command_buffer;
- gpu_backend_pools gpu_pools;
- struct resource_pools* resource_pools;
-} opengl_context;
-
-static opengl_context context;
-
-struct GLFWwindow;
-
-bool gpu_backend_init(const char* window_name, struct GLFWwindow* window) {
- INFO("loading OpenGL backend");
-
- memset(&context, 0, sizeof(opengl_context));
- context.window = window;
-
- size_t pool_buffer_size = 1024 * 1024;
- context.pool_arena = arena_create(malloc(pool_buffer_size), pool_buffer_size);
-
- backend_pools_init(&context.pool_arena, &context.gpu_pools);
- context.resource_pools = malloc(sizeof(struct resource_pools));
- resource_pools_init(&context.pool_arena, context.resource_pools);
-
- 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);
-
- // glad: load all opengl function pointers
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- ERROR("Failed to initialise GLAD \n");
- return false;
- }
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
-
- return true;
-}
-
-// --- Render Pipeline
-gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description) {
- gpu_pipeline* pipeline = pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL);
-
- // Create shader program
- u32 shader_id = shader_create_separate(description.vs.filepath.buf, description.fs.filepath.buf);
- pipeline->shader_id = shader_id;
-
- // Vertex format
- pipeline->vertex_desc = description.vertex_desc;
-
- // Allocate uniform buffers if needed
- u32 ubo_count = 0;
- // printf("data layouts %d\n", description.data_layouts_count);
- for (u32 layout_i = 0; layout_i < description.data_layouts_count; layout_i++) {
- shader_data_layout sdl = description.data_layouts[layout_i].shader_data_get_layout(NULL);
- TRACE("Got shader data layout %d's bindings! . found %d", layout_i, sdl.bindings_count);
-
- for (u32 binding_j = 0; binding_j < sdl.bindings_count; binding_j++) {
- u32 binding_id = binding_j;
- assert(binding_id < MAX_PIPELINE_UNIFORM_BUFFERS);
- shader_binding binding = sdl.bindings[binding_j];
- if (binding.type == SHADER_BINDING_BYTES) {
- static u32 s_binding_point = 0;
- buffer_handle ubo_handle =
- gpu_buffer_create(binding.data.bytes.size, CEL_BUFFER_UNIFORM, CEL_BUFFER_FLAG_GPU,
- NULL); // no data right now
- pipeline->uniform_bindings[ubo_count++] = ubo_handle;
- gpu_buffer* ubo_buf = BUFFER_GET(ubo_handle);
-
- i32 blockIndex = glGetUniformBlockIndex(pipeline->shader_id, binding.label);
- printf("Block index for %s: %d", binding.label, blockIndex);
- if (blockIndex < 0) {
- WARN("Couldn't retrieve block index for uniform block '%s'", binding.label);
- } else {
- // DEBUG("Retrived block index %d for %s", blockIndex, binding.label);
- }
- u32 blocksize;
- glGetActiveUniformBlockiv(pipeline->shader_id, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
- &blocksize);
- printf("\t with size %d bytes\n", blocksize);
-
- glBindBufferBase(GL_UNIFORM_BUFFER, s_binding_point, ubo_buf->id.ubo);
- if (blockIndex != GL_INVALID_INDEX) {
- glUniformBlockBinding(pipeline->shader_id, blockIndex, s_binding_point);
- }
- ubo_buf->ubo_binding_point = s_binding_point++;
- ubo_buf->name = binding.label;
- assert(s_binding_point < GL_MAX_UNIFORM_BUFFER_BINDINGS);
- }
- }
- }
- pipeline->uniform_count = ubo_count;
-
- pipeline->renderpass = description.renderpass;
- pipeline->wireframe = description.wireframe;
-
- return pipeline;
-}
-void gpu_pipeline_destroy(gpu_pipeline* pipeline) {}
-
-// --- Renderpass
-gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description) {
- gpu_renderpass* renderpass = renderpass_pool_alloc(&context.gpu_pools.renderpasses, NULL);
- memcpy(&renderpass->description, description, sizeof(gpu_renderpass_desc));
- bool default_framebuffer = description->default_framebuffer;
-
- if (!default_framebuffer) {
- GLuint gl_fbo_id;
- glGenFramebuffers(1, &gl_fbo_id);
- renderpass->fbo = gl_fbo_id;
- } else {
- renderpass->fbo = OPENGL_DEFAULT_FRAMEBUFFER;
- assert(!description->has_color_target);
- assert(!description->has_depth_stencil);
- }
- glBindFramebuffer(GL_FRAMEBUFFER, renderpass->fbo);
-
- if (description->has_color_target && !default_framebuffer) {
- gpu_texture* colour_attachment = TEXTURE_GET(description->color_target);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- colour_attachment->id, 0);
- }
- if (description->has_depth_stencil && !default_framebuffer) {
- gpu_texture* depth_attachment = TEXTURE_GET(description->depth_stencil);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_attachment->id,
- 0);
- }
-
- if (description->has_depth_stencil && !description->has_color_target) {
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0); // reset to default framebuffer
-
- return renderpass;
-}
-void gpu_renderpass_destroy(gpu_renderpass* pass) { glDeleteFramebuffers(1, &pass->fbo); }
-
-// --- Command buffer
-gpu_cmd_encoder gpu_cmd_encoder_create() {
- gpu_cmd_encoder encoder = { 0 };
- return encoder;
-}
-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) {
- 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_cmd_encoder_end_render(gpu_cmd_encoder* encoder) { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
-void gpu_cmd_encoder_begin_compute() {}
-gpu_cmd_encoder* gpu_get_default_cmd_encoder() { return &context.command_buffer; }
-
-/** @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) {
- // TODO: finish implementing this
- gpu_buffer* buf = BUFFER_GET(gpu_buf);
-}
-
-/** @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) {
- encoder->pipeline = pipeline;
-
- if (pipeline->wireframe) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- } else {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-
- // In OpenGL binding a pipeline is more or less equivalent to just setting the shader
- glUseProgram(pipeline->shader_id);
-}
-void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {
- shader_data_layout sdl = data->shader_data_get_layout(data->data);
- // printf("Binding %s shader data\n", sdl.name);
-
- for (u32 i = 0; i < sdl.bindings_count; i++) {
- shader_binding binding = sdl.bindings[i];
- /* print_shader_binding(binding); */
-
- if (binding.type == SHADER_BINDING_BYTES) {
- buffer_handle b;
- gpu_buffer* ubo_buf;
- bool found = false;
- for (u32 i = 0; i < encoder->pipeline->uniform_count; i++) {
- b = encoder->pipeline->uniform_bindings[i];
- ubo_buf = BUFFER_GET(b);
- assert(ubo_buf->name != NULL);
- if (strcmp(ubo_buf->name, binding.label) == 0) {
- found = true;
- break;
- }
- }
- if (!found) {
- ERROR("Couldnt find uniform buffer object!!");
- }
-
- i32 blockIndex = glGetUniformBlockIndex(encoder->pipeline->shader_id, binding.label);
- if (blockIndex < 0) {
- WARN("Couldn't retrieve block index for uniform block '%s'", binding.label);
- } else {
- // DEBUG("Retrived block index %d for %s", blockIndex, binding.label);
- }
-
- glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_buf->size, binding.data.bytes.data);
-
- } else if (binding.type == SHADER_BINDING_TEXTURE) {
- gpu_texture* tex = TEXTURE_GET(binding.data.texture.handle);
- GLint tex_slot = glGetUniformLocation(encoder->pipeline->shader_id, binding.label);
- // printf("%d slot \n", tex_slot);
- if (tex_slot == GL_INVALID_VALUE || tex_slot < 0) {
- WARN("Invalid binding label for texture %s - couldn't fetch texture slot uniform",
- binding.label);
- }
- glUniform1i(tex_slot, i);
- glActiveTexture(GL_TEXTURE0 + i);
- glBindTexture(GL_TEXTURE_2D, tex->id);
- }
- }
-}
-void encode_set_default_settings(gpu_cmd_encoder* encoder) {}
-void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
- gpu_buffer* buffer = BUFFER_GET(buf);
- if (buffer->vao == 0) { // if no VAO for this vertex buffer, create it
- INFO("Setting up VAO");
- buffer->vao = opengl_bindcreate_vao(buffer, encoder->pipeline->vertex_desc);
- }
- glBindVertexArray(buffer->vao);
-}
-void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
- gpu_buffer* buffer = BUFFER_GET(buf);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->id.ibo);
-}
-void encode_draw(gpu_cmd_encoder* encoder, u64 count) { glDrawArrays(GL_TRIANGLES, 0, count); }
-void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count) {
- /* printf("Draw %ld indices\n", index_count); */
- glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0);
-}
-void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {}
-
-// --- Buffers
-buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags,
- const void* data) {
- // "allocating" the cpu-side buffer struct
- buffer_handle handle;
- gpu_buffer* buffer = buffer_pool_alloc(&context.resource_pools->buffers, &handle);
- buffer->size = size;
- buffer->vao = 0; // When we create a new buffer, there will be no VAO.
-
- // Opengl buffer
- GLuint gl_buffer_id;
- glGenBuffers(1, &gl_buffer_id);
-
- GLenum gl_buf_type;
- GLenum gl_buf_usage = GL_STATIC_DRAW;
-
- switch (buf_type) {
- case CEL_BUFFER_UNIFORM:
- DEBUG("Creating Uniform buffer");
- gl_buf_type = GL_UNIFORM_BUFFER;
- /* gl_buf_usage = GL_DYNAMIC_DRAW; */
- buffer->id.ubo = gl_buffer_id;
- break;
- case CEL_BUFFER_DEFAULT:
- case CEL_BUFFER_VERTEX:
- DEBUG("Creating Vertex buffer");
- gl_buf_type = GL_ARRAY_BUFFER;
- buffer->id.vbo = gl_buffer_id;
- break;
- case CEL_BUFFER_INDEX:
- DEBUG("Creating Index buffer");
- gl_buf_type = GL_ELEMENT_ARRAY_BUFFER;
- buffer->id.ibo = gl_buffer_id;
- break;
- default:
- WARN("Unimplemented gpu_buffer_type provided %s", buffer_type_names[buf_type]);
- break;
- }
- // bind buffer
- glBindBuffer(gl_buf_type, gl_buffer_id);
-
- if (data) {
- TRACE("Upload data (%d bytes) as part of buffer creation", size);
- glBufferData(gl_buf_type, buffer->size, data, gl_buf_usage);
- } else {
- TRACE("Allocating but not uploading (%d bytes)", size);
- glBufferData(gl_buf_type, buffer->size, NULL, gl_buf_usage);
- }
-
- glBindBuffer(gl_buf_type, 0);
-
- return handle;
-}
-
-texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) {
- // "allocating" the cpu-side struct
- texture_handle 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;
-
- glBindTexture(GL_TEXTURE_2D, gl_texture_id);
-
- GLint internal_format =
- desc.format == CEL_TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_DEPTH_COMPONENT : GL_RGB;
- GLenum format = desc.format == CEL_TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_DEPTH_COMPONENT : GL_RGBA;
- GLenum data_type = desc.format == CEL_TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_FLOAT : GL_UNSIGNED_BYTE;
-
- if (desc.format == CEL_TEXTURE_FORMAT_DEPTH_DEFAULT) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- } else {
- // set the texture wrapping parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- // set texture filtering parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
-
- if (data) {
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.extents.x, desc.extents.y, 0, format,
- data_type, data);
- glGenerateMipmap(GL_TEXTURE_2D);
- } else {
- WARN("No image data provided");
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.extents.x, desc.extents.y, 0, format,
- data_type, NULL);
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- return handle;
-}
-
-void gpu_texture_destroy(texture_handle) {}
-void gpu_texture_upload(texture_handle texture, const void* data) {}
-
-// --- Vertex formats
-bytebuffer vertices_as_bytebuffer(arena* a, vertex_format format, vertex_darray* vertices) {}
-
-// --- TEMP
-bool gpu_backend_begin_frame() {
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- return true;
-}
-void gpu_backend_end_frame() {
- // TODO: Reset all bindings
- glfwSwapBuffers(context.window);
-}
-void gpu_temp_draw(size_t n_verts) {}
-
-u32 shader_create_separate(const char* vert_shader, const char* frag_shader) {
- INFO("Load shaders at %s and %s", vert_shader, frag_shader);
- int success;
- char info_log[512];
-
- u32 vertex = glCreateShader(GL_VERTEX_SHADER);
- const char* vertex_shader_src = string_from_file(vert_shader);
- if (vertex_shader_src == NULL) {
- ERROR("EXIT: couldnt load shader");
- exit(-1);
- }
- glShaderSource(vertex, 1, &vertex_shader_src, NULL);
- glCompileShader(vertex);
- glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
- if (!success) {
- glGetShaderInfoLog(vertex, 512, NULL, info_log);
- printf("%s\n", info_log);
- ERROR("EXIT: vertex shader compilation failed");
- exit(-1);
- }
-
- // fragment shader
- u32 fragment = glCreateShader(GL_FRAGMENT_SHADER);
- const char* fragment_shader_src = string_from_file(frag_shader);
- if (fragment_shader_src == NULL) {
- ERROR("EXIT: couldnt load shader");
- exit(-1);
- }
- glShaderSource(fragment, 1, &fragment_shader_src, NULL);
- glCompileShader(fragment);
- glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
- if (!success) {
- glGetShaderInfoLog(fragment, 512, NULL, info_log);
- printf("%s\n", info_log);
- ERROR("EXIT: fragment shader compilation failed");
- exit(-1);
- }
-
- u32 shader_prog;
- shader_prog = glCreateProgram();
-
- glAttachShader(shader_prog, vertex);
- glAttachShader(shader_prog, fragment);
- glLinkProgram(shader_prog);
- glDeleteShader(vertex);
- glDeleteShader(fragment);
- free((char*)vertex_shader_src);
- free((char*)fragment_shader_src);
-
- return shader_prog;
-}
-
-inline void uniform_vec3f(u32 program_id, const char* uniform_name, vec3* value) {
- glUniform3fv(glGetUniformLocation(program_id, uniform_name), 1, &value->x);
-}
-inline void uniform_f32(u32 program_id, const char* uniform_name, f32 value) {
- glUniform1f(glGetUniformLocation(program_id, uniform_name), value);
-}
-inline void uniform_i32(u32 program_id, const char* uniform_name, i32 value) {
- glUniform1i(glGetUniformLocation(program_id, uniform_name), value);
-}
-inline void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value) {
- glUniformMatrix4fv(glGetUniformLocation(program_id, uniform_name), 1, GL_FALSE, value->data);
-}
-
-// void clear_screen(vec3 colour) {
-// glClearColor(colour.x, colour.y, colour.z, 1.0f);
-// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-// }
-
-// void texture_data_upload(texture *tex) {
-// printf("Texture name %s\n", tex->name);
-// TRACE("Upload texture data");
-// u32 texture_id;
-// glGenTextures(1, &texture_id);
-// glBindTexture(GL_TEXTURE_2D, texture_id);
-// tex->texture_id = texture_id;
-
-// // set the texture wrapping parameters
-// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-// GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
-// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-// // set texture filtering parameters
-// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex->width, tex->height, 0, tex->channel_type,
-// GL_UNSIGNED_BYTE, tex->image_data);
-// glGenerateMipmap(GL_TEXTURE_2D);
-// DEBUG("Freeing texture image data after uploading to GPU");
-// // stbi_image_free(tex->image_data); // data is on gpu now so we dont need it around
-// }
-
-// void bind_texture(shader s, texture *tex, u32 slot) {
-// // printf("bind texture slot %d with texture id %d \n", slot, tex->texture_id);
-// glActiveTexture(GL_TEXTURE0 + slot);
-// glBindTexture(GL_TEXTURE_2D, tex->texture_id);
-// }
-
-// void bind_mesh_vertex_buffer(void *_backend, mesh *mesh) { glBindVertexArray(mesh->vao); }
-
-// static inline GLenum to_gl_prim_topology(enum cel_primitive_topology primitive) {
-// switch (primitive) {
-// case CEL_PRIMITIVE_TOPOLOGY_TRIANGLE:
-// return GL_TRIANGLES;
-// case CEL_PRIMITIVE_TOPOLOGY_POINT:
-// case CEL_PRIMITIVE_TOPOLOGY_LINE:
-// case CEL_PRIMITIVE_TOPOLOGY_LINE_STRIP:
-// case CEL_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
-// case CEL_PRIMITIVE_TOPOLOGY_COUNT:
-// break;
-// }
-// }
-#endif
diff --git a/src/render/archive/backends/opengl/backend_opengl.h b/src/render/archive/backends/opengl/backend_opengl.h
deleted file mode 100644
index 14b44af..0000000
--- a/src/render/archive/backends/opengl/backend_opengl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#pragma once
-
-#ifdef CEL_REND_BACKEND_OPENGL
-
-#include "defines.h"
-#include "maths_types.h"
-#include "ral.h"
-#include "ral_types.h"
-
-#define MAX_PIPELINE_UNIFORM_BUFFERS 32
-
-#define OPENGL_DEFAULT_FRAMEBUFFER 0
-
-typedef struct gpu_swapchain {
- u32x2 dimensions;
-} gpu_swapchain;
-typedef struct gpu_device {
-} gpu_device;
-typedef struct gpu_pipeline_layout {
- void* pad
-} gpu_pipeline_layout;
-typedef struct gpu_pipeline {
- u32 shader_id;
- gpu_renderpass* renderpass;
- vertex_description vertex_desc;
- buffer_handle uniform_bindings[MAX_PIPELINE_UNIFORM_BUFFERS];
- u32 uniform_count;
- bool wireframe;
-} gpu_pipeline;
-typedef struct gpu_renderpass {
- u32 fbo;
- gpu_renderpass_desc description;
-} gpu_renderpass;
-typedef struct gpu_cmd_encoder {
- gpu_pipeline* pipeline;
-} gpu_cmd_encoder; // Recording
-typedef struct gpu_cmd_buffer {
- void* pad;
-} gpu_cmd_buffer; // Ready for submission
-
-typedef struct gpu_buffer {
- union {
- u32 vbo;
- u32 ibo;
- u32 ubo;
- } id;
- union {
- u32 vao;
- u32 ubo_binding_point
- }; // Optional
- char* name;
- u64 size;
-} gpu_buffer;
-typedef struct gpu_texture {
- u32 id;
- void* pad;
-} gpu_texture;
-
-typedef struct opengl_support {
-} opengl_support;
-
-u32 shader_create_separate(const char* vert_shader, const char* frag_shader);
-
-void uniform_vec3f(u32 program_id, const char* uniform_name, vec3* value);
-void uniform_f32(u32 program_id, const char* uniform_name, f32 value);
-void uniform_i32(u32 program_id, const char* uniform_name, i32 value);
-void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value);
-#endif
diff --git a/src/render/archive/backends/vulkan/README.md b/src/render/archive/backends/vulkan/README.md
deleted file mode 100644
index 220ed64..0000000
--- a/src/render/archive/backends/vulkan/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Vulkan Backend Overview \ No newline at end of file
diff --git a/src/render/archive/backends/vulkan/backend_vulkan.c b/src/render/archive/backends/vulkan/backend_vulkan.c
deleted file mode 100644
index 8801230..0000000
--- a/src/render/archive/backends/vulkan/backend_vulkan.c
+++ /dev/null
@@ -1,1705 +0,0 @@
-#include "defines.h"
-#if defined(CEL_REND_BACKEND_VULKAN)
-
-#define GLFW_INCLUDE_VULKAN
-#include <glfw3.h>
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <vulkan/vk_platform.h>
-#include <vulkan/vulkan.h>
-#include <vulkan/vulkan_core.h>
-
-#include "backend_vulkan.h"
-#include "buf.h"
-#include "darray.h"
-#include "maths_types.h"
-#include "mem.h"
-#include "ral_types.h"
-#include "str.h"
-#include "vulkan_helpers.h"
-
-#include "file.h"
-#include "log.h"
-#include "ral.h"
-#include "utils.h"
-
-// TEMP
-#define SCREEN_WIDTH 1000
-#define SCREEN_HEIGHT 1000
-#define VULKAN_QUEUES_COUNT 2
-#define MAX_DESCRIPTOR_SETS 10
-
-const char* queue_names[VULKAN_QUEUES_COUNT] = { "GRAPHICS", "TRANSFER" };
-
-KITC_DECL_TYPED_ARRAY(VkDescriptorSet)
-
-typedef struct vulkan_context {
- VkInstance instance;
- VkAllocationCallbacks* allocator;
- VkSurfaceKHR surface;
- vulkan_swapchain_support_info swapchain_support;
-
- arena temp_arena;
- arena pool_arena;
- gpu_device* device;
- gpu_swapchain* swapchain;
- u32 framebuffer_count;
- VkFramebuffer*
- swapchain_framebuffers; // TODO: Move this data into the swapchain as its own struct
-
- u32 current_img_index;
- u32 current_frame; // super important
- gpu_cmd_encoder main_cmd_bufs[MAX_FRAMES_IN_FLIGHT];
- VkSemaphore image_available_semaphores[MAX_FRAMES_IN_FLIGHT];
- VkSemaphore render_finished_semaphores[MAX_FRAMES_IN_FLIGHT];
- VkFence in_flight_fences[MAX_FRAMES_IN_FLIGHT];
-
- // HACK
- VkRenderPass main_renderpass;
-
- u32 screen_width;
- u32 screen_height;
- bool is_resizing;
- GLFWwindow* window;
-
- // Storage
- gpu_buffer buffers[1024];
- size_t buffer_count;
- VkDescriptorSet_darray* free_set_queue;
- struct resource_pools* resource_pools;
- gpu_backend_pools gpu_pools;
-
- VkDebugUtilsMessengerEXT vk_debugger;
-} vulkan_context;
-
-static vulkan_context context;
-
-// --- Function forward declarations
-
-void backend_pools_init(arena* a, gpu_backend_pools* backend_pools);
-
-/** @brief Enumerates and selects the most appropriate graphics device */
-bool select_physical_device(gpu_device* out_device);
-
-bool is_physical_device_suitable(VkPhysicalDevice device);
-
-queue_family_indices find_queue_families(VkPhysicalDevice device);
-
-bool create_logical_device(gpu_device* out_device);
-void create_swapchain_framebuffers();
-void create_sync_objects();
-void create_descriptor_pools();
-size_t vertex_attrib_size(vertex_attrib_type attr);
-
-VkShaderModule create_shader_module(str8 spirv);
-
-/** @brief Helper function for creating array of all extensions we want */
-cstr_darray* get_all_extensions();
-
-VkImage vulkan_image_create(u32x2 dimensions, VkImageType image_type, VkFormat format,
- VkImageUsageFlags usage);
-void vulkan_transition_image_layout(gpu_texture* texture, VkFormat format, VkImageLayout old_layout,
- VkImageLayout new_layout);
-
-// --- 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))
-
-bool gpu_backend_init(const char* window_name, GLFWwindow* window) {
- memset(&context, 0, sizeof(vulkan_context));
- context.allocator = 0; // TODO: use an allocator
- context.screen_width = SCREEN_WIDTH;
- context.screen_height = SCREEN_HEIGHT;
- context.window = window;
- context.current_img_index = 0;
- context.current_frame = 0;
- context.free_set_queue = VkDescriptorSet_darray_new(100);
-
- // Create an allocator
- size_t temp_arena_size = 1024 * 1024;
- context.temp_arena = arena_create(malloc(temp_arena_size), temp_arena_size);
-
- size_t pool_buffer_size = 1024 * 1024;
- context.pool_arena = arena_create(malloc(pool_buffer_size), pool_buffer_size);
-
- backend_pools_init(&context.pool_arena, &context.gpu_pools);
-
- // Setup Vulkan instance
- VkApplicationInfo app_info = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
- app_info.apiVersion = VK_API_VERSION_1_2;
- app_info.pApplicationName = window_name;
- app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
- app_info.pEngineName = "Celeritas Engine";
- app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
-
- VkInstanceCreateInfo create_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
- create_info.pApplicationInfo = &app_info;
-
- // Extensions
- cstr_darray* required_extensions = cstr_darray_new(2);
- // cstr_darray_push(required_extensions, VK_KHR_SURFACE_EXTENSION_NAME);
-
- uint32_t count;
- const char** extensions = glfwGetRequiredInstanceExtensions(&count);
- for (u32 i = 0; i < count; i++) {
- cstr_darray_push(required_extensions, extensions[i]);
- }
-
- cstr_darray_push(required_extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
-
- DEBUG("Required extensions:");
- for (u32 i = 0; i < cstr_darray_len(required_extensions); i++) {
- DEBUG(" %s", required_extensions->data[i]);
- }
-
- create_info.enabledExtensionCount = cstr_darray_len(required_extensions);
- create_info.ppEnabledExtensionNames = required_extensions->data;
-
- // TODO: Validation layers
- create_info.enabledLayerCount = 0;
- create_info.ppEnabledLayerNames = NULL;
-
- INFO("Validation layers enabled");
- cstr_darray* desired_validation_layers = cstr_darray_new(1);
- cstr_darray_push(desired_validation_layers, "VK_LAYER_KHRONOS_validation");
-
- u32 n_available_layers = 0;
- VK_CHECK(vkEnumerateInstanceLayerProperties(&n_available_layers, 0));
- TRACE("%d available layers", n_available_layers);
- VkLayerProperties* available_layers =
- arena_alloc(&context.temp_arena, n_available_layers * sizeof(VkLayerProperties));
- VK_CHECK(vkEnumerateInstanceLayerProperties(&n_available_layers, available_layers));
-
- for (int i = 0; i < cstr_darray_len(desired_validation_layers); i++) {
- // look through layers to make sure we can find the ones we want
- bool found = false;
- for (int j = 0; j < n_available_layers; j++) {
- if (str8_equals(str8_cstr_view(desired_validation_layers->data[i]),
- str8_cstr_view(available_layers[j].layerName))) {
- found = true;
- TRACE("Found layer %s", desired_validation_layers->data[i]);
- break;
- }
- }
-
- if (!found) {
- FATAL("Required validation is missing %s", desired_validation_layers->data[i]);
- return false;
- }
- }
- INFO("All validation layers are present");
- create_info.enabledLayerCount = cstr_darray_len(desired_validation_layers);
- create_info.ppEnabledLayerNames = desired_validation_layers->data;
-
- VkResult result = vkCreateInstance(&create_info, NULL, &context.instance);
- if (result != VK_SUCCESS) {
- ERROR("vkCreateInstance failed with result: %u", result);
- return false;
- }
- TRACE("Vulkan Instance created");
-
- DEBUG("Creating Vulkan debugger");
- u32 log_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
- VkDebugUtilsMessengerCreateInfoEXT debug_create_info = {
- VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT
- };
- debug_create_info.messageSeverity = log_severity;
- debug_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
- debug_create_info.pfnUserCallback = vk_debug_callback;
-
- PFN_vkCreateDebugUtilsMessengerEXT func =
- (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(context.instance,
- "vkCreateDebugUtilsMessengerEXT");
- assert(func);
- VK_CHECK(func(context.instance, &debug_create_info, context.allocator, &context.vk_debugger));
- DEBUG("Vulkan Debugger created");
-
- // Surface creation
- VkSurfaceKHR surface;
- VK_CHECK(glfwCreateWindowSurface(context.instance, window, NULL, &surface));
- context.surface = surface;
- TRACE("Vulkan Surface created");
-
- return true;
-}
-
-void gpu_backend_shutdown() {
- gpu_swapchain_destroy(context.swapchain);
-
- vkDestroySurfaceKHR(context.instance, context.surface, context.allocator);
- vkDestroyInstance(context.instance, context.allocator);
- arena_free_storage(&context.temp_arena);
-}
-
-bool gpu_device_create(gpu_device* out_device) {
- // First things first store this poitner from the renderer
- context.device = out_device;
-
- arena_save savept = arena_savepoint(&context.temp_arena);
- // Physical device
- if (!select_physical_device(out_device)) {
- return false;
- }
- TRACE("Physical device selected");
-
- // Logical device & Queues
- create_logical_device(out_device);
-
- // Create the command pool
- VkCommandPoolCreateInfo pool_create_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
- pool_create_info.queueFamilyIndex = out_device->queue_family_indicies.graphics_family_index;
- pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- vkCreateCommandPool(out_device->logical_device, &pool_create_info, context.allocator,
- &out_device->pool);
- TRACE("Command Pool created");
-
- // Synchronisation objects
- create_sync_objects();
- TRACE("Synchronisation primitives created");
-
- arena_rewind(savept); // Free any temp data
- return true;
-}
-
-bool gpu_swapchain_create(gpu_swapchain* out_swapchain) {
- context.swapchain = out_swapchain;
-
- out_swapchain->swapchain_arena = arena_create(malloc(1024), 1024);
-
- vulkan_device_query_swapchain_support(context.device->physical_device, context.surface,
- &context.swapchain_support);
- vulkan_swapchain_support_info swapchain_support = context.swapchain_support;
-
- // TODO: custom swapchain extents VkExtent2D swapchain_extent = { width, height };
-
- VkSurfaceFormatKHR image_format = choose_swapchain_format(&swapchain_support);
- out_swapchain->image_format = image_format;
- VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; // guaranteed to be implemented
- out_swapchain->present_mode = present_mode;
-
- u32 image_count = swapchain_support.capabilities.minImageCount + 1;
- out_swapchain->image_count = image_count;
-
- VkSwapchainCreateInfoKHR swapchain_create_info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
- swapchain_create_info.surface = context.surface;
- swapchain_create_info.minImageCount = image_count;
- swapchain_create_info.imageFormat = image_format.format;
- swapchain_create_info.imageColorSpace = image_format.colorSpace;
- swapchain_create_info.imageExtent = swapchain_support.capabilities.currentExtent;
- swapchain_create_info.imageArrayLayers = 1;
- swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
- swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- swapchain_create_info.queueFamilyIndexCount = 0;
- swapchain_create_info.pQueueFamilyIndices = NULL;
-
- swapchain_create_info.preTransform = swapchain_support.capabilities.currentTransform;
- swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- swapchain_create_info.presentMode = present_mode;
- swapchain_create_info.clipped = VK_TRUE;
- swapchain_create_info.oldSwapchain = VK_NULL_HANDLE;
-
- out_swapchain->extent = swapchain_support.capabilities.currentExtent;
-
- VK_CHECK(vkCreateSwapchainKHR(context.device->logical_device, &swapchain_create_info,
- context.allocator, &out_swapchain->handle));
- TRACE("Vulkan Swapchain created");
-
- // Retrieve Images
- // out_swapchain->images =
- // arena_alloc(&out_swapchain->swapchain_arena, image_count * sizeof(VkImage));
- out_swapchain->images = malloc(image_count * sizeof(VkImage));
- VK_CHECK(vkGetSwapchainImagesKHR(context.device->logical_device, out_swapchain->handle,
- &image_count, out_swapchain->images));
-
- // Create ImageViews
- // TODO: Move this to a separate function
- out_swapchain->image_views = malloc(image_count * sizeof(VkImageView));
- // arena_alloc(&out_swapchain->swapchain_arena, image_count * sizeof(VkImageView));
- for (u32 i = 0; i < image_count; i++) {
- VkImageViewCreateInfo view_create_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
- view_create_info.image = out_swapchain->images[i];
- view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
- view_create_info.format = image_format.format;
- view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
- view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
- view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
- view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
- view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- view_create_info.subresourceRange.baseMipLevel = 0;
- view_create_info.subresourceRange.levelCount = 1;
- view_create_info.subresourceRange.baseArrayLayer = 0;
- view_create_info.subresourceRange.layerCount = 1;
- vkCreateImageView(context.device->logical_device, &view_create_info, context.allocator,
- &out_swapchain->image_views[i]);
- }
-
- return true;
-}
-
-void gpu_swapchain_destroy(gpu_swapchain* swapchain) {
- // Destroy Framebuffers
- DEBUG("Image count %d", swapchain->image_count);
- for (u32 i = 0; i < swapchain->image_count; i++) {
- DEBUG("Framebuffer handle %d", context.swapchain_framebuffers[i]);
- vkDestroyFramebuffer(context.device->logical_device, context.swapchain_framebuffers[i],
- context.allocator);
- }
- for (u32 i = 0; i < swapchain->image_count; i++) {
- vkDestroyImageView(context.device->logical_device, swapchain->image_views[i],
- context.allocator);
- }
- arena_free_all(&swapchain->swapchain_arena);
- vkDestroySwapchainKHR(context.device->logical_device, swapchain->handle, context.allocator);
- TRACE("Vulkan Swapchain destroyed");
-}
-
-static void recreate_swapchain(gpu_swapchain* swapchain) {
- int width = 0, height = 0;
- glfwGetFramebufferSize(context.window, &width, &height);
- while (width == 0 || height == 0) {
- glfwGetFramebufferSize(context.window, &width, &height);
- glfwWaitEvents();
- }
- DEBUG("Recreating swapchain...");
- vkDeviceWaitIdle(context.device->logical_device);
-
- gpu_swapchain_destroy(swapchain);
- gpu_swapchain_create(swapchain);
- create_swapchain_framebuffers();
-}
-
-VkFormat format_from_vertex_attr(vertex_attrib_type attr) {
- switch (attr) {
- case ATTR_F32:
- return VK_FORMAT_R32_SFLOAT;
- case ATTR_U32:
- return VK_FORMAT_R32_UINT;
- case ATTR_I32:
- return VK_FORMAT_R32_SINT;
- case ATTR_F32x2:
- return VK_FORMAT_R32G32_SFLOAT;
- case ATTR_U32x2:
- return VK_FORMAT_R32G32_UINT;
- case ATTR_I32x2:
- return VK_FORMAT_R32G32_UINT;
- case ATTR_F32x3:
- return VK_FORMAT_R32G32B32_SFLOAT;
- case ATTR_U32x3:
- return VK_FORMAT_R32G32B32_UINT;
- case ATTR_I32x3:
- return VK_FORMAT_R32G32B32_SINT;
- case ATTR_F32x4:
- return VK_FORMAT_R32G32B32A32_SFLOAT;
- case ATTR_U32x4:
- return VK_FORMAT_R32G32B32A32_UINT;
- case ATTR_I32x4:
- return VK_FORMAT_R32G32B32A32_SINT;
- }
-}
-
-gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description) {
- TRACE("GPU Graphics Pipeline creation");
- // Allocate
- gpu_pipeline_layout* layout =
- pipeline_layout_pool_alloc(&context.gpu_pools.pipeline_layouts, NULL);
- gpu_pipeline* pipeline = pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL);
-
- // Shaders
- printf("Vertex shader: %s\n", description.vs.filepath.buf);
- printf("Fragment shader: %s\n", description.fs.filepath.buf);
- VkShaderModule vertex_shader = create_shader_module(description.vs.code);
- VkShaderModule fragment_shader = create_shader_module(description.fs.code);
-
- // Vertex
- VkPipelineShaderStageCreateInfo vert_shader_stage_info = {
- VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
- };
- vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
- vert_shader_stage_info.module = vertex_shader;
- vert_shader_stage_info.pName = "main";
- // Fragment
- VkPipelineShaderStageCreateInfo frag_shader_stage_info = {
- VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
- };
- frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
- frag_shader_stage_info.module = fragment_shader;
- frag_shader_stage_info.pName = "main";
-
- VkPipelineShaderStageCreateInfo shader_stages[2] = { vert_shader_stage_info,
- frag_shader_stage_info };
-
- // Attributes
- u32 attr_count = description.vertex_desc.attributes_count;
- printf("N attributes %d\n", attr_count);
- VkVertexInputAttributeDescription attribute_descs[attr_count];
- memset(attribute_descs, 0, attr_count * sizeof(VkVertexInputAttributeDescription));
- u32 offset = 0;
- for (u32 i = 0; i < description.vertex_desc.attributes_count; i++) {
- attribute_descs[i].binding = 0;
- attribute_descs[i].location = i;
- attribute_descs[i].format = format_from_vertex_attr(description.vertex_desc.attributes[i]);
- attribute_descs[i].offset = offset;
- size_t this_offset = vertex_attrib_size(description.vertex_desc.attributes[i]);
- printf("offset total %d this attr %ld\n", offset, this_offset);
- printf("sizeof vertex %ld\n", sizeof(vertex));
- offset += this_offset;
- }
-
- // Vertex input
- // TODO: Generate this from descroiption now
- VkVertexInputBindingDescription binding_desc;
- binding_desc.binding = 0;
- binding_desc.stride = description.vertex_desc.use_full_vertex_size
- ? sizeof(vertex)
- : description.vertex_desc.stride;
- binding_desc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
-
- VkPipelineVertexInputStateCreateInfo vertex_input_info = {
- VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
- };
- vertex_input_info.vertexBindingDescriptionCount = 1;
- vertex_input_info.pVertexBindingDescriptions = &binding_desc;
- vertex_input_info.vertexAttributeDescriptionCount =
- attr_count; // description.vertex_desc.attributes_count;
- vertex_input_info.pVertexAttributeDescriptions = attribute_descs;
-
- // Input Assembly
- VkPipelineInputAssemblyStateCreateInfo input_assembly = {
- VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
- };
- input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
- input_assembly.primitiveRestartEnable = VK_FALSE;
-
- // Viewport
- VkViewport viewport = { .x = 0,
- .y = 0,
- .width = (f32)context.swapchain->extent.width,
- .height = (f32)context.swapchain->extent.height,
- .minDepth = 0.0,
- .maxDepth = 1.0 };
- VkRect2D scissor = { .offset = { .x = 0, .y = 0 }, .extent = context.swapchain->extent };
- VkPipelineViewportStateCreateInfo viewport_state = {
- VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
- };
- viewport_state.viewportCount = 1;
- // viewport_state.pViewports = &viewport;
- viewport_state.scissorCount = 1;
- // viewport_state.pScissors = &scissor;
-
- // Rasterizer
- VkPipelineRasterizationStateCreateInfo rasterizer_create_info = {
- VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
- };
- rasterizer_create_info.depthClampEnable = VK_FALSE;
- rasterizer_create_info.rasterizerDiscardEnable = VK_FALSE;
- rasterizer_create_info.polygonMode =
- description.wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
- rasterizer_create_info.lineWidth = 1.0f;
- rasterizer_create_info.cullMode = VK_CULL_MODE_BACK_BIT;
- rasterizer_create_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
- /* rasterizer_create_info.frontFace = VK_FRONT_FACE_CLOCKWISE; */
- rasterizer_create_info.depthBiasEnable = VK_FALSE;
- rasterizer_create_info.depthBiasConstantFactor = 0.0;
- rasterizer_create_info.depthBiasClamp = 0.0;
- rasterizer_create_info.depthBiasSlopeFactor = 0.0;
-
- // Multisampling
- VkPipelineMultisampleStateCreateInfo ms_create_info = {
- VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
- };
- ms_create_info.sampleShadingEnable = VK_FALSE;
- ms_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
- ms_create_info.minSampleShading = 1.0;
- ms_create_info.pSampleMask = 0;
- ms_create_info.alphaToCoverageEnable = VK_FALSE;
- ms_create_info.alphaToOneEnable = VK_FALSE;
-
- // TODO: Depth and stencil testing
- // VkPipelineDepthStencilStateCreateInfo depth_stencil = {
- // VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
- // };
- // depth_stencil.depthTestEnable = description.depth_test ? VK_TRUE : VK_FALSE;
- // depth_stencil.depthWriteEnable = description.depth_test ? VK_TRUE : VK_FALSE;
- // depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS;
- // depth_stencil.depthBoundsTestEnable = VK_FALSE;
- // depth_stencil.stencilTestEnable = VK_FALSE;
- // depth_stencil.pNext = 0;
-
- // Blending
- VkPipelineColorBlendAttachmentState color_blend_attachment_state;
- color_blend_attachment_state.blendEnable = VK_FALSE;
- color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
- color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
- color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
- color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;
- color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
- VK_COLOR_COMPONENT_G_BIT |
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
-
- VkPipelineColorBlendStateCreateInfo color_blend = {
- VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
- };
- color_blend.logicOpEnable = VK_FALSE;
- color_blend.logicOp = VK_LOGIC_OP_COPY;
- color_blend.attachmentCount = 1;
- color_blend.pAttachments = &color_blend_attachment_state;
-
-// Dynamic state
-#define DYNAMIC_STATE_COUNT 2
- VkDynamicState dynamic_states[DYNAMIC_STATE_COUNT] = {
- VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR,
- };
-
- VkPipelineDynamicStateCreateInfo dynamic_state = {
- VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
- };
- dynamic_state.dynamicStateCount = DYNAMIC_STATE_COUNT;
- dynamic_state.pDynamicStates = dynamic_states;
-
- // Descriptor Set layouts
-
- VkDescriptorSetLayout* desc_set_layouts =
- malloc(description.data_layouts_count * sizeof(VkDescriptorSetLayout));
- pipeline->desc_set_layouts = desc_set_layouts;
- pipeline->desc_set_layouts_count = description.data_layouts_count;
- if (description.data_layouts_count > 0) {
- pipeline->uniform_pointers =
- malloc(description.data_layouts_count * sizeof(desc_set_uniform_buffer));
- } else {
- pipeline->uniform_pointers = NULL;
- }
-
- // assert(description.data_layouts_count == 1);
- printf("data layouts %d\n", description.data_layouts_count);
- for (u32 layout_i = 0; layout_i < description.data_layouts_count; layout_i++) {
- shader_data_layout sdl = description.data_layouts[layout_i].shader_data_get_layout(NULL);
- TRACE("Got shader data layout %d's bindings! . found %d", layout_i, sdl.bindings_count);
-
- VkDescriptorSetLayoutBinding desc_set_bindings[sdl.bindings_count];
-
- // Bindings
- assert(sdl.bindings_count == 2);
- for (u32 binding_j = 0; binding_j < sdl.bindings_count; binding_j++) {
- desc_set_bindings[binding_j].binding = binding_j;
- desc_set_bindings[binding_j].descriptorCount = 1;
- switch (sdl.bindings[binding_j].type) {
- case SHADER_BINDING_BUFFER:
- case SHADER_BINDING_BYTES:
- desc_set_bindings[binding_j].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- desc_set_bindings[binding_j].stageFlags =
- VK_SHADER_STAGE_VERTEX_BIT; // FIXME: dont hardcode
-
- u64 buffer_size = sdl.bindings[binding_j].data.bytes.size;
- VkDeviceSize uniform_buf_size = buffer_size;
- // TODO: Create backing buffer
-
- VkBuffer buffers[MAX_FRAMES_IN_FLIGHT];
- VkDeviceMemory uniform_buf_memorys[MAX_FRAMES_IN_FLIGHT];
- void* uniform_buf_mem_mappings[MAX_FRAMES_IN_FLIGHT];
- // void* s?
- for (size_t frame_i = 0; frame_i < MAX_FRAMES_IN_FLIGHT; frame_i++) {
- buffer_handle uniform_buf_handle =
- gpu_buffer_create(buffer_size, CEL_BUFFER_UNIFORM, CEL_BUFFER_FLAG_CPU, NULL);
-
- gpu_buffer* created_gpu_buffer =
- BUFFER_GET(uniform_buf_handle); // context.buffers[uniform_buf_handle.raw];
- buffers[frame_i] = created_gpu_buffer->handle;
- uniform_buf_memorys[frame_i] = created_gpu_buffer->memory;
- vkMapMemory(context.device->logical_device, uniform_buf_memorys[frame_i], 0,
- uniform_buf_size, 0, &uniform_buf_mem_mappings[frame_i]);
- // now we have a pointer in unifrom_buf_mem_mappings we can write to
- }
-
- desc_set_uniform_buffer uniform_data;
- memcpy(&uniform_data.buffers, &buffers, sizeof(buffers));
- memcpy(&uniform_data.uniform_buf_memorys, &uniform_buf_memorys,
- sizeof(uniform_buf_memorys));
- memcpy(&uniform_data.uniform_buf_mem_mappings, &uniform_buf_mem_mappings,
- sizeof(uniform_buf_mem_mappings));
- uniform_data.size = buffer_size;
-
- pipeline->uniform_pointers[binding_j] = uniform_data;
-
- break;
- case SHADER_BINDING_TEXTURE:
- desc_set_bindings[binding_j].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- desc_set_bindings[binding_j].stageFlags =
- VK_SHADER_STAGE_FRAGMENT_BIT; // FIXME: dont hardcode
- desc_set_bindings[binding_j].pImmutableSamplers = NULL;
-
- break;
- default:
- ERROR_EXIT("Unimplemented binding type!! in backend_vulkan");
- }
- switch (sdl.bindings[binding_j].vis) {
- case VISIBILITY_VERTEX:
- desc_set_bindings[binding_j].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
- break;
- case VISIBILITY_FRAGMENT:
- desc_set_bindings[binding_j].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
- break;
- case VISIBILITY_COMPUTE:
- WARN("Compute is not implemented yet");
- break;
- }
- }
-
- VkDescriptorSetLayoutCreateInfo desc_set_layout_info = {
- VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
- };
- desc_set_layout_info.bindingCount = sdl.bindings_count;
- desc_set_layout_info.pBindings = desc_set_bindings;
-
- VK_CHECK(vkCreateDescriptorSetLayout(context.device->logical_device, &desc_set_layout_info,
- context.allocator, &desc_set_layouts[layout_i]));
- }
- printf("Descriptor set layouts\n");
-
- // Layout
- VkPipelineLayoutCreateInfo pipeline_layout_create_info = {
- VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
- };
- pipeline_layout_create_info.setLayoutCount = description.data_layouts_count;
- pipeline_layout_create_info.pSetLayouts = desc_set_layouts;
- pipeline_layout_create_info.pushConstantRangeCount = 0;
- pipeline_layout_create_info.pPushConstantRanges = NULL;
- VK_CHECK(vkCreatePipelineLayout(context.device->logical_device, &pipeline_layout_create_info,
- context.allocator, &layout->handle));
- pipeline->layout_handle = layout->handle; // keep a copy of the layout on the pipeline object
-
- VkGraphicsPipelineCreateInfo pipeline_create_info = {
- VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
- };
-
- pipeline_create_info.stageCount = 2;
- pipeline_create_info.pStages = shader_stages;
- pipeline_create_info.pVertexInputState = &vertex_input_info;
- pipeline_create_info.pInputAssemblyState = &input_assembly;
-
- pipeline_create_info.pViewportState = &viewport_state;
- pipeline_create_info.pRasterizationState = &rasterizer_create_info;
- pipeline_create_info.pMultisampleState = &ms_create_info;
- pipeline_create_info.pDepthStencilState = NULL; // &depth_stencil;
- pipeline_create_info.pColorBlendState = &color_blend;
- pipeline_create_info.pDynamicState = &dynamic_state;
- pipeline_create_info.pTessellationState = 0;
-
- pipeline_create_info.layout = layout->handle;
-
- pipeline_create_info.renderPass = description.renderpass->handle;
- pipeline_create_info.subpass = 0;
- pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;
- pipeline_create_info.basePipelineIndex = -1;
-
- printf("About to create graphics pipeline\n");
-
- VkResult result =
- vkCreateGraphicsPipelines(context.device->logical_device, VK_NULL_HANDLE, 1,
- &pipeline_create_info, context.allocator, &pipeline->handle);
- if (result != VK_SUCCESS) {
- FATAL("graphics pipeline creation failed. its fked mate");
- ERROR_EXIT("Doomed");
- }
- TRACE("Vulkan Graphics pipeline created");
-
- // once the pipeline has been created we can destroy these
- vkDestroyShaderModule(context.device->logical_device, vertex_shader, context.allocator);
- vkDestroyShaderModule(context.device->logical_device, fragment_shader, context.allocator);
-
- // Framebuffers
- create_swapchain_framebuffers();
- TRACE("Swapchain Framebuffers created");
-
- for (u32 frame_i = 0; frame_i < MAX_FRAMES_IN_FLIGHT; frame_i++) {
- context.main_cmd_bufs[frame_i] = gpu_cmd_encoder_create();
- }
- TRACE("main Command Buffer created");
-
- TRACE("Graphics pipeline created");
- return pipeline;
-}
-
-void gpu_pipeline_destroy(gpu_pipeline* pipeline) {
- vkDestroyPipeline(context.device->logical_device, pipeline->handle, context.allocator);
- vkDestroyPipelineLayout(context.device->logical_device, pipeline->layout_handle,
- context.allocator);
-}
-
-gpu_cmd_encoder* gpu_get_default_cmd_encoder() {
- return &context.main_cmd_bufs[context.current_frame];
-}
-
-gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description) {
- gpu_renderpass* renderpass = renderpass_pool_alloc(&context.gpu_pools.renderpasses, NULL);
-
- // attachments
- u32 attachment_desc_count = 2;
- VkAttachmentDescription attachment_descriptions[2];
-
- // Colour attachment
- VkAttachmentDescription color_attachment;
- color_attachment.format = context.swapchain->image_format.format;
- color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
- color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
- color_attachment.flags = 0;
-
- attachment_descriptions[0] = color_attachment;
-
- VkAttachmentReference color_attachment_reference;
- color_attachment_reference.attachment = 0;
- color_attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
- // Depth attachment
- u32x2 ext = { .x = context.swapchain_support.capabilities.currentExtent.width,
- .y = context.swapchain_support.capabilities.currentExtent.height };
- texture_desc depth_desc = { .extents = ext,
- .format = CEL_TEXTURE_FORMAT_DEPTH_DEFAULT,
- .tex_type = CEL_TEXTURE_TYPE_2D };
- texture_handle depth_texture_handle = gpu_texture_create(depth_desc, true, NULL);
- gpu_texture* depth = TEXTURE_GET(depth_texture_handle);
-
- VkAttachmentDescription depth_attachment;
- depth_attachment.format = // TODO: context->device.depth_format;
- depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
- depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- depth_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- depth_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- depth_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- depth_attachment.flags = 0;
-
- attachment_descriptions[1] = depth_attachment;
-
- VkAttachmentReference depth_attachment_reference;
- depth_attachment_reference.attachment = 1;
- depth_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
- // main subpass
- VkSubpassDescription subpass = { 0 };
- subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpass.colorAttachmentCount = 1;
- subpass.pColorAttachments = &color_attachment_reference;
-
- // sets everything up
- // renderpass dependencies
- VkSubpassDependency dependency;
- dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
- dependency.dstSubpass = 0;
- dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- dependency.srcAccessMask = 0;
- dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- dependency.dstAccessMask =
- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- dependency.dependencyFlags = 0;
-
- // Finally, create the RenderPass
- VkRenderPassCreateInfo render_pass_create_info = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
- render_pass_create_info.attachmentCount = 1;
- render_pass_create_info.pAttachments = &color_attachment;
- render_pass_create_info.subpassCount = 1;
- render_pass_create_info.pSubpasses = &subpass;
- render_pass_create_info.dependencyCount = 1;
- render_pass_create_info.pDependencies = &dependency;
- render_pass_create_info.flags = 0;
- render_pass_create_info.pNext = 0;
-
- VK_CHECK(vkCreateRenderPass(context.device->logical_device, &render_pass_create_info,
- context.allocator, &renderpass->handle));
-
- // HACK
- context.main_renderpass = renderpass->handle;
-
- return renderpass;
-}
-
-gpu_cmd_encoder gpu_cmd_encoder_create() {
- // gpu_cmd_encoder* encoder = malloc(sizeof(gpu_cmd_encoder)); // TODO: fix leaking mem
- gpu_cmd_encoder encoder = { 0 };
-
- VkCommandBufferAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
- allocate_info.commandPool = context.device->pool;
- allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocate_info.commandBufferCount = 1;
- allocate_info.pNext = NULL;
-
- VK_CHECK(vkAllocateCommandBuffers(context.device->logical_device, &allocate_info,
- &encoder.cmd_buffer););
-
- VkDescriptorPoolSize pool_sizes[2];
- // Uniforms pool
- pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- pool_sizes[0].descriptorCount = MAX_FRAMES_IN_FLIGHT * MAX_DESCRIPTOR_SETS;
- // Samplers pool
- pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- pool_sizes[1].descriptorCount = MAX_FRAMES_IN_FLIGHT * MAX_DESCRIPTOR_SETS;
-
- VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
- pool_info.poolSizeCount = 2;
- pool_info.pPoolSizes = pool_sizes;
- pool_info.maxSets = 100;
-
- VK_CHECK(vkCreateDescriptorPool(context.device->logical_device, &pool_info, context.allocator,
- &encoder.descriptor_pool));
-
- return encoder;
-}
-void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder) {
- vkFreeCommandBuffers(context.device->logical_device, context.device->pool, 1,
- &encoder->cmd_buffer);
-}
-
-void gpu_cmd_encoder_begin(gpu_cmd_encoder encoder) {
- VK_CHECK(vkResetDescriptorPool(context.device->logical_device, encoder.descriptor_pool, 0));
-
- VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
- VK_CHECK(vkBeginCommandBuffer(encoder.cmd_buffer, &begin_info));
-}
-
-void gpu_cmd_encoder_begin_render(gpu_cmd_encoder* encoder, gpu_renderpass* renderpass) {
- VkRenderPassBeginInfo begin_info = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
- begin_info.renderPass = renderpass->handle;
- /* printf("Current img: %d Current frame %d\n", context.current_img_index, context.current_frame);
- */
- begin_info.framebuffer = context.swapchain_framebuffers[context.current_img_index];
- begin_info.renderArea.offset = (VkOffset2D){ 0, 0 };
- begin_info.renderArea.extent = context.swapchain->extent;
-
- // VkClearValue clear_values[2];
- VkClearValue clear_color = { { { 0.02f, 0.02f, 0.02f, 1.0f } } };
- // clear_values[1].depthStencil.depth = renderpass->depth;
- // clear_values[1].depthStencil.stencil = renderpass->stencil;
-
- begin_info.clearValueCount = 1;
- begin_info.pClearValues = &clear_color;
-
- vkCmdBeginRenderPass(encoder->cmd_buffer, &begin_info, VK_SUBPASS_CONTENTS_INLINE);
- // command_buffer->state = COMMAND_BUFFER_STATE_IN_RENDER_PASS;
-}
-
-void gpu_cmd_encoder_end_render(gpu_cmd_encoder* encoder) {
- vkCmdEndRenderPass(encoder->cmd_buffer);
-}
-
-gpu_cmd_buffer gpu_cmd_encoder_finish(gpu_cmd_encoder* encoder) {
- vkEndCommandBuffer(encoder->cmd_buffer);
-
- // TEMP: submit
- return (gpu_cmd_buffer){ .cmd_buffer = encoder->cmd_buffer };
-}
-
-// --- Binding
-void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipeline* pipeline) {
- vkCmdBindPipeline(encoder->cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
- encoder->pipeline = pipeline;
-}
-
-void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {
- arena tmp = arena_create(malloc(1024), 1024);
-
- assert(data->data != NULL);
-
- // Update the local buffer
- desc_set_uniform_buffer ubo = encoder->pipeline->uniform_pointers[group];
- memcpy(ubo.uniform_buf_mem_mappings[context.current_frame], data->data, ubo.size);
-
- VkDescriptorSetAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
- alloc_info.descriptorPool = encoder->descriptor_pool;
- alloc_info.descriptorSetCount = 1;
- alloc_info.pSetLayouts = &encoder->pipeline->desc_set_layouts[group];
-
- shader_data_layout sdl = data->shader_data_get_layout(data->data);
- size_t binding_count = sdl.bindings_count;
- assert(binding_count == 2);
-
- VkDescriptorSet sets[0];
- VK_CHECK(vkAllocateDescriptorSets(context.device->logical_device, &alloc_info, sets));
- // FIXME: hardcoded
- VkDescriptorSet_darray_push(context.free_set_queue, sets[0]);
- /* VkDescriptorSet_darray_push(context.free_set_queue, sets[1]); */
-
- VkWriteDescriptorSet write_sets[binding_count];
- memset(&write_sets, 0, binding_count * sizeof(VkWriteDescriptorSet));
-
- for (u32 i = 0; i < sdl.bindings_count; i++) {
- shader_binding binding = sdl.bindings[i];
-
- if (binding.type == SHADER_BINDING_BUFFER || binding.type == SHADER_BINDING_BYTES) {
- VkDescriptorBufferInfo* buffer_info = arena_alloc(&tmp, sizeof(VkDescriptorBufferInfo));
- buffer_info->buffer = ubo.buffers[context.current_frame];
- buffer_info->offset = 0;
- buffer_info->range = binding.data.bytes.size;
-
- write_sets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_sets[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- write_sets[i].descriptorCount = 1;
- write_sets[i].dstSet = sets[0];
- write_sets[i].dstBinding = i;
- write_sets[i].dstArrayElement = 0;
- write_sets[i].pBufferInfo = buffer_info;
- } else if (binding.type == SHADER_BINDING_TEXTURE) {
- gpu_texture* texture = TEXTURE_GET(binding.data.texture.handle);
- VkDescriptorImageInfo* image_info = arena_alloc(&tmp, sizeof(VkDescriptorImageInfo));
- image_info->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- image_info->imageView = texture->view;
- image_info->sampler = texture->sampler;
-
- write_sets[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_sets[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- write_sets[i].descriptorCount = 1;
- write_sets[i].dstSet = sets[0];
- write_sets[i].dstBinding = i;
- write_sets[i].dstArrayElement = 0;
- write_sets[i].pImageInfo = image_info;
- } else {
- WARN("Unknown binding");
- }
- }
-
- // Update
- vkUpdateDescriptorSets(context.device->logical_device, binding_count, write_sets, 0, NULL);
-
- // Bind
- vkCmdBindDescriptorSets(encoder->cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
- encoder->pipeline->layout_handle, 0, 1, sets, 0, NULL);
-
- arena_free_storage(&tmp);
-}
-
-void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
- gpu_buffer* buffer = BUFFER_GET(buf); // context.buffers[buf.raw];
- VkBuffer vbs[] = { buffer->handle };
- VkDeviceSize offsets[] = { 0 };
- vkCmdBindVertexBuffers(encoder->cmd_buffer, 0, 1, vbs, offsets);
-}
-
-void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
- gpu_buffer* buffer = BUFFER_GET(buf); // context.buffers[buf.raw];
- vkCmdBindIndexBuffer(encoder->cmd_buffer, buffer->handle, 0, VK_INDEX_TYPE_UINT32);
-}
-
-// TEMP
-void encode_set_default_settings(gpu_cmd_encoder* encoder) {
- VkViewport viewport = { 0 };
- viewport.x = 0.0f;
- viewport.y = 0.0f;
- viewport.width = context.swapchain->extent.width;
- viewport.height = context.swapchain->extent.height;
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- vkCmdSetViewport(encoder->cmd_buffer, 0, 1, &viewport);
-
- VkRect2D scissor = { 0 };
- scissor.offset = (VkOffset2D){ 0, 0 };
- scissor.extent = context.swapchain->extent;
- vkCmdSetScissor(encoder->cmd_buffer, 0, 1, &scissor);
-}
-
-// --- Drawing
-
-bool gpu_backend_begin_frame() {
- u32 current_frame = context.current_frame;
- vkWaitForFences(context.device->logical_device, 1, &context.in_flight_fences[current_frame],
- VK_TRUE, UINT64_MAX);
-
- u32 image_index;
- VkResult result = vkAcquireNextImageKHR(
- context.device->logical_device, context.swapchain->handle, UINT64_MAX,
- context.image_available_semaphores[current_frame], VK_NULL_HANDLE, &image_index);
- if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || context.is_resizing) {
- ERROR("Acquire next image failure. recreate swapchain");
- context.is_resizing = false;
- recreate_swapchain(context.swapchain);
- return false;
- } else if (result != VK_SUCCESS) {
- ERROR_EXIT("failed to acquire swapchain image");
- }
-
- vkResetFences(context.device->logical_device, 1, &context.in_flight_fences[current_frame]);
-
- context.current_img_index = image_index;
- VK_CHECK(vkResetCommandBuffer(context.main_cmd_bufs[current_frame].cmd_buffer, 0));
- return true;
-}
-
-void gpu_temp_draw(size_t n_indices) {
- gpu_cmd_encoder* encoder = gpu_get_default_cmd_encoder(); // &context.main_cmd_buf;
- /* vkCmdDraw(encoder->cmd_buffer, n_verts, 1, 0, 0); */
- vkCmdDrawIndexed(encoder->cmd_buffer, n_indices, 1, 0, 0, 0);
-}
-
-void gpu_backend_end_frame() {
- VkPresentInfoKHR present_info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
- present_info.waitSemaphoreCount = 1;
- present_info.pWaitSemaphores = &context.render_finished_semaphores[context.current_frame];
-
- VkSwapchainKHR swapchains[] = { context.swapchain->handle };
- present_info.swapchainCount = 1;
- present_info.pSwapchains = swapchains;
- present_info.pImageIndices = &context.current_img_index;
-
- VkResult result = vkQueuePresentKHR(context.device->present_queue, &present_info);
- if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
- ERROR("Queue present error. recreate swapchain");
- recreate_swapchain(context.swapchain);
- return;
- } else if (result != VK_SUCCESS) {
- ERROR_EXIT("failed to present swapchain image");
- }
- context.current_frame = (context.current_frame + 1) % MAX_FRAMES_IN_FLIGHT;
-
- /* vkDeviceWaitIdle(context.device->logical_device); */
-}
-
-// TODO: Move into better order in file
-void gpu_queue_submit(gpu_cmd_buffer* buffer) {
- VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
-
- // Specify semaphore to wait on
- VkSemaphore wait_semaphores[] = { context.image_available_semaphores[context.current_frame] };
- VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
-
- submit_info.waitSemaphoreCount = 1;
- submit_info.pWaitSemaphores = wait_semaphores;
- submit_info.pWaitDstStageMask = wait_stages;
-
- // Specify semaphore to signal when finished executing buffer
- VkSemaphore signal_semaphores[] = { context.render_finished_semaphores[context.current_frame] };
- submit_info.signalSemaphoreCount = 1;
- submit_info.pSignalSemaphores = signal_semaphores;
-
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &buffer->cmd_buffer;
-
- VK_CHECK(vkQueueSubmit(context.device->graphics_queue, 1, &submit_info,
- context.in_flight_fences[context.current_frame]));
-}
-
-inline void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count) {
- vkCmdDrawIndexed(encoder->cmd_buffer, index_count, 1, 0, 0, 0);
-}
-
-bool select_physical_device(gpu_device* out_device) {
- u32 physical_device_count = 0;
- VK_CHECK(vkEnumeratePhysicalDevices(context.instance, &physical_device_count, 0));
- if (physical_device_count == 0) {
- FATAL("No devices that support vulkan were found");
- return false;
- }
- TRACE("Number of devices found %d", physical_device_count);
-
- VkPhysicalDevice* physical_devices =
- arena_alloc(&context.temp_arena, physical_device_count * sizeof(VkPhysicalDevice));
- VK_CHECK(vkEnumeratePhysicalDevices(context.instance, &physical_device_count, physical_devices));
-
- bool found = false;
- for (u32 device_i = 0; device_i < physical_device_count; device_i++) {
- if (is_physical_device_suitable(physical_devices[device_i])) {
- out_device->physical_device = physical_devices[device_i];
- found = true;
- break;
- }
- }
-
- if (!found) {
- FATAL("Couldn't find a suitable physical device");
- return false;
- }
-
- vkGetPhysicalDeviceProperties(out_device->physical_device, &out_device->properties);
- vkGetPhysicalDeviceFeatures(out_device->physical_device, &out_device->features);
- vkGetPhysicalDeviceMemoryProperties(out_device->physical_device, &out_device->memory);
-
- return true;
-}
-
-bool is_physical_device_suitable(VkPhysicalDevice device) {
- VkPhysicalDeviceProperties properties;
- vkGetPhysicalDeviceProperties(device, &properties);
-
- VkPhysicalDeviceFeatures features;
- vkGetPhysicalDeviceFeatures(device, &features);
-
- VkPhysicalDeviceMemoryProperties memory;
- vkGetPhysicalDeviceMemoryProperties(device, &memory);
-
- // TODO: Check against these device properties
-
- queue_family_indices indices = find_queue_families(device);
-
- vulkan_device_query_swapchain_support(device, context.surface, &context.swapchain_support);
-
- return indices.has_graphics && indices.has_present && context.swapchain_support.mode_count > 0 &&
- context.swapchain_support.format_count > 0;
-}
-
-queue_family_indices find_queue_families(VkPhysicalDevice device) {
- queue_family_indices indices = { 0 };
-
- u32 queue_family_count = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, 0);
-
- VkQueueFamilyProperties* queue_families =
- arena_alloc(&context.temp_arena, queue_family_count * sizeof(VkQueueFamilyProperties));
- vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families);
-
- for (u32 q_fam_i = 0; q_fam_i < queue_family_count; q_fam_i++) {
- // Graphics queue
- if (queue_families[q_fam_i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
- indices.graphics_family_index = q_fam_i;
- indices.has_graphics = true;
- }
-
- VkBool32 present_support = false;
- vkGetPhysicalDeviceSurfaceSupportKHR(device, q_fam_i, context.surface, &present_support);
- if (present_support && !indices.has_present) {
- indices.present_family_index = q_fam_i;
- indices.has_present = true;
- }
- }
-
- return indices;
-}
-
-bool create_logical_device(gpu_device* out_device) {
- queue_family_indices indices = find_queue_families(out_device->physical_device);
- INFO(" %s | %s | %s | %s | %s", bool_str(indices.has_graphics), bool_str(indices.has_present),
- bool_str(indices.has_compute), bool_str(indices.has_transfer),
- out_device->properties.deviceName);
- TRACE("Graphics Family queue index: %d", indices.graphics_family_index);
- TRACE("Present Family queue index: %d", indices.present_family_index);
- TRACE("Compute Family queue index: %d", indices.compute_family_index);
- TRACE("Transfer Family queue index: %d", indices.transfer_family_index);
-
- // Queues
- f32 prio_one = 1.0;
- VkDeviceQueueCreateInfo queue_create_infos[1] = { 0 };
- queue_create_infos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_create_infos[0].queueFamilyIndex = indices.graphics_family_index;
- queue_create_infos[0].queueCount = 1;
- queue_create_infos[0].pQueuePriorities = &prio_one;
- queue_create_infos[0].flags = 0;
- queue_create_infos[0].pNext = 0;
-
- // queue_create_infos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- // queue_create_infos[1].queueFamilyIndex = indices.present_family_index;
- // queue_create_infos[1].queueCount = 1;
- // queue_create_infos[1].pQueuePriorities = &prio_one;
- // queue_create_infos[1].flags = 0;
- // queue_create_infos[1].pNext = 0;
-
- // Features
- VkPhysicalDeviceFeatures device_features = { 0 };
- device_features.samplerAnisotropy = VK_TRUE; // request anistrophy
-
- // Device itself
- VkDeviceCreateInfo device_create_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
- device_create_info.queueCreateInfoCount = 1;
- device_create_info.pQueueCreateInfos = queue_create_infos;
- device_create_info.pEnabledFeatures = &device_features;
- device_create_info.enabledExtensionCount = 1;
- const char* extension_names = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
- device_create_info.ppEnabledExtensionNames = &extension_names;
-
- // deprecated
- device_create_info.enabledLayerCount = 0;
- device_create_info.ppEnabledLayerNames = 0;
-
- VkResult result = vkCreateDevice(context.device->physical_device, &device_create_info,
- context.allocator, &context.device->logical_device);
- if (result != VK_SUCCESS) {
- printf("error creating logical device with status %u\n", result);
- ERROR_EXIT("Unable to create vulkan logical device. Exiting..");
- }
- TRACE("Logical device created");
-
- context.device->queue_family_indicies = indices;
-
- // Retrieve queue handles
- vkGetDeviceQueue(context.device->logical_device, indices.graphics_family_index, 0,
- &context.device->graphics_queue);
- vkGetDeviceQueue(context.device->logical_device, indices.present_family_index, 0,
- &context.device->present_queue);
-
- return true;
-}
-
-VkShaderModule create_shader_module(str8 spirv) {
- VkShaderModuleCreateInfo create_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };
- create_info.codeSize = spirv.len;
- create_info.pCode = (uint32_t*)spirv.buf;
-
- VkShaderModule shader_module;
- VK_CHECK(vkCreateShaderModule(context.device->logical_device, &create_info, context.allocator,
- &shader_module));
-
- return shader_module;
-}
-
-void create_descriptor_pools() {}
-
-void create_swapchain_framebuffers() {
- WARN("Recreating framebuffers...");
- u32 image_count = context.swapchain->image_count;
- context.swapchain_framebuffers =
- arena_alloc(&context.swapchain->swapchain_arena, image_count * sizeof(VkFramebuffer));
- for (u32 i = 0; i < image_count; i++) {
- VkImageView attachments[1] = { context.swapchain->image_views[i] };
-
- VkFramebufferCreateInfo framebuffer_create_info = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
- framebuffer_create_info.attachmentCount = 1;
- framebuffer_create_info.pAttachments = attachments;
-
- framebuffer_create_info.renderPass =
- context.main_renderpass; // TODO: description.renderpass->handle;
- framebuffer_create_info.width = context.swapchain->extent.width;
- framebuffer_create_info.height = context.swapchain->extent.height;
- framebuffer_create_info.layers = 1;
-
- VK_CHECK(vkCreateFramebuffer(context.device->logical_device, &framebuffer_create_info,
- context.allocator, &context.swapchain_framebuffers[i]));
- }
-}
-
-void create_sync_objects() {
- VkSemaphoreCreateInfo semaphore_info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
- VkFenceCreateInfo fence_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
- fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
-
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- VK_CHECK(vkCreateSemaphore(context.device->logical_device, &semaphore_info, context.allocator,
- &context.image_available_semaphores[i]););
- VK_CHECK(vkCreateSemaphore(context.device->logical_device, &semaphore_info, context.allocator,
- &context.render_finished_semaphores[i]););
-
- VK_CHECK(vkCreateFence(context.device->logical_device, &fence_info, context.allocator,
- &context.in_flight_fences[i]));
- }
-}
-
-static i32 find_memory_index(u32 type_filter, u32 property_flags) {
- VkPhysicalDeviceMemoryProperties memory_properties;
- vkGetPhysicalDeviceMemoryProperties(context.device->physical_device, &memory_properties);
-
- for (u32 i = 0; i < memory_properties.memoryTypeCount; ++i) {
- // Check each memory type to see if its bit is set to 1.
- if (type_filter & (1 << i) &&
- (memory_properties.memoryTypes[i].propertyFlags & property_flags) == property_flags) {
- return i;
- }
- }
-
- WARN("Unable to find suitable memory type!");
- return -1;
-}
-
-buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags,
- const void* data) {
- VkBufferCreateInfo buffer_info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
- buffer_info.size = size;
- buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-
- switch (buf_type) {
- case CEL_BUFFER_DEFAULT:
- buffer_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
- break;
- case CEL_BUFFER_VERTEX:
- buffer_info.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
- break;
- case CEL_BUFFER_INDEX:
- buffer_info.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
- break;
- case CEL_BUFFER_UNIFORM:
- buffer_info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
- break;
- case CEL_BUFFER_COUNT:
- WARN("Incorrect gpu_buffer_type provided. using default");
- break;
- }
-
- buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
- // "allocating" the cpu-side buffer struct
- /* gpu_buffer buffer; */
- /* buffer.size = size; */
- buffer_handle handle;
- gpu_buffer* buffer = buffer_pool_alloc(&context.resource_pools->buffers, &handle);
- buffer->size = size;
-
- VK_CHECK(vkCreateBuffer(context.device->logical_device, &buffer_info, context.allocator,
- &buffer->handle));
-
- VkMemoryRequirements requirements;
- vkGetBufferMemoryRequirements(context.device->logical_device, buffer->handle, &requirements);
-
- // Just make them always need all of them for now
- i32 memory_index =
- find_memory_index(requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-
- // Allocate the actual VRAM
- VkMemoryAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
- allocate_info.allocationSize = requirements.size;
- allocate_info.memoryTypeIndex = (u32)memory_index;
-
- vkAllocateMemory(context.device->logical_device, &allocate_info, context.allocator,
- &buffer->memory);
- vkBindBufferMemory(context.device->logical_device, buffer->handle, buffer->memory, 0);
-
- /* Now there are two options:
- * 1. create CPU-accessible memory -> map memory -> memcpy -> unmap
- * 2. use a staging buffer thats CPU-accessible and copy its contents to a
- * GPU-only buffer
- */
-
- /* context.buffers[context.buffer_count] = buffer; */
- /* context.buffer_count++; */
-
- if (data) {
- TRACE("Upload data as part of buffer creation");
- if (flags & CEL_BUFFER_FLAG_CPU) {
- // map memory -> copy data in -> unmap memory
- buffer_upload_bytes(handle, (bytebuffer){ .buf = (u8*)data, .size = size }, 0, size);
- } else if (flags & CEL_BUFFER_FLAG_GPU) {
- TRACE("Uploading data to buffer using staging buffer");
- // Create a staging buffer
- buffer_handle staging = gpu_buffer_create(size, buf_type, CEL_BUFFER_FLAG_CPU, NULL);
-
- // Copy data into it
- buffer_upload_bytes(staging, (bytebuffer){ .buf = (u8*)data, .size = size }, 0, size);
-
- // Enqueue a copy from the staging buffer into the DEVICE_LOCAL buffer
- gpu_cmd_encoder temp_encoder = gpu_cmd_encoder_create();
- gpu_cmd_encoder_begin(temp_encoder);
- encode_buffer_copy(&temp_encoder, staging, 0, handle, 0, size);
- gpu_cmd_buffer copy_cmd_buffer = gpu_cmd_encoder_finish(&temp_encoder);
-
- VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &temp_encoder.cmd_buffer;
- vkQueueSubmit(context.device->graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
-
- // Cleanup
- vkQueueWaitIdle(context.device->graphics_queue);
- gpu_cmd_encoder_destroy(&temp_encoder);
- gpu_buffer_destroy(staging);
- }
- }
-
- return handle;
-}
-
-void gpu_buffer_destroy(buffer_handle buffer) {
- gpu_buffer* b = buffer_pool_get(&context.resource_pools->buffers, buffer);
- vkDestroyBuffer(context.device->logical_device, b->handle, context.allocator);
- vkFreeMemory(context.device->logical_device, b->memory, context.allocator);
- buffer_pool_dealloc(&context.resource_pools->buffers, buffer);
-}
-
-// Upload data to a
-void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size) {
- gpu_buffer* buffer = buffer_pool_get(&context.resource_pools->buffers, gpu_buf);
- void* data_ptr;
- vkMapMemory(context.device->logical_device, buffer->memory, 0, size, 0, &data_ptr);
- DEBUG("Uploading %d bytes to buffer", size);
- memcpy(data_ptr, cpu_buf.buf, size);
- vkUnmapMemory(context.device->logical_device, buffer->memory);
-}
-
-void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset,
- buffer_handle dst, u64 dst_offset, u64 copy_size) {
- VkBufferCopy copy_region;
- copy_region.srcOffset = src_offset;
- copy_region.dstOffset = dst_offset;
- copy_region.size = copy_size;
-
- gpu_buffer* src_buf = buffer_pool_get(&context.resource_pools->buffers, src);
- gpu_buffer* dst_buf = buffer_pool_get(&context.resource_pools->buffers, dst);
- vkCmdCopyBuffer(encoder->cmd_buffer, src_buf->handle, dst_buf->handle, 1, &copy_region);
-}
-
-// one-shot command buffers
-VkCommandBuffer vulkan_command_buffer_create_oneshot() {
- VkCommandBufferAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
- alloc_info.commandPool = context.device->pool;
- alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- alloc_info.commandBufferCount = 1;
- alloc_info.pNext = 0;
-
- VkCommandBuffer cmd_buffer;
- vkAllocateCommandBuffers(context.device->logical_device, &alloc_info, &cmd_buffer);
-
- VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
- begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
-
- vkBeginCommandBuffer(cmd_buffer, &begin_info);
-
- return cmd_buffer;
-}
-
-void vulkan_command_buffer_finish_oneshot(VkCommandBuffer cmd_buffer) {
- VK_CHECK(vkEndCommandBuffer(cmd_buffer));
-
- // submit to queue
- VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &cmd_buffer;
- VK_CHECK(vkQueueSubmit(context.device->graphics_queue, 1, &submit_info, 0));
- VK_CHECK(vkQueueWaitIdle(context.device->graphics_queue));
-
- vkFreeCommandBuffers(context.device->logical_device, context.device->pool, 1, &cmd_buffer);
-}
-
-void copy_buffer_to_buffer_oneshot(buffer_handle src, u64 src_offset, buffer_handle dst,
- u64 dst_offset, u64 copy_size) {
- VkBufferCopy copy_region;
- copy_region.srcOffset = src_offset;
- copy_region.dstOffset = dst_offset;
- copy_region.size = copy_size;
-
- gpu_buffer* src_buf = buffer_pool_get(&context.resource_pools->buffers, src);
- gpu_buffer* dst_buf = buffer_pool_get(&context.resource_pools->buffers, dst);
- VkCommandBuffer temp_cmd_buffer = vulkan_command_buffer_create_oneshot();
- vkCmdCopyBuffer(temp_cmd_buffer, src_buf->handle, dst_buf->handle, 1, &copy_region);
- vulkan_command_buffer_finish_oneshot(temp_cmd_buffer);
-}
-
-void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst) {
- gpu_buffer* src_buf = buffer_pool_get(&context.resource_pools->buffers, src);
- gpu_texture* dst_tex = texture_pool_get(&context.resource_pools->textures, dst);
-
- VkCommandBuffer temp_cmd_buffer = vulkan_command_buffer_create_oneshot();
-
- VkBufferImageCopy region;
- region.bufferOffset = 0;
- region.bufferRowLength = 0;
- region.bufferImageHeight = 0;
- region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.imageSubresource.mipLevel = 0;
- region.imageSubresource.baseArrayLayer = 0;
- region.imageSubresource.layerCount = 1;
- printf("Image details width: %d height %d\n", dst_tex->desc.extents.x, dst_tex->desc.extents.y);
- region.imageOffset.x = 0;
- region.imageOffset.y = 0;
- region.imageOffset.z = 0;
- region.imageExtent.width = dst_tex->desc.extents.x;
- region.imageExtent.height = dst_tex->desc.extents.y;
- region.imageExtent.depth = 1;
-
- vkCmdCopyBufferToImage(temp_cmd_buffer, src_buf->handle, dst_tex->handle,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
-
- vulkan_command_buffer_finish_oneshot(temp_cmd_buffer);
-}
-
-VkImage vulkan_image_create(u32x2 dimensions, VkImageType image_type, VkFormat format,
- VkImageUsageFlags usage) {
- VkImage image;
-
- VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
- image_create_info.imageType = VK_IMAGE_TYPE_2D;
- image_create_info.extent.width = dimensions.x;
- image_create_info.extent.height = dimensions.y;
- image_create_info.extent.depth = 1;
- image_create_info.mipLevels = 1;
- image_create_info.arrayLayers = 1;
- image_create_info.format = format;
- image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
- image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- image_create_info.usage = usage; // VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
- image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
-
- VK_CHECK(
- vkCreateImage(context.device->logical_device, &image_create_info, context.allocator, &image));
-
- return image;
-}
-
-texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) {
- VkDeviceSize image_size = desc.extents.x * desc.extents.y * 4;
- // FIXME: handle this properly
- VkFormat format = desc.format == CEL_TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM ? VK_FORMAT_R8G8B8A8_SRGB
- : VK_FORMAT_D32_SFLOAT;
-
- VkImage image; // vulkan_image_create(desc.extents, VK_IMAGE_TYPE_2D, format,
- // VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
- VkDeviceMemory image_memory;
-
- VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
- image_create_info.imageType = VK_IMAGE_TYPE_2D;
- image_create_info.extent.width = desc.extents.x;
- image_create_info.extent.height = desc.extents.y;
- image_create_info.extent.depth = 1;
- image_create_info.mipLevels = 1;
- image_create_info.arrayLayers = 1;
- image_create_info.format = format;
- image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
- image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
- if (format == VK_FORMAT_D32_SFLOAT) {
- image_create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
- }
- image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
-
- VK_CHECK(
- vkCreateImage(context.device->logical_device, &image_create_info, context.allocator, &image));
-
- VkMemoryRequirements memory_reqs;
- vkGetImageMemoryRequirements(context.device->logical_device, image, &memory_reqs);
-
- VkMemoryAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
- alloc_info.allocationSize = memory_reqs.size;
- alloc_info.memoryTypeIndex =
- find_memory_index(memory_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
- vkAllocateMemory(context.device->logical_device, &alloc_info, context.allocator, &image_memory);
-
- vkBindImageMemory(context.device->logical_device, image, image_memory, 0);
-
- texture_handle handle;
- gpu_texture* texture = texture_pool_alloc(&context.resource_pools->textures, &handle);
- DEBUG("Allocated texture with handle %d", handle.raw);
- texture->handle = image;
- texture->debug_label = "Test Texture";
- texture->desc = desc;
- texture->memory = image_memory;
- texture->size = image_size;
-
- if (data) {
- TRACE("Uploading pixel data to texture using staging buffer");
- // Create a staging buffer
- buffer_handle staging =
- gpu_buffer_create(image_size, CEL_BUFFER_DEFAULT, CEL_BUFFER_FLAG_CPU, NULL);
- // Copy data into it
- vulkan_transition_image_layout(texture, format, VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- buffer_upload_bytes(staging, (bytebuffer){ .buf = (u8*)data, .size = image_size }, 0,
- image_size);
- copy_buffer_to_image_oneshot(staging, handle);
- vulkan_transition_image_layout(texture, format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-
- gpu_buffer_destroy(staging);
- }
-
- // Texture View
- if (create_view) {
- VkImageViewCreateInfo view_create_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
- view_create_info.image = image;
- view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
- view_create_info.format = format;
- view_create_info.subresourceRange.aspectMask =
- format == VK_FORMAT_D32_SFLOAT ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
-
- view_create_info.subresourceRange.baseMipLevel = 0;
- view_create_info.subresourceRange.levelCount = 1;
- view_create_info.subresourceRange.baseArrayLayer = 0;
- view_create_info.subresourceRange.layerCount = 1;
-
- VK_CHECK(vkCreateImageView(context.device->logical_device, &view_create_info, context.allocator,
- &texture->view));
- }
-
- // Sampler
- VkSamplerCreateInfo sampler_info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
- sampler_info.magFilter = VK_FILTER_LINEAR;
- sampler_info.minFilter = VK_FILTER_LINEAR;
- sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- sampler_info.anisotropyEnable = VK_TRUE;
- sampler_info.maxAnisotropy = 16;
- sampler_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
- sampler_info.unnormalizedCoordinates = VK_FALSE;
- sampler_info.compareEnable = VK_FALSE;
- sampler_info.compareOp = VK_COMPARE_OP_ALWAYS;
- sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
- sampler_info.mipLodBias = 0.0;
- sampler_info.minLod = 0.0;
- sampler_info.maxLod = 0.0;
-
- VkResult res = vkCreateSampler(context.device->logical_device, &sampler_info, context.allocator,
- &texture->sampler);
- if (res != VK_SUCCESS) {
- ERROR("Error creating texture sampler for image %s", texture->debug_label);
- exit(1);
- }
-
- return handle;
-}
-
-void vulkan_transition_image_layout(gpu_texture* texture, VkFormat format, VkImageLayout old_layout,
- VkImageLayout new_layout) {
- VkCommandBuffer temp_cmd_buffer = vulkan_command_buffer_create_oneshot();
-
- VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
- barrier.oldLayout = old_layout;
- barrier.newLayout = new_layout;
- barrier.srcQueueFamilyIndex = context.device->queue_family_indicies.graphics_family_index;
- barrier.dstQueueFamilyIndex = context.device->queue_family_indicies.graphics_family_index;
- barrier.image = texture->handle;
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- barrier.subresourceRange.baseMipLevel = 0;
- barrier.subresourceRange.levelCount = 1;
- barrier.subresourceRange.baseArrayLayer = 0;
- barrier.subresourceRange.layerCount = 1;
- barrier.srcAccessMask = 0; // TODO
- barrier.dstAccessMask = 0; // TODO
-
- VkPipelineStageFlags source_stage;
- VkPipelineStageFlags dest_stage;
-
- if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED &&
- new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-
- source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- dest_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
-
- } else if (old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
- new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- dest_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- } else {
- FATAL("Unsupported image layout transition");
- return;
- }
-
- vkCmdPipelineBarrier(temp_cmd_buffer, source_stage, dest_stage, 0, 0, 0, 0, 0, 1, &barrier);
-
- vulkan_command_buffer_finish_oneshot(temp_cmd_buffer);
-}
-
-/* TYPED_POOL(gpu_buffer, buffer); */
-/* TYPED_POOL(gpu_texture, texture); */
-
-/* void resource_pools_init(arena* a, struct resource_pools* res_pools) { */
-/* buffer_pool buf_pool = buffer_pool_create(a, MAX_BUFFERS, sizeof(gpu_buffer)); */
-/* res_pools->buffers = buf_pool; */
-/* texture_pool tex_pool = texture_pool_create(a, MAX_TEXTURES, sizeof(gpu_texture)); */
-/* res_pools->textures = tex_pool; */
-
-/* context.resource_pools = res_pools; */
-/* } */
-
-#endif
diff --git a/src/render/archive/backends/vulkan/backend_vulkan.h b/src/render/archive/backends/vulkan/backend_vulkan.h
deleted file mode 100644
index 6ca0bb5..0000000
--- a/src/render/archive/backends/vulkan/backend_vulkan.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma once
-#include "defines.h"
-#if defined(CEL_REND_BACKEND_VULKAN)
-#include <vulkan/vk_platform.h>
-#include <vulkan/vulkan.h>
-#include <vulkan/vulkan_core.h>
-
-#include "mem.h"
-#include "ral.h"
-#include "ral_types.h"
-
-#define MAX_FRAMES_IN_FLIGHT 2
-#define GPU_SWAPCHAIN_IMG_COUNT 2
-
-/*
-Conventions:
- - Place the 'handle' as the first field of a struct
- - Vulkan specific data goes at the top, followed by our internal data
-*/
-
-typedef struct queue_family_indices {
- u32 graphics_family_index;
- u32 present_family_index;
- u32 compute_family_index;
- u32 transfer_family_index;
- bool has_graphics;
- bool has_present;
- bool has_compute;
- bool has_transfer;
-} queue_family_indices;
-
-// typedef struct vulkan_framebuffer {
-// } vulkan_framebuffer;
-
-typedef struct gpu_swapchain {
- VkSwapchainKHR handle;
- arena swapchain_arena;
- VkExtent2D extent;
- u32x2 dimensions;
- VkSurfaceFormatKHR image_format;
- VkPresentModeKHR present_mode;
- u32 image_count;
- VkImage* images;
- VkImageView* image_views;
-} gpu_swapchain;
-
-typedef struct gpu_device {
- // In Vulkan we store both physical and logical device here
- VkPhysicalDevice physical_device;
- VkDevice logical_device;
- VkPhysicalDeviceProperties properties;
- VkPhysicalDeviceFeatures features;
- VkPhysicalDeviceMemoryProperties memory;
- queue_family_indices queue_family_indicies;
- VkQueue graphics_queue;
- VkQueue present_queue;
- VkQueue compute_queue;
- VkQueue transfer_queue;
- VkCommandPool pool;
-} gpu_device;
-
-typedef struct gpu_pipeline_layout {
- VkPipelineLayout handle;
-} gpu_pipeline_layout;
-
-typedef struct desc_set_uniform_buffer {
- VkBuffer buffers[MAX_FRAMES_IN_FLIGHT];
- VkDeviceMemory uniform_buf_memorys[MAX_FRAMES_IN_FLIGHT];
- void* uniform_buf_mem_mappings[MAX_FRAMES_IN_FLIGHT];
- size_t size;
-} desc_set_uniform_buffer;
-
-typedef struct gpu_pipeline {
- VkPipeline handle;
- VkPipelineLayout layout_handle;
-
- // Descriptor gubbins
- shader_data data_layouts[MAX_SHADER_DATA_LAYOUTS];
- u32 data_layouts_count;
-
- VkDescriptorSetLayout* desc_set_layouts;
- // Based on group, we know which data to load
- desc_set_uniform_buffer* uniform_pointers;
- u32 desc_set_layouts_count;
-
-} gpu_pipeline;
-
-typedef struct gpu_renderpass {
- VkRenderPass handle;
- // TODO: Where to store framebuffers? VkFramebuffer framebuffers[GPU_SWAPCHAIN_IMG_COUNT];
-} gpu_renderpass;
-
-typedef struct gpu_cmd_encoder {
- VkCommandBuffer cmd_buffer;
- VkDescriptorPool descriptor_pool;
- gpu_pipeline* pipeline;
-} gpu_cmd_encoder;
-
-typedef struct gpu_cmd_buffer {
- VkCommandBuffer cmd_buffer;
-} gpu_cmd_buffer;
-
-typedef struct gpu_buffer {
- VkBuffer handle;
- VkDeviceMemory memory;
- u64 size;
-} gpu_buffer;
-
-typedef struct gpu_texture {
- VkImage handle;
- VkDeviceMemory memory;
- u64 size;
- texture_desc desc;
- VkImageView view;
- VkSampler sampler;
- char* debug_label;
-} gpu_texture;
-#endif \ No newline at end of file
diff --git a/src/render/immdraw.c b/src/render/immdraw.c
deleted file mode 100644
index 8a10c65..0000000
--- a/src/render/immdraw.c
+++ /dev/null
@@ -1,176 +0,0 @@
-#include "immdraw.h"
-#include "core.h"
-#include "file.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"
-#include "render.h"
-#include "render_types.h"
-#include "shader_layouts.h"
-
-void Immdraw_Init(Immdraw_Storage* storage) {
- INFO("Immediate drawing initialisation");
-
- // Meshes
- Geometry sphere_geo = Geo_CreateUVsphere(1.0, 16, 16);
- storage->sphere = Mesh_Create(&sphere_geo, true);
-
- Geometry cube_geo = Geo_CreateCuboid(f32x3(1.0, 1.0, 1.0));
- storage->cube = Mesh_Create(&cube_geo, true);
-
- Geometry plane_geo = Geo_CreatePlane(f32x2(1.0, 1.0), 1, 1);
- storage->plane = Mesh_Create(&plane_geo, true);
-
- Geometry cone_geo = Geo_CreateCone(1.0, 1.0, 8);
- storage->cone = Mesh_Create(&cone_geo, true);
-
- Geometry cyl_geo = Geo_CreateCylinder(1.0, 2.0, 8);
- storage->cylinder = Mesh_Create(&cyl_geo, true);
-
- storage->bbox = GenBboxMesh();
-
- // Pipeline / material
- VertexDescription vertex_desc = {
- .debug_label = "Immdraw Vertex",
- .use_full_vertex_size = true,
- };
- VertexDesc_AddAttr(&vertex_desc, "position", ATTR_F32x3);
- VertexDesc_AddAttr(&vertex_desc, "normal", ATTR_F32x3);
-
- const char* vert_path = "assets/shaders/immdraw.vert";
- const char* frag_path = "assets/shaders/immdraw.frag";
- const char* vert_shader = string_from_file(vert_path);
- const char* frag_shader = string_from_file(frag_path);
-
- ShaderDataLayout camera_data = Binding_Camera_GetLayout(NULL);
- ShaderDataLayout imm_uniform_data = ImmediateUniforms_GetLayout(NULL);
-
- GraphicsPipelineDesc pipeline_desc = {
- .debug_name = "Immediate Draw Pipeline",
- .vertex_desc = static_3d_vertex_description(),
- .data_layouts = { camera_data, imm_uniform_data },
- .data_layouts_count = 2,
- .vs = { .debug_name = "Immdraw Vertex Shader", .filepath = vert_path, .code = vert_shader },
- .fs = { .debug_name = "Immdraw Fragment Shader", .filepath = frag_path, .code = frag_shader },
- .depth_test = true,
- .wireframe = true,
- };
- GPU_Renderpass* rpass =
- GPU_Renderpass_Create((GPU_RenderpassDesc){ .default_framebuffer = true });
- storage->colour_pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, rpass);
-}
-
-void Immdraw_Shutdown(Immdraw_Storage* storage) {
- GraphicsPipeline_Destroy(storage->colour_pipeline);
-}
-
-void Immdraw_Sphere(Transform tf, Vec4 colour, bool wireframe) {
- TRACE("Draw sphere");
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- Immdraw_Primitive(tf, CEL_TRI, 1.0, colour, wireframe, imm->sphere);
-}
-void Immdraw_Cuboid(Transform tf, Vec4 colour, bool wireframe) {
- TRACE("Draw cube");
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- Immdraw_Primitive(tf, CEL_TRI, 1.0, colour, wireframe, imm->cube);
-}
-void Immdraw_Plane(Transform tf, Vec4 colour, bool wireframe) {
- TRACE("Draw plane");
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- Immdraw_Primitive(tf, CEL_TRI, 1.0, colour, wireframe, imm->plane);
-}
-
-void Immdraw_Bbox(Transform tf, Vec4 colour, bool wireframe) {
- TRACE("Draw bbox");
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- Immdraw_Primitive(tf, CEL_LINE, 1.0, colour, wireframe, imm->bbox);
-}
-
-void Immdraw_Cylinder(Transform tf, Vec4 colour, bool wireframe) {
- TRACE("Draw cylinder");
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- Immdraw_Primitive(tf, CEL_TRI, 1.0, colour, wireframe, imm->cylinder);
-}
-
-void Immdraw_Cone(Transform tf, Vec4 colour, bool wireframe) {
- TRACE("Draw cone");
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- Immdraw_Primitive(tf, CEL_TRI, 1.0, colour, wireframe, imm->cone);
-}
-
-void Immdraw_Primitive(Transform tf, PrimitiveTopology topology, f32 size, Vec4 colour,
- bool wireframe, Mesh mesh) {
- Immdraw_Storage* imm = Render_GetImmdrawStorage();
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
-
- // begin renderpass
- GPU_CmdEncoder_BeginRender(enc, imm->colour_pipeline->renderpass);
- // bind pipeline
- GPU_EncodeBindPipeline(enc, imm->colour_pipeline);
-
- // TODO: implement wireframe in other apis
-#if defined(CEL_REND_BACKEND_OPENGL)
-#include <glad/glad.h>
- if (wireframe) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- } else {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-#endif
-
- // update uniforms
- ImmediateUniforms uniforms = {
- .model = transform_to_mat(&tf),
- .colour = colour,
- };
- Mat4 view, proj;
- u32x2 dimensions = GPU_Swapchain_GetDimensions();
- RenderScene* scene = Render_GetScene();
- Camera_ViewProj(&scene->camera, (f32)dimensions.x, (f32)dimensions.y, &view, &proj);
- Binding_Camera camera_data = { .view = view,
- .projection = proj,
- .viewPos = vec4(scene->camera.position.x, scene->camera.position.y,
- scene->camera.position.z, 1.0) };
- GPU_EncodeBindShaderData(enc, 0, Binding_Camera_GetLayout(&camera_data));
- GPU_EncodeBindShaderData(enc, 1, ImmediateUniforms_GetLayout(&uniforms));
-
- // draw call
- GPU_EncodeSetVertexBuffer(enc, mesh.vertex_buffer);
- GPU_EncodeSetIndexBuffer(enc, mesh.index_buffer);
- GPU_EncodeDrawIndexed(enc, topology, mesh.geometry.index_count);
-
- // end renderpass
- GPU_CmdEncoder_EndRender(enc);
-}
-
-Mesh GenBboxMesh() {
- Vertex_darray* vertices = Vertex_darray_new(8);
- u32_darray* indices = u32_darray_new(24);
-
- // normals & uvs dont matter
- VERT_3D(vertices, FRONT_BOT_LEFT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, FRONT_BOT_RIGHT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, BACK_BOT_LEFT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, BACK_BOT_RIGHT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, FRONT_TOP_LEFT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, FRONT_TOP_RIGHT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, BACK_TOP_LEFT, VEC3_NEG_Z, vec2(0, 0));
- VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_NEG_Z, vec2(0, 0));
-
- u32 line_indices[24] = { 0, 1, 2, 3, 0, 2, 1, 3, 4, 5, 6, 7, 4, 6, 5, 7, 0, 4, 1, 5, 2, 6, 3, 7 };
- for (u32 i = 0; i < 24; i++) {
- u32_darray_push(indices, line_indices[i]);
- }
-
- Geometry geo = { .format = VERTEX_STATIC_3D,
- .has_indices = true,
- .index_count = indices->len,
- .vertices = vertices,
- .indices = indices };
-
- return Mesh_Create(&geo, true);
-}
diff --git a/src/render/immdraw.h b/src/render/immdraw.h
deleted file mode 100644
index 2911350..0000000
--- a/src/render/immdraw.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @brief Immediate-mode drawing APIs
- */
-
-#pragma once
-#include "defines.h"
-#include "maths_types.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-#include "render_types.h"
-
-typedef struct Immdraw_Storage {
- Mesh plane;
- Mesh cube;
- Mesh sphere;
- Mesh cylinder;
- Mesh cone;
- Mesh bbox;
- GPU_Pipeline* colour_pipeline; /** @brief Pipeline for drawing geometry that has vertex colours */
-} Immdraw_Storage;
-
-typedef struct ImmediateUniforms {
- Mat4 model;
- Vec4 colour;
-} ImmediateUniforms;
-
-// --- Public API
-
-PUB void Immdraw_Init(Immdraw_Storage* storage);
-PUB void Immdraw_Shutdown(Immdraw_Storage* storage);
-
-// These functions cause a pipeline switch and so aren't optimised for performance
-PUB void Immdraw_Plane(Transform tf, Vec4 colour, bool wireframe);
-PUB void Immdraw_Cuboid(Transform tf, Vec4 colour, bool wireframe);
-PUB void Immdraw_Cylinder(Transform tf, Vec4 colour, bool wireframe);
-PUB void Immdraw_Cone(Transform tf, Vec4 colour, bool wireframe);
-PUB void Immdraw_Sphere(Transform tf, Vec4 colour, bool wireframe);
-PUB void Immdraw_Bbox(Transform tf, Vec4 colour, bool wireframe);
-
-PUB void Immdraw_TransformGizmo(Transform tf, f32 size);
-
-// --- Internal
-
-void Immdraw_Primitive(Transform tf, PrimitiveTopology topology, f32 size, Vec4 colour,
- bool wireframe, Mesh mesh);
-
-Mesh GenBboxMesh();
-
-static ShaderDataLayout ImmediateUniforms_GetLayout(void* data) {
- ImmediateUniforms* d = (ImmediateUniforms*)data;
- bool has_data = data != NULL;
-
- ShaderBinding b1 = { .label = "ImmUniforms",
- .kind = BINDING_BYTES,
- // .vis = VISIBILITY_VERTEX,
- .data.bytes.size = sizeof(ImmediateUniforms) };
-
- if (has_data) {
- b1.data.bytes.data = d;
- }
-
- return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 };
-}
diff --git a/src/render/pbr.c b/src/render/pbr.c
deleted file mode 100644
index 4bad528..0000000
--- a/src/render/pbr.c
+++ /dev/null
@@ -1,266 +0,0 @@
-#include "pbr.h"
-#include "animation.h"
-#include "camera.h"
-#include "core.h"
-#include "file.h"
-#include "log.h"
-#include "maths.h"
-#include "mem.h"
-#include "ral_common.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-#include "render.h"
-#include "render_types.h"
-#include "shader_layouts.h"
-
-void PBR_Init(PBR_Storage* storage) {
- INFO("PBR shaders init");
- storage->pbr_pass = PBR_RPassCreate();
- PBR_PipelinesCreate(storage, storage->pbr_pass);
-}
-
-GPU_Renderpass* PBR_RPassCreate() {
- GPU_RenderpassDesc desc = { .default_framebuffer = true };
- return GPU_Renderpass_Create(desc);
-}
-
-void PBR_PipelinesCreate(PBR_Storage* storage, GPU_Renderpass* rpass) {
- // Common shader bindings
- ShaderDataLayout camera_data = Binding_Camera_GetLayout(NULL);
- ShaderDataLayout model_data = Binding_Model_GetLayout(NULL);
- ShaderDataLayout material_data = PBRMaterial_GetLayout(NULL);
- ShaderDataLayout lights_data = Binding_Lights_GetLayout(NULL);
-
- // Static
- {
- const char* vert_path = "assets/shaders/static_geometry.vert";
- const char* frag_path = "assets/shaders/pbr_textured.frag";
- char* vert_shader = string_from_file(vert_path);
- char* frag_shader = string_from_file(frag_path);
-
- GraphicsPipelineDesc desc = {
- .debug_name = "PBR (Static) Pipeline",
- .vertex_desc = static_3d_vertex_description(),
- .data_layouts = { camera_data, model_data, material_data, lights_data },
- .data_layouts_count = 4,
- .vs = { .debug_name = "PBR (textured) Vertex Shader",
- .filepath = str8(vert_path),
- .code = vert_shader },
- .fs = { .debug_name = "PBR (textured) Fragment Shader",
- .filepath = str8(frag_path),
- .code = frag_shader },
- .depth_test = true,
- .wireframe = true,
- };
- storage->pbr_static_pipeline = GPU_GraphicsPipeline_Create(desc, rpass);
- }
-
- // Skinned
- {
- const char* vert_path = "assets/shaders/skinned_geometry.vert";
- const char* frag_path = "assets/shaders/pbr_textured.frag";
- char* vert_shader = string_from_file(vert_path);
- char* frag_shader = string_from_file(frag_path);
-
- ShaderDataLayout anim_uniform = AnimData_GetLayout(NULL);
-
- VertexDescription vertex_desc = { .debug_label = "Skinned vertices",
- .use_full_vertex_size = true };
- VertexDesc_AddAttr(&vertex_desc, "inPosition", ATTR_F32x3);
- VertexDesc_AddAttr(&vertex_desc, "inNormal", ATTR_F32x3);
- VertexDesc_AddAttr(&vertex_desc, "inTexCoords", ATTR_F32x2);
- VertexDesc_AddAttr(&vertex_desc, "inBoneIndices", ATTR_I32x4);
- VertexDesc_AddAttr(&vertex_desc, "inWeights", ATTR_F32x4);
-
- GraphicsPipelineDesc desc = {
- .debug_name = "PBR (Skinned) Pipeline",
- .vertex_desc = vertex_desc,
- .data_layouts = { camera_data, model_data, material_data, lights_data, anim_uniform },
- .data_layouts_count = 5,
- .vs = { .debug_name = "PBR (textured) Vertex Shader",
- .filepath = str8(vert_path),
- .code = vert_shader },
- .fs = { .debug_name = "PBR (textured) Fragment Shader",
- .filepath = str8(frag_path),
- .code = frag_shader },
- .depth_test = true,
- .wireframe = true,
- };
- storage->pbr_skinned_pipeline = GPU_GraphicsPipeline_Create(desc, rpass);
- }
-}
-
-void PBR_Execute(PBR_Storage* storage, Camera camera, TextureHandle shadowmap_tex,
- RenderEnt* entities, size_t entity_count) {
- // 1. set up our pipeline
- // 2. upload constant data (camera, lights)
- // 3. draw each entity
- // - upload material data -> in the future we will sort & batch by material
- // - upload model transform
- // - emit draw call
-
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
- GPU_CmdEncoder_BeginRender(enc, storage->pbr_pass);
-
- // TEMP: only do skinned
- GPU_EncodeBindPipeline(enc, storage->pbr_skinned_pipeline);
-
- // Feed shader data
- Mat4 view, proj;
- u32x2 dimensions = GPU_Swapchain_GetDimensions();
- Camera_ViewProj(&camera, (f32)dimensions.x, (f32)dimensions.y, &view, &proj);
- Binding_Camera camera_data = { .view = view,
- .projection = proj,
- .viewPos = vec4(camera.position.x, camera.position.y,
- camera.position.z, 1.0) };
- GPU_EncodeBindShaderData(enc, 0, Binding_Camera_GetLayout(&camera_data));
-
- Vec3 light_color = vec3(300.0, 300.0, 300.0);
- Binding_Lights
- lights_data = { .pointLights = {
- // FIXME: add lights to our RenderScene structure. for now these are
- // hardcoded
- (pbr_point_light){ .pos = vec3(0.0, 6.0, 6.0), .color = light_color },
- (pbr_point_light){ .pos = vec3(-10, 10, 10), .color = light_color },
- (pbr_point_light){ .pos = vec3(10, -10, 10), .color = light_color },
- (pbr_point_light){ .pos = vec3(-10, -10, 10), .color = light_color },
- } };
- GPU_EncodeBindShaderData(enc, 3, Binding_Lights_GetLayout(&lights_data));
-
- // TODO: Add shadowmap texture to uniforms
- Mesh_pool* mesh_pool = Render_GetMeshPool();
- Material_pool* material_pool = Render_GetMaterialPool();
-
- for (size_t ent_i = 0; ent_i < entity_count; ent_i++) {
- RenderEnt renderable = entities[ent_i];
- Mesh* mesh = Mesh_pool_get(mesh_pool, renderable.mesh);
- Material* mat = Material_pool_get(material_pool, renderable.material);
-
- // upload material data
- PBRMaterialUniforms material_data = { .mat = *mat };
- GPU_EncodeBindShaderData(enc, 2, PBRMaterial_GetLayout(&material_data));
-
- // upload model transform
- Binding_Model model_data = { .model = renderable.affine };
- GPU_EncodeBindShaderData(enc, 1, Binding_Model_GetLayout(&model_data));
-
- // Skinning matrices
-
- // 1. calculate matrices
- AnimDataUniform anim_data = { 0 };
- CASSERT(renderable.armature);
- Armature* skeleton = renderable.armature;
- // Skip the first one as we assume its root for this test
- for (int j_i = 1; j_i < skeleton->joints->len; j_i++) {
- Joint* j = &skeleton->joints->data[j_i];
- j->local_transform = transform_to_mat(&j->transform_components);
- Mat4 m = mat4_mult(j->local_transform, j->inverse_bind_matrix);
- Joint* p = &skeleton->joints->data[j->parent];
- j->local_transform = mat4_mult(j->local_transform, p->local_transform);
- printf("Quat %f \n", j->transform_components.rotation.z);
- }
-
- // 2. bind and upload
- for (int j_i = 1; j_i < skeleton->joints->len; j_i++) {
- anim_data.bone_matrices[j_i] = skeleton->joints->data[j_i].local_transform;
- }
- GPU_EncodeBindShaderData(enc, 3, AnimData_GetLayout(&anim_data));
-
- // set buffers
- GPU_EncodeSetVertexBuffer(enc, mesh->vertex_buffer);
- GPU_EncodeSetIndexBuffer(enc, mesh->index_buffer);
- // draw
- GPU_EncodeDrawIndexedTris(enc, mesh->geometry.index_count);
- }
-
- GPU_CmdEncoder_EndRender(enc);
-}
-
-void PBRMaterial_BindData(ShaderDataLayout* layout, const void* data) {
- PBRMaterialUniforms* d = (PBRMaterialUniforms*)data;
- CASSERT(data);
- CASSERT(layout->binding_count == 5);
-
- TextureHandle white1x1 = Render_GetWhiteTexture();
- if (d->mat.albedo_map.raw != INVALID_TEX_HANDLE.raw) {
- layout->bindings[0].data.texture.handle = d->mat.albedo_map;
- } else {
- layout->bindings[0].data.texture.handle = white1x1;
- }
- // TODO .. the rest
-}
-
-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,
- };
- ShaderBinding b5 = { .label = "PBR_Params",
- .kind = BINDING_BYTES,
- .data.bytes.size = sizeof(PBR_Params) };
-
- if (has_data) {
- TextureHandle white1x1 = Render_GetWhiteTexture();
- if (d->mat.albedo_map.raw != INVALID_TEX_HANDLE.raw) {
- b1.data.texture.handle = d->mat.albedo_map;
- } else {
- b1.data.texture.handle = white1x1;
- }
-
- if (d->mat.metallic_roughness_map.raw != INVALID_TEX_HANDLE.raw) {
- b2.data.texture.handle = d->mat.metallic_roughness_map;
- } else {
- b2.data.texture.handle = white1x1;
- }
-
- if (d->mat.ambient_occlusion_map.raw != INVALID_TEX_HANDLE.raw) {
- b3.data.texture.handle = d->mat.ambient_occlusion_map;
- } else {
- b3.data.texture.handle = white1x1;
- }
-
- if (d->mat.normal_map.raw != INVALID_TEX_HANDLE.raw) {
- b4.data.texture.handle = d->mat.normal_map;
- } else {
- b4.data.texture.handle = white1x1;
- }
-
- arena* frame = Render_GetFrameArena();
- PBR_Params* params = arena_alloc(frame, sizeof(PBR_Params));
- params->albedo = d->mat.base_colour;
- params->metallic = d->mat.metallic;
- params->roughness = d->mat.roughness;
- params->ambient_occlusion = d->mat.ambient_occlusion;
- b5.data.bytes.data = params;
- }
-
- return (ShaderDataLayout){ .bindings = { b1, b2, b3, b4, b5 }, .binding_count = 5 };
-}
-
-Material PBRMaterialDefault() {
- return (Material){ .name = "Standard Material",
- .kind = MAT_PBR,
- .base_colour = vec3(1.0, 1.0, 1.0),
- .metallic = 0.0,
- .roughness = 0.5,
- .ambient_occlusion = 0.0,
- .albedo_map = INVALID_TEX_HANDLE,
- .metallic_roughness_map = INVALID_TEX_HANDLE,
- .normal_map = INVALID_TEX_HANDLE,
- .ambient_occlusion_map = INVALID_TEX_HANDLE };
-}
diff --git a/src/render/pbr.h b/src/render/pbr.h
deleted file mode 100644
index 5a21533..0000000
--- a/src/render/pbr.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file pbr.h
- * @brief PBR render pass and uniforms
- */
-
-#pragma once
-#include "backend_opengl.h"
-#include "camera.h"
-#include "defines.h"
-#include "maths_types.h"
-#include "ral_types.h"
-#include "render_types.h"
-
-// --- Public API
-
-/** @brief Holds data for the PBR pipeline */
-typedef struct PBR_Storage {
- GPU_Renderpass* pbr_pass;
- GPU_Pipeline* pbr_static_pipeline;
- GPU_Pipeline* pbr_skinned_pipeline;
-} PBR_Storage;
-
-typedef struct PBRMaterialUniforms {
- Material mat;
-} PBRMaterialUniforms;
-
-/** @brief */
-PUB void PBR_Init(PBR_Storage* storage);
-
-// NOTE: For simplicity's sake we will render this pass directly to the default framebuffer
-// internally this defers to `PBR_Execute()`
-PUB void PBR_Run(PBR_Storage* storage
- // light data
- // camera
- // geometry
- // materials
-);
-
-/** @brief Parameters that get passed as a uniform block to the PBR shader */
-typedef struct PBR_Params {
- Vec3 albedo;
- f32 metallic;
- f32 roughness;
- f32 ambient_occlusion;
-} PBR_Params;
-
-/** @brief Textures that will get passed into the PBR shader if they're not `INVALID_TEX_HANDLE` */
-typedef struct PBR_Textures {
- TextureHandle albedo_map;
- TextureHandle normal_map;
- bool metal_roughness_combined;
- TextureHandle metallic_map;
- TextureHandle roughness_map;
- TextureHandle ao_map;
-} PBR_Textures;
-
-/** @brief Returns a default white matte material */
-PUB Material PBRMaterialDefault();
-
-PUB ShaderDataLayout PBRMaterial_GetLayout(void* data);
-
-// --- Internal
-
-GPU_Renderpass* PBR_RPassCreate(); /** @brief Create the PBR Renderpass */
-
-void PBR_PipelinesCreate(PBR_Storage* storage,
- GPU_Renderpass* rpass); /** @brief Create PBR Pipelines */
-
-void PBR_Execute(PBR_Storage* storage, Camera camera, TextureHandle shadowmap_tex,
- RenderEnt* entities, size_t entity_count);
diff --git a/src/render/render.c b/src/render/render.c
deleted file mode 100644
index af636a8..0000000
--- a/src/render/render.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * @brief
- */
-
-#include "render.h"
-#include <assert.h>
-#include <glfw3.h>
-#include <stdio.h>
-#include "camera.h"
-#include "core.h"
-#include "grid.h"
-#include "immdraw.h"
-#include "log.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "mem.h"
-#include "pbr.h"
-#include "ral_common.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-#include "render_types.h"
-#include "shadows.h"
-#include "terrain.h"
-
-#define STB_IMAGE_IMPLEMENTATION
-#include <stb_image.h>
-
-#define FRAME_ARENA_SIZE MB(1)
-#define POOL_SIZE_BYTES \
- MB(10) // we will reserve 10 megabytes up front to store resource, mesh, and material pools
-#define MAX_MESHES 1024
-#define MAX_MATERIALS 256
-
-extern Core g_core;
-
-struct Renderer {
- struct GLFWwindow* window;
- RendererConfig config;
- GPU_Device device;
- GPU_Swapchain swapchain;
- GPU_Renderpass* default_renderpass;
- bool frame_aborted;
- RenderMode render_mode;
- RenderScene scene;
- PBR_Storage* pbr;
- Shadow_Storage* shadows;
- Terrain_Storage* terrain;
- Grid_Storage* grid;
- Immdraw_Storage* immediate;
- // Text_Storage* text;
- ResourcePools* resource_pools;
- Mesh_pool mesh_pool;
- Material_pool material_pool;
- arena frame_arena;
- TextureHandle white_1x1;
- TextureHandle black_1x1;
-};
-
-Renderer* get_renderer() { return g_core.renderer; }
-
-bool Renderer_Init(RendererConfig config, Renderer* ren, GLFWwindow** out_window,
- GLFWwindow* optional_window) {
- INFO("Renderer init");
- ren->render_mode = RENDER_MODE_DEFAULT;
-
- ren->frame_arena = arena_create(malloc(FRAME_ARENA_SIZE), FRAME_ARENA_SIZE);
-
- // init resource pools
- DEBUG("Initialise GPU resource pools");
- arena pool_arena = arena_create(malloc(POOL_SIZE_BYTES), POOL_SIZE_BYTES);
- ren->resource_pools = arena_alloc(&pool_arena, sizeof(struct ResourcePools));
- ResourcePools_Init(&pool_arena, ren->resource_pools);
- ren->mesh_pool = Mesh_pool_create(&pool_arena, MAX_MESHES, sizeof(Mesh));
- ren->material_pool = Material_pool_create(&pool_arena, MAX_MATERIALS, sizeof(Material));
-
- // GLFW window creation
- GLFWwindow* window;
- if (optional_window != NULL) {
- INFO("GLFWwindow pointer was provided!!!! Skipping generic glfw init..");
- window = optional_window;
- } else {
- INFO("No GLFWwindow provided - creating one");
- // 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
-
- window = glfwCreateWindow(config.scr_width, config.scr_height, config.window_name, NULL, NULL);
- INFO("Window created");
- if (window == NULL) {
- ERROR("Failed to create GLFW window\n");
- glfwTerminate();
- return false;
- }
- }
-
- ren->window = window;
- *out_window = window;
-
- glfwMakeContextCurrent(ren->window);
-
- DEBUG("Set up GLFW window callbacks");
- glfwSetWindowSizeCallback(window, Render_WindowSizeChanged);
-
- // set the RAL backend up
- if (!GPU_Backend_Init(config.window_name, window, ren->resource_pools)) {
- return false;
- }
-
- 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);
- SetCamera(default_cam);
- DirectionalLight default_light = { /* TODO */ };
- SetMainLight(default_light);
-
- // create our renderpasses
- ren->shadows = malloc(sizeof(Shadow_Storage));
- Shadow_Init(ren->shadows, 1024, 1024);
-
- ren->pbr = calloc(1, sizeof(PBR_Storage));
- PBR_Init(ren->pbr);
-
- ren->terrain = calloc(1, sizeof(Terrain_Storage));
- Terrain_Init(ren->terrain);
-
- // FIXME
- // ren->grid = calloc(1, sizeof(Grid_Storage));
- // Grid_Init(ren->grid);
-
- ren->immediate = calloc(1, sizeof(Immdraw_Storage));
- Immdraw_Init(ren->immediate);
-
- // load default textures
- ren->white_1x1 = TextureLoadFromFile("assets/textures/white1x1.png");
- ren->black_1x1 = TextureLoadFromFile("assets/textures/black1x1.png");
-
- return true;
-}
-
-void Renderer_Shutdown(Renderer* ren) {
- free(ren->shadows);
- DEBUG("Freed Shadows storage");
- free(ren->pbr);
- DEBUG("Freed PBR storage");
- free(ren->terrain);
- DEBUG("Freed Terrain storage");
- free(ren->immediate);
- DEBUG("Freed Immdraw storage");
- arena_free_storage(&ren->frame_arena);
- DEBUG("Freed frame allocator buffer");
-}
-size_t Renderer_GetMemReqs() { return sizeof(Renderer); }
-
-void Render_WindowSizeChanged(GLFWwindow* window, i32 new_width, i32 new_height) {
- (void)window;
- INFO("Window size changed callback");
- // Renderer* ren = Core_GetRenderer(&g_core);
- GPU_Swapchain_Resize(new_width, new_height);
-}
-
-void Render_FrameBegin(Renderer* ren) {
- arena_free_all(&ren->frame_arena);
- ren->frame_aborted = false;
- if (!GPU_Backend_BeginFrame()) {
- ren->frame_aborted = true;
- WARN("Frame aborted");
- return;
- }
-}
-void Render_FrameEnd(Renderer* ren) {
- if (ren->frame_aborted) {
- return;
- }
-
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
-
- GPU_Backend_EndFrame();
-}
-void Render_RenderEntities(RenderEnt* entities, size_t entity_count) {
- Renderer* ren = get_renderer();
- RenderScene scene = ren->scene;
-
- // FUTURE: Depth pre-pass
-
- Shadow_Storage* shadow_storage = Render_GetShadowStorage();
- shadow_storage->enabled = false;
- TextureHandle sun_shadowmap =
- shadow_storage->enabled ? Shadow_GetShadowMapTexture(shadow_storage) : INVALID_TEX_HANDLE;
-
- PBR_Execute(ren->pbr, scene.camera, sun_shadowmap, 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, 0);
- if (data) {
- DEBUG("loaded texture: %s", path);
- } else {
- WARN("failed to load texture");
- }
-
- // printf("width: %d height: %d num channels: %d\n", width, height, num_channels);
-
- 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,
- .num_channels = num_channels,
- .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) {
- 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
- if (geometry->has_indices) {
- 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; // clone geometry data and store on Mesh struct
- if (free_on_upload) {
- Geometry_Destroy(geometry);
- }
- return m;
-}
-
-void Geometry_Destroy(Geometry* geometry) {
- if (geometry->indices) {
- u32_darray_free(geometry->indices);
- }
- if (geometry->vertices) {
- Vertex_darray_free(geometry->vertices);
- }
-}
-PUB MeshHandle Mesh_Insert(Mesh* mesh) { return Mesh_pool_insert(Render_GetMeshPool(), mesh); }
-PUB MaterialHandle Material_Insert(Material* material) {
- return Material_pool_insert(Render_GetMaterialPool(), material);
-}
-Mesh* Mesh_Get(MeshHandle handle) { return Mesh_pool_get(Render_GetMeshPool(), handle); }
-
-void Mesh_DebugPrint(Mesh* mesh) {
- printf("Mesh %d vertices %d indices %d joints \n", mesh->geometry.vertices->len,
- mesh->geometry.indices->len);
-}
-
-size_t ModelExtractRenderEnts(RenderEnt_darray* entities, ModelHandle model_handle, Mat4 affine,
- RenderEntityFlags flags) {
- Model* model = MODEL_GET(model_handle);
- for (u32 i = 0; i < model->mesh_count; i++) {
- Mesh* m = Mesh_pool_get(Render_GetMeshPool(), model->meshes[i]);
- RenderEnt data = { .mesh = model->meshes[i],
- .material = m->material,
- .affine = affine,
- // .bounding_box
- .flags = flags };
- RenderEnt_darray_push(entities, data);
- }
- return model->mesh_count; // how many RenderEnts we pushed
-}
-
-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; }
-
-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;
-}
-
-Terrain_Storage* Render_GetTerrainStorage() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return ren->terrain;
-}
-
-Grid_Storage* Render_GetGridStorage() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return ren->grid;
-}
-
-Immdraw_Storage* Render_GetImmdrawStorage() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return ren->immediate;
-}
-
-TextureHandle Render_GetWhiteTexture() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return ren->white_1x1;
-}
-
-/** @return an arena allocator that gets cleared at the beginning of every render frame */
-arena* Render_GetFrameArena() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return &ren->frame_arena;
-}
-
-Mesh_pool* Render_GetMeshPool() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return &ren->mesh_pool;
-}
-Material_pool* Render_GetMaterialPool() {
- Renderer* ren = Core_GetRenderer(&g_core);
- return &ren->material_pool;
-}
-
-void Render_SetRenderMode(RenderMode mode) {
- Renderer* ren = Core_GetRenderer(&g_core);
- ren->render_mode = mode;
-}
diff --git a/src/render/render.h b/src/render/render.h
deleted file mode 100644
index d752f8b..0000000
--- a/src/render/render.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * @brief
- */
-
-#pragma once
-#include "camera.h"
-#include "defines.h"
-#include "grid.h"
-#include "immdraw.h"
-#include "maths_types.h"
-#include "ral_types.h"
-#include "render_types.h"
-#include "shadows.h"
-
-typedef struct Renderer Renderer;
-typedef struct GLFWwindow GLFWwindow;
-typedef struct RendererConfig {
- const char* window_name;
- u32 scr_width, scr_height;
- Vec3 clear_colour;
-} RendererConfig;
-
-typedef struct RenderFlags {
- bool wireframe;
-} RenderFlags;
-
-typedef struct RenderCtx {
- Mat4 view;
- Mat4 projection;
-} RenderCtx;
-
-/** @brief Holds globally bound data for rendering a scene. Typically held by the renderer.
- * Whenever you call draw functions you can think of this as an implicit parameter. */
-typedef struct RenderScene {
- Camera camera;
- DirectionalLight sun;
-} RenderScene;
-
-PUB void SetCamera(Camera camera);
-PUB void SetMainLight(DirectionalLight light);
-
-// #define MESH_GET(h) (Mesh_pool_get(g_core.renderer->meshes, h))
-// #define MATERIAL_GET(h) (Material_pool_get(g_core.renderer->material, h))
-
-// --- Lifecycle
-
-PUB bool Renderer_Init(RendererConfig config, Renderer* renderer, GLFWwindow** out_window,
- GLFWwindow* optional_window);
-PUB void Renderer_Shutdown(Renderer* renderer);
-PUB size_t Renderer_GetMemReqs();
-void Render_WindowSizeChanged(GLFWwindow* window, i32 new_width, i32 new_height);
-
-// internal init functions
-void DefaultPipelinesInit(Renderer* renderer);
-
-// NOTE: All of these functions grab the Renderer instance off the global Core
-PUB void Render_FrameBegin(Renderer* renderer);
-PUB void Render_FrameEnd(Renderer* renderer);
-
-/** @brief */
-PUB void Render_RenderEntities(RenderEnt* entities, size_t entity_count);
-
-// TODO: Render_FrameDraw(); - this will
-
-// --- Resources
-
-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
-
-PUB Mesh Mesh_Create(Geometry* geometry, bool free_on_upload);
-PUB void Mesh_Delete(Mesh* mesh);
-Mesh* Mesh_Get(MeshHandle handle);
-void Geometry_Destroy(Geometry* geometry);
-MeshHandle Mesh_Insert(Mesh* mesh);
-void Mesh_DebugPrint(Mesh* mesh);
-MaterialHandle Material_Insert(Material* material);
-
-/** @brief gets render entities from a model and pushes them into a dynamic array for rendering */
-size_t ModelExtractRenderEnts(RenderEnt_darray* entities, ModelHandle model_handle, Mat4 affine,
- RenderEntityFlags flags);
-
-// --- Drawing
-
-// NOTE: These functions use the globally bound camera in RenderScene
-PUB void DrawMesh(Mesh* mesh, Material* material, Mat4 model);
-
-/** @brief the renderer does some internal bookkeeping for terrain so we use the terrain
- stored on the Renderer rather than accept it as a parameter */
-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);
-
-typedef struct RenderScene RenderScene;
-typedef struct Shadow_Storage Shadow_Storage;
-typedef struct Terrain_Storage Terrain_Storage;
-
-RenderScene* Render_GetScene();
-Shadow_Storage* Render_GetShadowStorage();
-Terrain_Storage* Render_GetTerrainStorage();
-Grid_Storage* Render_GetGridStorage();
-Immdraw_Storage* Render_GetImmdrawStorage();
-TextureHandle Render_GetWhiteTexture();
-arena* Render_GetFrameArena();
-Mesh_pool* Render_GetMeshPool();
-Material_pool* Render_GetMaterialPool();
-
-// --- Setters
-void Render_SetRenderMode(RenderMode mode);
-
-// -------------------------------------------------
-
-// Frame lifecycle on CPU
-
-// 1. extract
-// 2. culling
-// 3. render
-// 4. dispatch (combined with render for now)
-
-// typedef struct Cull_Result {
-// u64 n_visible_objects;
-// u64 n_culled_objects;
-// u32* visible_ent_indices; // allocated on frame arena
-// size_t index_count;
-// } Cull_Result;
-
-// // everything that can be in the world, knows how to extract rendering data
-// typedef void (*ExtractRenderData)(void* world_data);
-
-// typedef struct Renderer Renderer;
-
-// /** @brief Produces a smaller set of only those meshes visible in the camera frustum on the CPU
-// */ Cull_Result Frame_Cull(Renderer* ren, RenderEnt* entities, size_t entity_count, Camera*
-// camera);
-
-// Cull_Result Frame_Cull(Renderer* ren, RenderEnt* entities, size_t entity_count, Camera* camera) {
-// // TODO: u32 chunk_count = Tpool_GetNumWorkers();
-
-// arena* frame_arena = GetRenderFrameArena(ren);
-
-// Cull_Result result = { 0 };
-// result.visible_ent_indices = arena_alloc(
-// frame_arena, sizeof(u32) * entity_count); // make space for if all ents are visible
-
-// assert((result.n_visible_objects + result.n_culled_objects == entity_count));
-// return result;
-// }
diff --git a/src/render/render_types.h b/src/render/render_types.h
deleted file mode 100644
index bdf9849..0000000
--- a/src/render/render_types.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * @brief
- */
-
-#pragma once
-#include "animation.h"
-#include "defines.h"
-#include "maths_types.h"
-#include "mem.h"
-#include "ral_types.h"
-
-// --- Handles
-
-#define INVALID_MODEL_HANDLE ((ModelHandle){ .raw = 9999991 })
-#define INVALID_MATERIAL_HANDLE ((MaterialHandle){ .raw = 9999992 })
-#define INVALID_MESH_HANDLE ((MeshHandle){ .raw = 9999993 })
-
-typedef enum RenderMode {
- RENDER_MODE_DEFAULT,
- RENDER_MODE_WIREFRAME,
- RENDER_MODE_WIREFRAME_ON_LIT,
- RENDER_MODE_COUNT
-} RenderMode;
-
-typedef struct u32_opt {
- u32 value;
- bool has_value;
-} u32_opt;
-
-typedef struct Mesh {
- BufferHandle vertex_buffer;
- BufferHandle index_buffer;
- Geometry geometry; // NULL means it has been freed CPU-side
- MaterialHandle material;
- bool is_skinned; // false = its static
- Armature armature;
- bool is_uploaded; // has the data been uploaded to the GPU
-} Mesh;
-#ifndef TYPED_MESH_CONTAINERS
-KITC_DECL_TYPED_ARRAY(Mesh)
-TYPED_POOL(Mesh, Mesh)
-#define TYPED_MESH_CONTAINERS
-#endif
-
-typedef struct TextureData {
- TextureDesc description;
- void* image_data;
-} TextureData;
-
-// --- Supported materials
-typedef enum MaterialKind {
- 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;
-static const char* material_kind_names[] = { "Blinn Phong", "PBR (Textures)", "PBR (Params)",
- "Count (This should be an error)" };
-
-/**
- * @brief
- * @note based on https://google.github.io/filament/Filament.html#materialsystem/standardmodel
- */
-typedef struct Material {
- char name[64];
- MaterialKind kind; // at the moment all materials are PBR materials
- Vec3 base_colour; // linear RGB {0,0,0} to {1,1,1}
- f32 metallic;
- f32 roughness;
- f32 ambient_occlusion;
- TextureHandle albedo_map;
- TextureHandle normal_map;
- TextureHandle metallic_roughness_map;
- TextureHandle ambient_occlusion_map;
-} Material;
-
-#ifndef TYPED_MATERIAL_CONTAINERS
-KITC_DECL_TYPED_ARRAY(Material)
-TYPED_POOL(Material, Material)
-#define TYPED_MATERIAL_CONTAINERS
-#endif
-
-/** @brief Convenient wrapper around a number of meshes each with a material */
-typedef struct Model {
- Str8 name;
- MeshHandle* meshes;
- size_t mesh_count;
- MaterialHandle* materials;
- size_t material_count;
- arena anim_arena;
- AnimationClip_darray* animations;
-} 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)
-
-// --- Lights
-typedef struct PointLight {
- Vec3 position;
- f32 constant, linear, quadratic;
- Vec3 ambient;
- Vec3 diffuse;
- Vec3 specular;
-} PointLight;
-
-typedef struct DirectionalLight {
- Vec3 direction;
- Vec3 ambient;
- Vec3 diffuse;
- Vec3 specular;
-} DirectionalLight;
-
-// ---
-
-typedef enum RenderEntityFlag {
- REND_ENT_CASTS_SHADOWS = 1 << 0,
- REND_ENT_VISIBLE = 1 << 1,
-} RenderEntityFlag;
-typedef u32 RenderEntityFlags;
-
-/** @brief A renderable 'thing' */
-typedef struct RenderEnt {
- MeshHandle mesh;
- MaterialHandle material;
- /** If NULL, no armature and the mesh is static geometry, else it is to be skinned */
- Armature* armature;
- Mat4 affine; // In the future this should be updated by the transform graph
- Bbox_3D bounding_box;
- RenderEntityFlags flags;
-} RenderEnt;
-
-#ifndef TYPED_RENDERENT_ARRAY
-KITC_DECL_TYPED_ARRAY(RenderEnt)
-#define TYPED_RENDERENT_ARRAY
-#endif
diff --git a/src/render/shader_layouts.h b/src/render/shader_layouts.h
deleted file mode 100644
index ef94c89..0000000
--- a/src/render/shader_layouts.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-#include "maths_types.h"
-#include "ral_types.h"
-
-/** @brief shader layout for camera matrices */
-typedef struct Binding_Camera {
- Mat4 view;
- Mat4 projection;
- Vec4 viewPos;
-} 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_Lights {
- pbr_point_light pointLights[4];
-} Binding_Lights;
-
-static ShaderDataLayout Binding_Camera_GetLayout(void* data) {
- Binding_Camera* d = data;
- bool has_data = data != NULL;
-
- ShaderBinding b1 = { .label = "Camera",
- .kind = BINDING_BYTES,
- .data.bytes = { .size = sizeof(Binding_Camera) } };
- 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,
- .vis = VISIBILITY_VERTEX,
- .data.bytes = { .size = sizeof(Binding_Model) } };
- if (has_data) {
- b1.data.bytes.data = d;
- }
- return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 };
-}
-
-static ShaderDataLayout Binding_Lights_GetLayout(void* data) {
- Binding_Lights* d = data;
- bool has_data = data != NULL;
-
- ShaderBinding b1 = { .label = "Lights",
- .kind = BINDING_BYTES,
- .vis = VISIBILITY_FRAGMENT,
- .data.bytes = { .size = sizeof(Binding_Lights) } };
- if (has_data) {
- b1.data.bytes.data = d;
- }
- return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 };
-}
diff --git a/src/render/shadows.c b/src/render/shadows.c
deleted file mode 100644
index 029eefb..0000000
--- a/src/render/shadows.c
+++ /dev/null
@@ -1,211 +0,0 @@
-#include "shadows.h"
-#include <string.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"
-#include "render.h"
-#include "render_types.h"
-#include "str.h"
-
-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 } };
-}
-
-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 = u32x2(shadowmap_width, shadowmap_height),
- .format = TEXTURE_FORMAT_DEPTH_DEFAULT,
- .tex_type = TEXTURE_TYPE_2D };
- DEBUG("Creating depth map texture for shadows");
- 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,
- .depth_stencil = depthmap };
-
- storage->shadowmap_pass = GPU_Renderpass_Create(rpass_desc);
-
- WARN("About to laod shaders");
- WARN("Shader paths: %s %s", "assets/shaders/shadows.vert", "assets/shaders/shadows.frag");
- 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");
- }
-
- ShaderDataLayout uniforms = ShadowUniforms_GetLayout(NULL);
-
- 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->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");
- }
-
- ShaderDataLayout debugquad_uniforms = ShadowDebugQuad_GetLayout(NULL);
-
- 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), 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);
- ShaderDataLayout quad_data = ShadowDebugQuad_GetLayout(&shadow_storage->depth_texture);
- GPU_EncodeBindShaderData(enc, 0, quad_data);
- GPU_EncodeSetVertexBuffer(enc, shadow_storage->quad.vertex_buffer);
- GPU_EncodeSetIndexBuffer(enc, shadow_storage->quad.index_buffer);
- GPU_EncodeDrawIndexedTris(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");
-
- // FIXME: shouldnt be gl specific
- glClear(GL_DEPTH_BUFFER_BIT);
-
- GPU_EncodeBindPipeline(&shadow_encoder, storage->shadowmap_pipeline);
-
- ShadowUniforms uniforms = {
- .light_space = light_space_transform,
- .model = mat4_ident() // this will be overwritten for each Model
- };
- ShaderDataLayout shader_data = ShadowUniforms_GetLayout(&uniforms);
-
- for (size_t ent_i = 0; ent_i < entity_count; ent_i++) {
- RenderEnt renderable = entities[ent_i];
- if (renderable.flags && REND_ENT_CASTS_SHADOWS) {
- // Model* model = MODEL_GET(renderable.model);
-
- uniforms.model = renderable.affine; // update the model transform
-
- Mesh* mesh = Mesh_pool_get(Render_GetMeshPool(), renderable.mesh);
- GPU_EncodeBindShaderData(&shadow_encoder, 0, shader_data);
- GPU_EncodeSetVertexBuffer(&shadow_encoder, mesh->vertex_buffer);
- GPU_EncodeSetIndexBuffer(&shadow_encoder, mesh->index_buffer);
- GPU_EncodeDrawIndexedTris(&shadow_encoder, mesh->geometry.indices->len);
- }
- }
-
- GPU_CmdEncoder_EndRender(&shadow_encoder); // end renderpass
-}
-
-TextureHandle Shadow_GetShadowMapTexture(Shadow_Storage* storage) { return storage->depth_texture; }
diff --git a/src/render/shadows.h b/src/render/shadows.h
deleted file mode 100644
index 0482d10..0000000
--- a/src/render/shadows.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @brief Functions for adding shadows to scene rendering.
- */
-
-#pragma once
-#include "defines.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-#include "render_types.h"
-
-typedef struct Shadow_Storage {
- bool enabled;
- GPU_Renderpass* shadowmap_pass;
- 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;
-
-typedef struct ShadowUniforms {
- Mat4 light_space;
- Mat4 model;
-} ShadowUniforms;
-
-typedef struct Camera Camera;
-typedef struct Mat4 Mat4;
-
-// --- Public API
-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(RenderEnt* entities, size_t entity_count);
-
-PUB void Shadow_DrawDebugQuad();
-
-/** @brief Get the shadow texture generated from shadowmap pass */
-PUB TextureHandle 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* entities, size_t entity_count);
-void Shadow_RenderDebugQuad();
diff --git a/src/render/skybox.c b/src/render/skybox.c
deleted file mode 100644
index b4e1e42..0000000
--- a/src/render/skybox.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#include "skybox.h"
-#include <assert.h>
-#include "file.h"
-#include "glad/glad.h"
-#include "log.h"
-#include "maths.h"
-#include "primitives.h"
-#include "ral_common.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-#include "render.h"
-#include "render_types.h"
-#include "shader_layouts.h"
-
-float skyboxVertices[] = {
- // positions
- -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-
- -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
- -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-
- 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
-
- -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-
- -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
-
- -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
- 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f
-};
-
-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/front.jpg", "assets/demo/skybox/back.jpg" };
-
-Skybox Skybox_Create(const char** face_paths, int n) {
- INFO("Creating a skybox");
- CASSERT_MSG(
- n == 6,
- "We only support full cubemaps for now"); // ! we're only supporting a full cubemap for now
-
- // -- cube verts
- Geometry geom = { .format = VERTEX_POS_ONLY, // doesnt matter
- .has_indices = false,
- .indices = NULL,
- .vertices = Vertex_darray_new(36) };
- for (u32 i = 0; i < (36 * 3); i += 3) {
- Vertex_darray_push(
- geom.vertices,
- (Vertex){ .pos_only = { .position = vec3(skyboxVertices[i], skyboxVertices[i + 1],
- skyboxVertices[i + 2]) } });
- }
- Mesh cube = Mesh_Create(&geom, false);
-
- // -- cubemap texture
- TextureHandle handle;
- GPU_Texture* tex = GPU_TextureAlloc(&handle);
- glBindTexture(GL_TEXTURE_CUBE_MAP, tex->id);
-
- for (unsigned int i = 0; i < n; i++) {
- TextureData data = TextureDataLoad(face_paths[i], false);
- 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
- GPU_RenderpassDesc rpass_desc = {
- .default_framebuffer = true,
- };
- GPU_Renderpass* pass = GPU_Renderpass_Create(rpass_desc);
-
- arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
-
- Str8 vert_path = str8("assets/shaders/skybox.vert");
- Str8 frag_path = str8("assets/shaders/skybox.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")
- }
-
- ShaderDataLayout camera_data = Binding_Camera_GetLayout(NULL);
- ShaderDataLayout shader_data = Skybox_GetLayout(NULL);
-
- VertexDescription builder = { .debug_label = "pos only" };
- VertexDesc_AddAttr(&builder, "inPosition", ATTR_F32x3);
- builder.use_full_vertex_size = true;
-
- GraphicsPipelineDesc pipeline_desc = {
- .debug_name = "Skybox pipeline",
- .vertex_desc = builder,
- .data_layouts = { shader_data, camera_data },
- .data_layouts_count = 2,
- .vs = { .debug_name = "Skybox Vertex Shader",
- .filepath = vert_path,
- .code = vertex_shader.contents },
- .fs = { .debug_name = "Skybox Fragment Shader",
- .filepath = frag_path,
- .code = fragment_shader.contents },
- .wireframe = false,
- .depth_test = true,
- };
-
- GPU_Pipeline* pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, pass);
-
- return (Skybox){ .cube = cube, .texture = handle, .pipeline = pipeline };
-}
-
-Skybox Skybox_Default() { return Skybox_Create(faces, 6); }
-
-void Skybox_Draw(Skybox* skybox, Camera camera) {
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
- glDepthFunc(GL_LEQUAL);
- GPU_CmdEncoder_BeginRender(enc, skybox->pipeline->renderpass);
- GPU_EncodeBindPipeline(enc, skybox->pipeline);
- GPU_EncodeSetDefaults(enc);
-
- // Shader data
-
- Mat4 view, proj;
- u32x2 dimensions = GPU_Swapchain_GetDimensions();
- Camera_ViewProj(&camera, dimensions.x, dimensions.y, &view, &proj);
- Mat4 new = mat4_ident();
- new.data[0] = view.data[0];
- new.data[1] = view.data[1];
- new.data[2] = view.data[2];
- new.data[4] = view.data[4];
- new.data[5] = view.data[5];
- new.data[6] = view.data[6];
- new.data[8] = view.data[8];
- new.data[9] = view.data[9];
- new.data[10] = view.data[10];
-
- Binding_Camera camera_data = { .view = new,
- .projection = proj,
- .viewPos = vec4(camera.position.x, camera.position.y,
- camera.position.z, 1.0) };
- GPU_EncodeBindShaderData(enc, 0, Binding_Camera_GetLayout(&camera_data));
-
- SkyboxUniforms uniforms = { .cubemap = skybox->texture };
- ShaderDataLayout skybox_data = Skybox_GetLayout(&uniforms);
- GPU_EncodeBindShaderData(enc, 0, skybox_data);
-
- GPU_EncodeSetVertexBuffer(enc, skybox->cube.vertex_buffer);
- GPU_EncodeSetIndexBuffer(enc, skybox->cube.index_buffer);
-
- GPU_EncodeDrawTris(enc, 36);
-
- GPU_CmdEncoder_EndRender(enc);
- glDepthFunc(GL_LESS);
-}
diff --git a/src/render/skybox.h b/src/render/skybox.h
deleted file mode 100644
index c2ef3a2..0000000
--- a/src/render/skybox.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @brief
- */
-
-#pragma once
-#include "camera.h"
-#include "defines.h"
-#include "ral_impl.h"
-#include "render_types.h"
-
-typedef struct Skybox {
- Mesh cube;
- TextureHandle texture;
- GPU_Pipeline* pipeline; // "shader"
-} Skybox;
-
-PUB Skybox Skybox_Create(const char** face_paths, int n); // should always pass n = 6 for now
-
-PUB void Skybox_Draw(Skybox* skybox, Camera camera);
-
-typedef struct SkyboxUniforms {
- TextureHandle cubemap;
-} SkyboxUniforms;
-
-static ShaderDataLayout Skybox_GetLayout(void* data) {
- SkyboxUniforms* d = (SkyboxUniforms*)data; // cold cast
- bool has_data = data != NULL;
-
- ShaderBinding b1 = {
- .label = "cubeMap",
- .vis = VISIBILITY_FRAGMENT,
- .kind = BINDING_TEXTURE,
- };
-
- if (has_data) {
- b1.data.texture.handle = d->cubemap;
- }
- return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 };
-}
-
-Skybox Skybox_Default(); \ No newline at end of file
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
deleted file mode 100644
index 66ae1b6..0000000
--- a/src/resources/gltf.c
+++ /dev/null
@@ -1,596 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "animation.h"
-#include "colours.h"
-#include "core.h"
-#include "defines.h"
-#include "file.h"
-#include "loaders.h"
-#include "log.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "mem.h"
-#include "pbr.h"
-#include "platform.h"
-#include "ral_types.h"
-#include "render.h"
-#include "render_types.h"
-#include "str.h"
-
-#define CGLTF_IMPLEMENTATION
-#include <cgltf.h>
-
-extern Core g_core;
-
-/* GLTF Loading Pipeline
- ===================== */
-
-struct face {
- cgltf_uint indices[3];
-};
-typedef struct face face;
-
-KITC_DECL_TYPED_ARRAY(Vec3)
-KITC_DECL_TYPED_ARRAY(Vec2)
-KITC_DECL_TYPED_ARRAY(Vec4u)
-KITC_DECL_TYPED_ARRAY(Vec4i)
-KITC_DECL_TYPED_ARRAY(Vec4)
-KITC_DECL_TYPED_ARRAY(face)
-KITC_DECL_TYPED_ARRAY(i32)
-
-size_t GLTF_LoadMaterials(cgltf_data* data, Str8 relative_path, Material_darray* out_materials);
-
-ModelHandle ModelLoad_gltf(const char* path, bool invert_texture_y) {
- size_t arena_size = MB(1);
- arena scratch = arena_create(malloc(arena_size), arena_size);
-
- TRACE("Loading model at Path %s\n", path);
- path_opt relative_path = path_parent(&scratch, path);
- if (!relative_path.has_value) {
- WARN("Couldnt get a relative path for the path to use for loading materials & textures later");
- }
- 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);
-
- bool success =
- model_load_gltf_str(file_string, path, relative_path.path, model, invert_texture_y);
-
- if (!success) {
- FATAL("Couldnt load GLTF file at path %s", path);
- ERROR_EXIT("Load fails are considered crash-worthy right now. This will change later.\n");
- }
-
- arena_free_all(&scratch);
- arena_free_storage(&scratch);
- return handle;
-}
-
-void assert_path_type_matches_component_type(cgltf_animation_path_type target_path,
- cgltf_accessor* output) {
- if (target_path == cgltf_animation_path_type_rotation) {
- assert(output->component_type == cgltf_component_type_r_32f);
- assert(output->type == cgltf_type_vec4);
- }
-}
-
-// TODO: Brainstorm how I can make this simpler and break it up into more testable pieces
-
-void load_position_components(Vec3_darray* positions, cgltf_accessor* accessor) {
- TRACE("Loading %d vec3 position components", accessor->count);
- CASSERT_MSG(accessor->component_type == cgltf_component_type_r_32f,
- "Positions components are floats");
- CASSERT_MSG(accessor->type == cgltf_type_vec3, "Vertex positions should be a vec3");
-
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- Vec3 pos;
- cgltf_accessor_read_float(accessor, v, &pos.x, 3);
- Vec3_darray_push(positions, pos);
- }
-}
-
-void load_normal_components(Vec3_darray* normals, cgltf_accessor* accessor) {
- TRACE("Loading %d vec3 normal components", accessor->count);
- CASSERT_MSG(accessor->component_type == cgltf_component_type_r_32f,
- "Normal vector components are floats");
- CASSERT_MSG(accessor->type == cgltf_type_vec3, "Vertex normals should be a vec3");
-
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- Vec3 pos;
- cgltf_accessor_read_float(accessor, v, &pos.x, 3);
- Vec3_darray_push(normals, pos);
- }
-}
-
-void load_texcoord_components(Vec2_darray* texcoords, cgltf_accessor* accessor) {
- TRACE("Load texture coordinates from accessor");
- CASSERT(accessor->component_type == cgltf_component_type_r_32f);
- CASSERT_MSG(accessor->type == cgltf_type_vec2, "Texture coordinates should be a vec2");
-
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- Vec2 tex;
- bool success = cgltf_accessor_read_float(accessor, v, &tex.x, 2);
- if (!success) {
- ERROR("Error loading tex coord");
- }
- Vec2_darray_push(texcoords, tex);
- }
-}
-
-void load_joint_index_components(Vec4i_darray* joint_indices, cgltf_accessor* accessor) {
- TRACE("Load joint indices from accessor");
- CASSERT(accessor->component_type == cgltf_component_type_r_16u);
- CASSERT_MSG(accessor->type == cgltf_type_vec4, "Joint indices should be a vec4");
- Vec4i tmp_joint_index;
- Vec4 joints_as_floats;
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- cgltf_accessor_read_float(accessor, v, &joints_as_floats.x, 4);
- tmp_joint_index.x = (u32)joints_as_floats.x;
- tmp_joint_index.y = (u32)joints_as_floats.y;
- tmp_joint_index.z = (u32)joints_as_floats.z;
- tmp_joint_index.w = (u32)joints_as_floats.w;
- printf("Joints affecting vertex %d : %d %d %d %d\n", v, tmp_joint_index.x, tmp_joint_index.y,
- tmp_joint_index.z, tmp_joint_index.w);
- Vec4i_darray_push(joint_indices, tmp_joint_index);
- }
-}
-
-bool model_load_gltf_str(const char* file_string, const char* filepath, Str8 relative_path,
- Model* out_model, bool invert_textures_y) {
- TRACE("Load GLTF from string");
-
- // Setup temps
- Vec3_darray* tmp_positions = Vec3_darray_new(1000);
- Vec3_darray* tmp_normals = Vec3_darray_new(1000);
- Vec2_darray* tmp_uvs = Vec2_darray_new(1000);
- Vec4i_darray* tmp_joint_indices = Vec4i_darray_new(1000);
- Vec4_darray* tmp_weights = Vec4_darray_new(1000);
- Material_darray* tmp_materials = Material_darray_new(1);
- Mesh_darray* tmp_meshes = Mesh_darray_new(1);
- i32_darray* tmp_material_indexes = i32_darray_new(1);
-
- Joint_darray* joints = Joint_darray_new(256);
-
- cgltf_options options = { 0 };
- cgltf_data* data = NULL;
- cgltf_result result = cgltf_parse_file(&options, filepath, &data);
- if (result != cgltf_result_success) {
- WARN("gltf load failed");
- // TODO: cleanup arrays(allocate all from arena ?)
- return false;
- }
-
- cgltf_load_buffers(&options, data, filepath);
- DEBUG("loaded buffers");
-
- // --- Skin
- size_t num_skins = data->skins_count;
- bool is_skinned = false;
- Armature main_skeleton = { 0 };
- if (num_skins == 1) {
- is_skinned = true;
- } else if (num_skins > 1) {
- WARN("GLTF files with more than 1 skin are not supported");
- return false;
- }
-
- if (is_skinned) {
- cgltf_skin* gltf_skin = data->skins;
- DEBUG("loading skin %s", gltf_skin->name);
- size_t num_joints = gltf_skin->joints_count;
- DEBUG("# Joints %d", num_joints);
-
- // Create our data that will be placed onto the model
- Armature armature = { .label = "test_skin" };
- printf("Skin %s\n", gltf_skin->name);
- // armature.label = Clone_cstr(&armature.arena, gltf_skin->name);
- armature.joints = joints; // ! Make sure not to free this
-
- cgltf_accessor* gltf_inverse_bind_matrices = gltf_skin->inverse_bind_matrices;
-
- // --- Joints
- // for each one we'll spit out a joint
- for (size_t i = 0; i < num_joints; i++) {
- // Get the joint and assign its node index for later referencing
- cgltf_node* joint_node = gltf_skin->joints[i];
- TRACE("Joint %d (node index %d)", i, cgltf_node_index(data, joint_node));
- Joint joint_i = { .debug_label = "test_joint",
- .node_idx = cgltf_node_index(data, joint_node),
- .inverse_bind_matrix = mat4_ident() };
-
- if (joint_node->children_count > 0 && !joint_node->has_translation &&
- !joint_node->has_rotation) {
- WARN("Joint node with index %d is the root node", i);
- joint_i.transform_components = TRANSFORM_DEFAULT;
- joint_i.parent = -1;
- for (u32 c_i = 0; c_i < joint_node->children_count; c_i++) {
- joint_i.children[c_i] = cgltf_node_index(data, joint_node->children[c_i]);
- joint_i.children_count++;
- }
- } else {
- TRACE("Storing joint transform");
- joint_i.transform_components = TRANSFORM_DEFAULT;
- if (joint_node->has_translation) {
- memcpy(&joint_i.transform_components.position, &joint_node->translation, 3 * sizeof(f32));
- }
- if (joint_node->has_rotation) {
- memcpy(&joint_i.transform_components.rotation, &joint_node->rotation, 4 * sizeof(f32));
- }
- if (joint_node->has_scale) {
- memcpy(&joint_i.transform_components.scale, &joint_node->scale, 3 * sizeof(f32));
- }
- joint_i.parent = cgltf_node_index(data, joint_node->parent);
- }
- // Calculate and store the starting transform of the joint
- joint_i.local_transform = transform_to_mat(&joint_i.transform_components);
- // Read in the inverse bind matrix
- cgltf_accessor_read_float(gltf_inverse_bind_matrices, i, &joint_i.inverse_bind_matrix.data[0],
- 16);
- Joint_darray_push(armature.joints, joint_i);
- }
- main_skeleton = armature;
- // out_model->armature = armature;
- // out_model->has_joints = true;
- }
-
- // --- Materials
- size_t num_materials = GLTF_LoadMaterials(data, relative_path, tmp_materials);
-
- // --- Meshes
- size_t num_meshes = data->meshes_count;
- TRACE("Num meshes %d", num_meshes);
- for (size_t m = 0; m < num_meshes; m++) {
- printf("Primitive count %d\n", data->meshes[m].primitives_count);
- for (size_t prim_i = 0; prim_i < data->meshes[m].primitives_count; prim_i++) {
- DEBUG("Primitive %d\n", prim_i);
-
- cgltf_primitive primitive = data->meshes[m].primitives[prim_i];
- DEBUG("Found %d attributes", primitive.attributes_count);
-
- for (cgltf_size a = 0; a < primitive.attributes_count; a++) {
- cgltf_attribute attribute = primitive.attributes[a];
- if (attribute.type == cgltf_attribute_type_position) {
- cgltf_accessor* accessor = attribute.data;
- load_position_components(tmp_positions, accessor);
- } else if (attribute.type == cgltf_attribute_type_normal) {
- cgltf_accessor* accessor = attribute.data;
- load_normal_components(tmp_normals, accessor);
- } else if (attribute.type == cgltf_attribute_type_texcoord) {
- cgltf_accessor* accessor = attribute.data;
- load_texcoord_components(tmp_uvs, accessor);
- } else if (attribute.type == cgltf_attribute_type_joints) {
- TRACE("Load joint indices from accessor");
- cgltf_accessor* accessor = attribute.data;
- load_joint_index_components(tmp_joint_indices, accessor);
- } else if (attribute.type == cgltf_attribute_type_weights) {
- TRACE("Load joint weights from accessor");
- cgltf_accessor* accessor = attribute.data;
- CASSERT(accessor->component_type == cgltf_component_type_r_32f);
- CASSERT(accessor->type == cgltf_type_vec4);
-
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- Vec4 weights;
- cgltf_accessor_read_float(accessor, v, &weights.x, 4);
- printf("Weights affecting vertex %d : %f %f %f %f\n", v, weights.x, weights.y,
- weights.z, weights.w);
- Vec4_darray_push(tmp_weights, weights);
- }
- } else {
- WARN("Unhandled cgltf_attribute_type: %s. skipping..", attribute.name);
- }
- }
- // mesh.vertex_bone_data = vertex_bone_data_darray_new(1);
- i32 mat_idx = -1;
- if (primitive.material != NULL) {
- DEBUG("Primitive Material %s", primitive.material->name);
- // FIXME!
- for (u32 i = 0; i < Material_darray_len(tmp_materials); i++) {
- printf("%s vs %s \n", primitive.material->name, tmp_materials->data[i].name);
- if (strcmp(primitive.material->name, tmp_materials->data[i].name) == 0) {
- INFO("Found material");
- mat_idx = i;
- i32_darray_push(tmp_material_indexes, mat_idx);
- break;
- }
- }
- } else {
- i32_darray_push(tmp_material_indexes, -1);
- }
-
- TRACE("Vertex data has been loaded");
-
- Vertex_darray* geo_vertices = Vertex_darray_new(3);
- u32_darray* geo_indices = u32_darray_new(0);
-
- // Store vertices
- printf("Positions %d Normals %d UVs %d\n", tmp_positions->len, tmp_normals->len,
- tmp_uvs->len);
- // assert(tmp_positions->len == tmp_normals->len);
- // assert(tmp_normals->len == tmp_uvs->len);
- bool has_normals = tmp_normals->len > 0;
- bool has_uvs = tmp_uvs->len > 0;
- for (u32 v_i = 0; v_i < tmp_positions->len; v_i++) {
- Vertex v = { 0 };
- if (is_skinned) {
- v.skinned_3d.position = tmp_positions->data[v_i];
- v.skinned_3d.normal = has_normals ? tmp_normals->data[v_i] : VEC3_ZERO,
- v.skinned_3d.tex_coords = has_uvs ? tmp_uvs->data[v_i] : vec2_create(0., 0.);
- v.skinned_3d.bone_ids = tmp_joint_indices->data[v_i];
- v.skinned_3d.bone_weights = tmp_weights->data[v_i];
- } else {
- v.static_3d.position = tmp_positions->data[v_i];
- v.static_3d.normal = has_normals ? tmp_normals->data[v_i] : VEC3_ZERO,
- v.static_3d.tex_coords = has_uvs ? tmp_uvs->data[v_i] : vec2_create(0., 0.);
- }
- Vertex_darray_push(geo_vertices, v);
- };
-
- // Store indices
- cgltf_accessor* indices = primitive.indices;
- if (primitive.indices > 0) {
- WARN("indices! %d", indices->count);
-
- // store indices
- for (cgltf_size i = 0; i < indices->count; ++i) {
- cgltf_uint ei;
- cgltf_accessor_read_uint(indices, i, &ei, 1);
- u32_darray_push(geo_indices, ei);
- }
-
- Geometry* geometry = malloc(sizeof(Geometry));
- geometry->format = is_skinned ? VERTEX_SKINNED : VERTEX_STATIC_3D;
- geometry->has_indices = true;
- geometry->vertices = geo_vertices;
- geometry->indices = geo_indices;
- geometry->index_count = geo_indices->len;
-
- Mesh m = Mesh_Create(geometry, false);
- if (is_skinned) {
- m.is_skinned = true;
- m.armature = main_skeleton;
- }
- Mesh_darray_push(tmp_meshes, m);
-
- Vec3_darray_clear(tmp_positions);
- Vec3_darray_clear(tmp_normals);
- Vec2_darray_clear(tmp_uvs);
- Vec4i_darray_clear(tmp_joint_indices);
- Vec4_darray_clear(tmp_weights);
- } else {
- WARN("No indices found. Ignoring mesh...");
- }
- }
-
- // --- Animations
- size_t num_animations = data->animations_count;
- TRACE("Num animations %d", num_animations);
-
- if (num_animations > 0) {
- if (!out_model->animations) {
- out_model->animations = AnimationClip_darray_new(num_animations);
- }
- out_model->anim_arena = arena_create(malloc(MB(1)), MB(1));
- arena* arena = &out_model->anim_arena;
-
- // Iterate over each animation in the GLTF
- for (int anim_idx = 0; anim_idx < data->animations_count; anim_idx++) {
- cgltf_animation animation = data->animations[anim_idx];
- AnimationClip clip = { 0 };
- clip.clip_name = "test anim clip";
- clip.channels = AnimationSampler_darray_new(1);
-
- // for each animation, loop through all the channels
- for (size_t c = 0; c < animation.channels_count; c++) {
- cgltf_animation_channel channel = animation.channels[c];
-
- AnimationSampler sampler = { 0 };
-
- KeyframeKind data_type;
-
- switch (channel.target_path) {
- case cgltf_animation_path_type_rotation:
- data_type = KEYFRAME_ROTATION;
- break;
- case cgltf_animation_path_type_translation:
- data_type = KEYFRAME_TRANSLATION;
- break;
- case cgltf_animation_path_type_scale:
- data_type = KEYFRAME_SCALE;
- break;
- case cgltf_animation_path_type_weights:
- data_type = KEYFRAME_WEIGHTS;
- WARN("Morph target weights arent supported yet");
- return false;
- default:
- WARN("unsupported animation type");
- return false;
- }
-
- sampler.current_index = 0;
- sampler.animation.interpolation = INTERPOLATION_LINEAR; // NOTE: hardcoded for now
-
- // Keyframe times
- size_t n_frames = channel.sampler->input->count;
- CASSERT_MSG(channel.sampler->input->component_type == cgltf_component_type_r_32f,
- "Expected animation sampler input component to be type f32");
- f32* times = arena_alloc(arena, n_frames * sizeof(f32));
- sampler.animation.n_timestamps = n_frames;
- sampler.animation.timestamps = times;
- cgltf_accessor_unpack_floats(channel.sampler->input, times, n_frames);
-
- // Keyframe values
- size_t n_values = channel.sampler->output->count;
- CASSERT_MSG(n_frames == n_values, "keyframe times = keyframe values");
-
- Keyframes keyframes = { 0 };
- keyframes.kind = data_type;
- keyframes.count = n_values;
- keyframes.values = arena_alloc(arena, n_values * sizeof(Keyframe));
- for (cgltf_size v = 0; v < channel.sampler->output->count; ++v) {
- switch (data_type) {
- case KEYFRAME_ROTATION: {
- Quat rot;
- cgltf_accessor_read_float(channel.sampler->output, v, &rot.x, 4);
- // printf("Quat %f %f %f %f\n", rot.x, rot.y, rot.z, rot.w);
- keyframes.values[v].rotation = rot;
- break;
- }
- case KEYFRAME_TRANSLATION: {
- Vec3 trans;
- cgltf_accessor_read_float(channel.sampler->output, v, &trans.x, 3);
- keyframes.values[v].translation = trans;
- break;
- }
- case KEYFRAME_SCALE: {
- Vec3 scale;
- cgltf_accessor_read_float(channel.sampler->output, v, &scale.x, 3);
- keyframes.values[v].scale = scale;
- break;
- }
- case KEYFRAME_WEIGHTS: {
- // TODO: morph weights
- break;
- }
- }
- }
- sampler.animation.values = keyframes;
- sampler.min = channel.sampler->input->min[0];
- sampler.max = channel.sampler->input->max[0];
-
- // *target_property = sampler;
- printf("%d timestamps between %f and %f\n", sampler.animation.n_timestamps, sampler.min,
- sampler.max);
-
- // TODO: get target
- size_t target_index = cgltf_node_index(data, channel.target_node);
- size_t joint_index = 0;
- bool found = false;
- for (u32 ji = 0; ji < main_skeleton.joints->len; ji++) {
- if (main_skeleton.joints->data[ji].node_idx == target_index) {
- joint_index = ji;
- found = true;
- break;
- }
- }
- if (!found) {
- WARN("Coulndnt find joint index");
- }
- sampler.target_joint_idx =
- joint_index; // NOTE: this assuming the target is a joint at the moment
- AnimationSampler_darray_push(clip.channels, sampler);
- }
-
- AnimationClip_darray_push(out_model->animations, clip);
- }
- }
-
- // exit(0);
- }
-
- num_meshes = tmp_meshes->len;
-
- // we now have an array of meshes, materials, and the material which each mesh should get
- out_model->meshes = malloc(num_meshes * sizeof(MeshHandle));
- out_model->mesh_count = num_meshes;
- out_model->materials = malloc(num_materials * sizeof(MaterialHandle));
- out_model->material_count = num_materials;
-
- MaterialHandle* mat_handles = calloc(num_materials, sizeof(MaterialHandle));
- for (u32 mat_i = 0; mat_i < num_materials; mat_i++) {
- mat_handles[mat_i] =
- Material_pool_insert(Render_GetMaterialPool(), &tmp_materials->data[mat_i]);
- }
- memcpy(out_model->materials, mat_handles, num_materials * sizeof(MaterialHandle));
-
- for (u32 mesh_i = 0; mesh_i < num_meshes; mesh_i++) {
- i32 mat_idx = tmp_material_indexes->data[mesh_i];
- if (mat_idx > 0) {
- tmp_meshes->data[mesh_i].material = mat_handles[mat_idx];
-
- } else {
- Material default_mat = PBRMaterialDefault();
- tmp_meshes->data[mesh_i].material =
- Material_pool_insert(Render_GetMaterialPool(), &default_mat);
- }
- MeshHandle mesh = Mesh_pool_insert(Render_GetMeshPool(), &tmp_meshes->data[mesh_i]);
- out_model->meshes[mesh_i] = mesh;
- }
-
- free(mat_handles);
-
- return true;
-}
-
-const char* bool_yes_no(bool pred) { return pred ? "Yes" : "No"; }
-
-// Loads all materials
-size_t GLTF_LoadMaterials(cgltf_data* data, Str8 relative_path, Material_darray* out_materials) {
- size_t num_materials = data->materials_count;
- TRACE("Num materials %d", num_materials);
- for (size_t m = 0; m < num_materials; m++) {
- cgltf_material gltf_material = data->materials[m];
- TRACE("Loading material '%s'", gltf_material.name);
- cgltf_pbr_metallic_roughness pbr = gltf_material.pbr_metallic_roughness;
-
- Material our_material = PBRMaterialDefault(); // focusing on PBR materials for now
-
- our_material.base_colour =
- vec3(pbr.base_color_factor[0], pbr.base_color_factor[1], pbr.base_color_factor[2]);
- our_material.metallic = pbr.metallic_factor;
- our_material.roughness = pbr.roughness_factor;
-
- // -- albedo / base colour
- cgltf_texture_view albedo_tex_view = pbr.base_color_texture;
- bool has_albedo_texture = albedo_tex_view.texture != NULL;
- TRACE("Has PBR base colour texture? %s", bool_yes_no(has_albedo_texture));
- printf("Base colour factor: %f %f %f\n", pbr.base_color_factor[0], pbr.base_color_factor[1],
- pbr.base_color_factor[2]);
- if (has_albedo_texture) {
- char albedo_map_path[1024];
- snprintf(albedo_map_path, sizeof(albedo_map_path), "%s/%s", relative_path.buf,
- albedo_tex_view.texture->image->uri);
- our_material.albedo_map = TextureLoadFromFile(albedo_map_path);
- } else {
- our_material.albedo_map = Render_GetWhiteTexture();
- WARN("GLTF model has no albedo map");
- our_material.base_colour =
- vec3_create(pbr.base_color_factor[0], pbr.base_color_factor[1], pbr.base_color_factor[2]);
- }
-
- // -- metallic
- cgltf_texture_view metal_rough_tex_view = pbr.metallic_roughness_texture;
- printf("Metal factor: %f\n", pbr.metallic_factor);
- printf("Roughness factor: %f\n", pbr.roughness_factor);
- if (metal_rough_tex_view.texture != NULL) {
- char metal_rough_map_path[1024];
- snprintf(metal_rough_map_path, sizeof(metal_rough_map_path), "%s/%s", relative_path.buf,
- metal_rough_tex_view.texture->image->uri);
- our_material.metallic_roughness_map = TextureLoadFromFile(metal_rough_map_path);
- } else {
- WARN("GLTF model has no metal/roughness map");
- our_material.metallic = pbr.metallic_factor;
- our_material.roughness = pbr.roughness_factor;
- }
-
- cgltf_texture_view normal_tex_view = gltf_material.normal_texture;
- if (normal_tex_view.texture != NULL) {
- char normal_map_path[1024];
- snprintf(normal_map_path, sizeof(normal_map_path), "%s/%s", relative_path.buf,
- normal_tex_view.texture->image->uri);
- our_material.normal_map = TextureLoadFromFile(normal_map_path);
- } else {
- WARN("GLTF model has no normal map");
- }
-
- u32 string_length = strlen(gltf_material.name) + 1;
- assert(string_length < 64);
- strcpy(our_material.name, gltf_material.name);
-
- Material_darray_push(out_materials, our_material);
- }
-
- return out_materials->len;
-}
diff --git a/src/resources/loaders.h b/src/resources/loaders.h
deleted file mode 100644
index ea1f9a2..0000000
--- a/src/resources/loaders.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "defines.h"
-#include "render_types.h"
-#include "str.h"
-
-// --- Public API
-PUB ModelHandle ModelLoad_obj(const char* path, bool invert_texture_y);
-PUB ModelHandle ModelLoad_gltf(const char* path, bool invert_texture_y);
-
-typedef struct GLTF_LoadStats {
- u32 mesh_count, material_count, vertex_count, index_count, animation_count, joint_count;
-} GLTF_LoadStats;
-
-// --- Internal
-bool model_load_gltf_str(const char* file_string, const char* filepath, Str8 relative_path,
- Model* out_model, bool invert_textures_y);
diff --git a/src/resources/obj.c b/src/resources/obj.c
deleted file mode 100644
index a5e9b18..0000000
--- a/src/resources/obj.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/**
- * @file obj.c
- * @brief Wavefront OBJ loader.
- * @copyright Copyright (c) 2024
- */
-#include <ctype.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "core.h"
-#include "darray.h"
-#include "file.h"
-#include "log.h"
-#include "maths.h"
-#include "mem.h"
-#include "platform.h"
-#include "render.h"
-#include "render_types.h"
-#include "str.h"
-
-extern Core g_core;
-
-struct face {
- u32 vertex_indices[3];
- u32 normal_indices[3];
- u32 uv_indices[3];
-};
-typedef struct face face;
-
-KITC_DECL_TYPED_ARRAY(Vec3)
-KITC_DECL_TYPED_ARRAY(Vec2)
-KITC_DECL_TYPED_ARRAY(face)
-
-// Forward declarations
-// void create_submesh(mesh_darray *meshes, Vec3_darray *tmp_positions, Vec3_darray *tmp_normals,
-// Vec2_darray *tmp_uvs, face_darray *tmp_faces, material_darray *materials,
-// bool material_loaded, char current_material_name[256]);
-// bool load_material_lib(const char *path, str8 relative_path, material_darray *materials);
-// bool model_load_obj_str(const char *file_string, str8 relative_path, Model *out_model,
-// bool invert_textures_y);
-
-ModelHandle model_load_obj(Core* core, const char* path, bool invert_textures_y) {
- size_t arena_size = 1024;
- arena scratch = arena_create(malloc(arena_size), arena_size);
-
- TRACE("Loading model at Path %s\n", path);
- path_opt relative_path = path_parent(&scratch, path);
- if (!relative_path.has_value) {
- WARN("Couldnt get a relative path for the path to use for loading materials & textures later");
- }
- 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);
-
- // bool success = model_load_obj_str(file_string, relative_path.path, &model, invert_textures_y);
-
- // if (!success) {
- // FATAL("Couldnt load OBJ file at path %s", path);
- // ERROR_EXIT("Load fails are considered crash-worthy right now. This will change later.\n");
- // }
-
- // arena_free_all(&scratch);
- // arena_free_storage(&scratch);
- return handle;
-}
-
-bool model_load_obj_str(const char* file_string, Str8 relative_path, Model* out_model,
- bool invert_textures_y) {
- TRACE("Load OBJ from string");
-
- // // Setup temps
- // vec3_darray *tmp_positions = vec3_darray_new(1000);
- // vec3_darray *tmp_normals = vec3_darray_new(1000);
- // vec2_darray *tmp_uvs = vec2_darray_new(1000);
- // face_darray *tmp_faces = face_darray_new(1000);
- // // TODO: In the future I'd like these temporary arrays to be allocated from an arena provided
- // // by the function one level up, model_load_obj. That way we can just `return false;` anywhere
- // in
- // // this code to indicate an error, and be sure that all that memory will be cleaned up without
- // // having to call vec3_darray_free in every single error case before returning.
-
- // // Other state
- // bool object_set = false;
- // bool material_loaded = false;
- // char current_material_name[64];
-
- // char *pch;
- // char *rest = file_string;
- // pch = strtok_r((char *)file_string, "\n", &rest);
-
- // int line_num = 0;
- // char last_char_type = 'a';
-
- // while (pch != NULL) {
- // line_num++;
- // char line_header[128];
- // int offset = 0;
-
- // // skip whitespace
- // char *p = pch;
-
- // skip_space(pch);
-
- // if (*p == '\0') {
- // /* the string is empty */
- // } else {
- // // read the first word of the line
- // int res = sscanf(pch, "%s %n", line_header, &offset);
- // /* printf("header: %s, offset : %d res: %d\n",line_header, offset, res); */
- // if (res != 1) {
- // break;
- // }
-
- // if (strcmp(line_header, "o") == 0 || strcmp(line_header, "g") == 0) {
- // // if we're currently parsing one
- // if (!object_set) {
- // object_set = true;
- // } else {
- // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
- // NULL, // out_model->materials,
- // material_loaded, current_material_name);
- // object_set = false;
- // }
- // } else if (strcmp(line_header, "v") == 0) {
- // // special logic: if we went from faces back to vertices trigger a mesh output.
- // // PS: I hate OBJ
- // if (last_char_type == 'f') {
- // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
- // NULL, // FIXME: out_model->materials,
- // material_loaded, current_material_name);
- // object_set = false;
- // }
-
- // last_char_type = 'v';
- // vec3 vertex;
- // sscanf(pch + offset, "%f %f %f", &vertex.x, &vertex.y, &vertex.z);
-
- // vec3_darray_push(tmp_positions, vertex);
- // } else if (strcmp(line_header, "vt") == 0) {
- // last_char_type = 't';
- // vec2 uv;
- // char copy[1024];
- // memcpy(copy, pch + offset, strlen(pch + offset) + 1);
- // char *p = pch + offset;
- // while (isspace((unsigned char)*p)) ++p;
-
- // // I can't remember what is going on here
- // memset(copy, 0, 1024);
- // memcpy(copy, pch + offset, strlen(pch + offset) + 1);
- // int res = sscanf(copy, "%f %f", &uv.x, &uv.y);
- // memset(copy, 0, 1024);
- // memcpy(copy, pch + offset, strlen(pch + offset) + 1);
- // if (res != 1) {
- // // da frick? some .obj files have 3 uvs instead of 2
- // f32 dummy;
- // int res2 = sscanf(copy, "%f %f %f", &uv.x, &uv.y, &dummy);
- // }
-
- // if (invert_textures_y) {
- // uv.y = -uv.y; // flip Y axis to be consistent with how other PNGs are being handled
- // // `texture_load` will flip it again
- // }
- // vec2_darray_push(tmp_uvs, uv);
- // } else if (strcmp(line_header, "vn") == 0) {
- // last_char_type = 'n';
- // vec3 normal;
- // sscanf(pch + offset, "%f %f %f", &normal.x, &normal.y, &normal.z);
- // vec3_darray_push(tmp_normals, normal);
- // } else if (strcmp(line_header, "f") == 0) {
- // last_char_type = 'f';
- // struct face f;
- // sscanf(pch + offset, "%d/%d/%d %d/%d/%d %d/%d/%d", &f.vertex_indices[0],
- // &f.uv_indices[0],
- // &f.normal_indices[0], &f.vertex_indices[1], &f.uv_indices[1],
- // &f.normal_indices[1], &f.vertex_indices[2], &f.uv_indices[2],
- // &f.normal_indices[2]);
- // // printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", f.vertex_indices[0], f.uv_indices[0],
- // // f.normal_indices[0],
- // // f.vertex_indices[1], f.uv_indices[1], f.normal_indices[1],
- // // f.vertex_indices[2], f.uv_indices[2], f.normal_indices[2]);
- // face_darray_push(tmp_faces, f);
- // } else if (strcmp(line_header, "mtllib") == 0) {
- // char filename[1024];
- // sscanf(pch + offset, "%s", filename);
- // char mtllib_path[1024];
- // snprintf(mtllib_path, sizeof(mtllib_path), "%s/%s", relative_path.buf, filename);
- // if (!load_material_lib(mtllib_path, relative_path, out_model->materials)) {
- // ERROR("couldnt load material lib");
- // return false;
- // }
- // } else if (strcmp(line_header, "usemtl") == 0) {
- // material_loaded = true;
- // sscanf(pch + offset, "%s", current_material_name);
- // }
- // }
-
- // pch = strtok_r(NULL, "\n", &rest);
- // }
-
- // // last mesh or if one wasnt created with 'o' directive
- // if (face_darray_len(tmp_faces) > 0) {
- // TRACE("Last leftover mesh");
- // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
- // NULL, // TODO: out_model->materials,
- // material_loaded, current_material_name);
- // }
-
- // // Free data
- // free((char *)file_string);
- // vec3_darray_free(tmp_positions);
- // vec3_darray_free(tmp_normals);
- // vec2_darray_free(tmp_uvs);
- // face_darray_free(tmp_faces);
- // TRACE("Freed temporary OBJ loading data");
-
- // if (mesh_darray_len(out_model->meshes) > 256) {
- // printf("num meshes: %ld\n", mesh_darray_len(out_model->meshes));
- // }
-
- // // TODO: bounding box calculation for each mesh
- // // TODO: bounding box calculation for model
-
- // TODO: copy from mesh_darray to malloc'd mesh* array
-
- return true;
-}
-
-// /**
-// * @brief Takes the current positions, normals, uvs arrays and constructs the vertex array
-// * from those indices.
-// */
-// void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray *tmp_normals,
-// vec2_darray *tmp_uvs, face_darray *tmp_faces, material_darray *materials,
-// bool material_loaded, char current_material_name[256]) {
-// // size_t num_verts = face_darray_len(tmp_faces) * 3;
-// // vertex_darray *out_vertices = vertex_darray_new(num_verts);
-
-// // face_darray_iter face_iter = face_darray_iter_new(tmp_faces);
-// // struct face *f;
-
-// // while ((f = face_darray_iter_next(&face_iter))) {
-// // for (int j = 0; j < 3; j++) {
-// // vertex vert = { 0 };
-// // vert.position = tmp_positions->data[f->vertex_indices[j] - 1];
-// // if (vec3_darray_len(tmp_normals) == 0) {
-// // vert.normal = vec3_create(0.0, 0.0, 0.0);
-// // } else {
-// // vert.normal = tmp_normals->data[f->normal_indices[j] - 1];
-// // }
-// // vert.uv = tmp_uvs->data[f->uv_indices[j] - 1];
-// // vertex_darray_push(out_vertices, vert);
-// // }
-// // }
-
-// // DEBUG("Loaded submesh\n vertices: %zu\n uvs: %zu\n normals: %zu\n faces: %zu",
-// // vec3_darray_len(tmp_positions), vec2_darray_len(tmp_uvs),
-// vec3_darray_len(tmp_normals),
-// // face_darray_len(tmp_faces));
-
-// // // Clear current object faces
-// // face_darray_clear(tmp_faces);
-
-// // mesh m = { .vertices = out_vertices };
-// // if (material_loaded) {
-// // // linear scan to find material
-// // bool found = false;
-// // DEBUG("Num of materials : %ld", material_darray_len(materials));
-// // material_darray_iter mat_iter = material_darray_iter_new(materials);
-// // blinn_phong_material *cur_material;
-// // while ((cur_material = material_darray_iter_next(&mat_iter))) {
-// // if (strcmp(cur_material->name, current_material_name) == 0) {
-// // DEBUG("Found match");
-// // m.material_index = mat_iter.current_idx - 1;
-// // found = true;
-// // break;
-// // }
-// // }
-
-// // if (!found) {
-// // // TODO: default material
-// // m.material_index = 0;
-// // DEBUG("Set default material");
-// // }
-// // }
-// // mesh_darray_push(meshes, m);
-// }
-
-// bool load_material_lib(const char *path, str8 relative_path, material_darray *materials) {
-// TRACE("BEGIN load material lib at %s", path);
-
-// // const char *file_string = string_from_file(path);
-// // if (file_string == NULL) {
-// // ERROR("couldnt load %s", path);
-// // return false;
-// // }
-
-// // char *pch;
-// // char *saveptr;
-// // pch = strtok_r((char *)file_string, "\n", &saveptr);
-
-// // material current_material = DEFAULT_MATERIAL;
-
-// // bool material_set = false;
-
-// // while (pch != NULL) {
-// // char line_header[128];
-// // int offset = 0;
-// // // read the first word of the line
-// // int res = sscanf(pch, "%s %n", line_header, &offset);
-// // if (res != 1) {
-// // break;
-// // }
-
-// // // When we see "newmtl", start a new material, or flush the previous one
-// // if (strcmp(line_header, "newmtl") == 0) {
-// // if (material_set) {
-// // // a material was being parsed, so flush that one and start a new one
-// // material_darray_push(materials, current_material);
-// // DEBUG("pushed material with name %s", current_material.name);
-// // WARN("Reset current material");
-// // current_material = DEFAULT_MATERIAL;
-// // } else {
-// // material_set = true;
-// // }
-// // // scan the new material name
-// // char material_name[64];
-// // sscanf(pch + offset, "%s", current_material.name);
-// // DEBUG("material name %s\n", current_material.name);
-// // // current_material.name = material_name;
-// // } else if (strcmp(line_header, "Ka") == 0) {
-// // // ambient
-// // sscanf(pch + offset, "%f %f %f", &current_material.ambient_colour.x,
-// // &current_material.ambient_colour.y, &current_material.ambient_colour.z);
-// // } else if (strcmp(line_header, "Kd") == 0) {
-// // // diffuse
-// // sscanf(pch + offset, "%f %f %f", &current_material.diffuse.x,
-// &current_material.diffuse.y,
-// // &current_material.diffuse.z);
-// // } else if (strcmp(line_header, "Ks") == 0) {
-// // // specular
-// // sscanf(pch + offset, "%f %f %f", &current_material.specular.x,
-// // &current_material.specular.y,
-// // &current_material.specular.z);
-// // } else if (strcmp(line_header, "Ns") == 0) {
-// // // specular exponent
-// // sscanf(pch + offset, "%f", &current_material.spec_exponent);
-// // } else if (strcmp(line_header, "map_Kd") == 0) {
-// // char diffuse_map_filename[1024];
-// // sscanf(pch + offset, "%s", diffuse_map_filename);
-// // char diffuse_map_path[1024];
-// // snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf,
-// // diffuse_map_filename);
-// // printf("load from %s\n", diffuse_map_path);
-
-// // // --------------
-// // texture diffuse_texture = texture_data_load(diffuse_map_path, true);
-// // current_material.diffuse_texture = diffuse_texture;
-// // strcpy(current_material.diffuse_tex_path, diffuse_map_path);
-// // texture_data_upload(&current_material.diffuse_texture);
-// // // --------------
-// // } else if (strcmp(line_header, "map_Ks") == 0) {
-// // // char specular_map_path[1024] = "assets/";
-// // // sscanf(pch + offset, "%s", specular_map_path + 7);
-// // char specular_map_filename[1024];
-// // sscanf(pch + offset, "%s", specular_map_filename);
-// // char specular_map_path[1024];
-// // snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf,
-// // specular_map_filename);
-// // printf("load from %s\n", specular_map_path);
-// // // --------------
-// // texture specular_texture = texture_data_load(specular_map_path, true);
-// // current_material.specular_texture = specular_texture;
-// // strcpy(current_material.specular_tex_path, specular_map_path);
-// // texture_data_upload(&current_material.specular_texture);
-// // // --------------
-// // } else if (strcmp(line_header, "map_Bump") == 0) {
-// // // TODO
-// // }
-
-// // pch = strtok_r(NULL, "\n", &saveptr);
-// // }
-
-// // TRACE("end load material lib");
-
-// // // last mesh or if one wasnt created with 'o' directive
-// // // TRACE("Last leftover material");
-// // material_darray_push(materials, current_material);
-
-// // INFO("Loaded %ld materials", material_darray_len(materials));
-// TRACE("END load material lib");
-// return true;
-// }
diff --git a/src/std/buf.h b/src/std/buf.h
deleted file mode 100644
index 77fc7b9..0000000
--- a/src/std/buf.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * @file buf.h
- * @brief
- */
-#pragma once
-#include "defines.h"
-
-typedef struct bytebuffer {
- u8* buf;
- size_t size;
-} bytebuffer;
diff --git a/src/std/containers/container_utils.h b/src/std/containers/container_utils.h
deleted file mode 100644
index e1d164c..0000000
--- a/src/std/containers/container_utils.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * @file container_utils.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-06-19
- *
- * @copyright Copyright (c) 2024
- *
- */
-
-#pragma once
-
-typedef struct generic_iterator {
-} generic_iterator;
-
-typedef void* (*iterator_next_item)(void* iterator); \ No newline at end of file
diff --git a/src/std/containers/darray.h b/src/std/containers/darray.h
deleted file mode 100644
index 080afb4..0000000
--- a/src/std/containers/darray.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * @file darray.h
- * @brief Typed dynamic array
- * @copyright Copyright (c) 2023
- */
-// COPIED FROM KITC WITH SOME MINOR ADJUSTMENTS
-
-/* TODO:
- - a 'find' function that takes a predicate (maybe wrap with a macro so we dont have to define a
- new function?)
-*/
-
-#ifndef KITC_TYPED_ARRAY_H
-#define KITC_TYPED_ARRAY_H
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define DARRAY_DEFAULT_CAPACITY 64
-#define DARRAY_RESIZE_FACTOR 3
-
-/** @brief create a new darray type and functions with type `N` */
-#define typed_array(T) \
- struct { \
- /* @brief current number of items in the array */ \
- size_t len; \
- size_t capacity; \
- T* data; \
- }
-
-#define typed_array_iterator(T) \
- struct { \
- T##_darray* array; \
- size_t current_idx; \
- }
-
-#define PREFIX static
-
-#define KITC_DECL_TYPED_ARRAY(T) DECL_TYPED_ARRAY(T, T)
-
-#define DECL_TYPED_ARRAY(T, Type) \
- typedef typed_array(T) Type##_darray; \
- typedef typed_array_iterator(Type) Type##_darray_iter; \
- \
- /* Create a new one growable array */ \
- PREFIX Type##_darray* Type##_darray_new(size_t starting_capacity) { \
- Type##_darray* d; \
- T* data; \
- d = malloc(sizeof(Type##_darray)); \
- data = malloc(starting_capacity * sizeof(T)); \
- \
- d->len = 0; \
- d->capacity = starting_capacity; \
- d->data = data; \
- \
- return d; \
- } \
- \
- PREFIX void Type##_darray_free(Type##_darray* d) { \
- if (d != NULL) { \
- free(d->data); \
- free(d); \
- } \
- } \
- \
- PREFIX T* Type##_darray_resize(Type##_darray* d, size_t capacity) { \
- /* resize the internal data block */ \
- T* new_data = realloc(d->data, sizeof(T) * capacity); \
- /* TODO: handle OOM error */ \
- \
- d->capacity = capacity; \
- d->data = new_data; \
- return new_data; \
- } \
- \
- PREFIX void Type##_darray_push(Type##_darray* d, T value) { \
- if (d->len >= d->capacity) { \
- size_t new_capacity = \
- d->capacity > 0 ? d->capacity * DARRAY_RESIZE_FACTOR : DARRAY_DEFAULT_CAPACITY; \
- T* resized = Type##_darray_resize(d, new_capacity); \
- (void)resized; \
- } \
- \
- d->data[d->len] = value; \
- d->len += 1; \
- } \
- \
- PREFIX void Type##_darray_push_copy(Type##_darray* d, const T* value) { \
- if (d->len >= d->capacity) { \
- size_t new_capacity = \
- d->capacity > 0 ? d->capacity * DARRAY_RESIZE_FACTOR : DARRAY_DEFAULT_CAPACITY; \
- T* resized = Type##_darray_resize(d, new_capacity); \
- (void)resized; \
- } \
- \
- T* place = d->data + d->len; \
- d->len += 1; \
- memcpy(place, value, sizeof(T)); \
- } \
- \
- PREFIX void Type##_darray_pop(Type##_darray* d, T* dest) { \
- T* item = d->data + (d->len - 1); \
- d->len -= 1; \
- memcpy(dest, item, sizeof(T)); \
- } \
- \
- PREFIX void Type##_darray_ins(Type##_darray* d, const T* value, size_t index) { \
- /* check if requires resize */ \
- if (d->len + 1 > d->capacity) { \
- size_t new_capacity = \
- d->capacity > 0 ? d->capacity * DARRAY_RESIZE_FACTOR : DARRAY_DEFAULT_CAPACITY; \
- T* resized = Type##_darray_resize(d, new_capacity); \
- (void)resized; \
- } \
- \
- /* shift existing data after index */ \
- T* insert_dest = d->data + index; \
- T* shift_dest = insert_dest + 1; \
- \
- int num_items = d->len - index; \
- \
- d->len += 1; \
- memcpy(shift_dest, insert_dest, num_items * sizeof(T)); \
- memcpy(insert_dest, value, sizeof(T)); \
- } \
- \
- PREFIX void Type##_darray_clear(Type##_darray* d) { \
- d->len = 0; \
- memset(d->data, 0, d->capacity * sizeof(T)); \
- } \
- \
- PREFIX size_t Type##_darray_len(Type##_darray* d) { return d->len; } \
- \
- PREFIX Type##_darray_iter Type##_darray_iter_new(Type##_darray* d) { \
- Type##_darray_iter iterator; \
- iterator.array = d; \
- iterator.current_idx = 0; \
- return iterator; \
- } \
- \
- PREFIX void* Type##_darray_iter_next(Type##_darray_iter* iterator) { \
- if (iterator->current_idx < iterator->array->len) { \
- return &iterator->array->data[iterator->current_idx++]; \
- } else { \
- return NULL; \
- } \
- }
-
-#endif // KITC_TYPED_ARRAY_H
diff --git a/src/std/containers/graphs.h b/src/std/containers/graphs.h
deleted file mode 100644
index 5dbec97..0000000
--- a/src/std/containers/graphs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * @file graphs.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-04-27
- *
- * @copyright Copyright (c) 2024
- *
- */
-
-// Adjacency list backed graphs
-
-// Matrix backed graphs (not as useful) \ No newline at end of file
diff --git a/src/std/containers/hashmap.h b/src/std/containers/hashmap.h
deleted file mode 100644
index 95c1c6b..0000000
--- a/src/std/containers/hashmap.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * @file hashmap.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-04-27
- *
- * @copyright Copyright (c) 2024
- *
- */
-
-typedef struct hashmap hashmap;
-
-/*
-Example usage
--------------
-init hashmap
-insert (string, material)
-get (string) -> material_opt or material* ?
-
-*/
-
-void hashmap_init(hashmap* map);
-
-// ...
-
-void hashmap_free(hashmap* map); \ No newline at end of file
diff --git a/src/std/containers/hashset.h b/src/std/containers/hashset.h
deleted file mode 100644
index 7f87213..0000000
--- a/src/std/containers/hashset.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file hashset.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-04-27
- *
- * @copyright Copyright (c) 2024
- *
- */
-
-#include "defines.h"
-
-typedef struct hashset hashset;
-
-/** @brief Describes a function that will take a pointer to a datatype (e.g. a u64 or a struct)
- and return a hashed key. */
-typedef uint64_t (*hash_item)(void* item);
-
-void hashset_init(hashset* set, hash_item hash_func, size_t initial_capacity);
-// TODO: void hashset_from_iterator();
-bool hashset_insert(hashset* set, void* item, uint64_t* out_key);
-void hashset_batch_insert(hashset* set, void* items, u64 item_count);
-bool hashset_contains(hashset* set, void* item);
-bool hashset_remove_item(hashset* set, void* item);
-bool hashset_remove_key(hashset* set, uint64_t key);
-void hashset_merge(hashset* set_a, hashset* set_b);
-hashset* hashset_merge_cloned(hashset* set_a, hashset* set_b);
-void hashset_free(hashset* set); \ No newline at end of file
diff --git a/src/std/containers/ring_queue.c b/src/std/containers/ring_queue.c
deleted file mode 100644
index 8bfc10b..0000000
--- a/src/std/containers/ring_queue.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "ring_queue.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include "defines.h"
-
-ring_queue* ring_queue_new(size_t type_size, size_t capacity, void* memory) {
- ring_queue* q = malloc(sizeof(ring_queue));
- q->len = 0;
- q->capacity = capacity;
- q->type_size = type_size;
- q->head = 0;
- q->tail = -1;
-
- if (memory) {
- // caller owns the memory
- q->owns_memory = false;
- q->data = memory;
- } else {
- // ring queue should own the memory
- q->owns_memory = true;
- q->data = malloc(capacity * type_size);
- }
-
- return q;
-}
-
-void ring_queue_free(ring_queue* queue) {
- if (queue) {
- if (queue->owns_memory) {
- free(queue->data);
- }
- free(queue);
- }
-}
-
-bool ring_queue_enqueue(ring_queue* queue, const void* value) {
- if (queue->len == queue->capacity) {
- return false;
- }
-
- queue->tail = (queue->tail + 1) % queue->capacity;
- memcpy(queue->data + (queue->tail * queue->type_size), value, queue->type_size);
- queue->len++;
- return true;
-}
-
-bool ring_queue_dequeue(ring_queue* queue, void* out_value) {
- if (queue->len == 0) {
- // queue is empty
- return false;
- }
-
- memcpy(out_value, queue->data + (queue->head * queue->type_size), queue->type_size);
- queue->head = (queue->head + 1) % queue->capacity;
- queue->len--;
- return true;
-}
-
-bool ring_queue_peek(const ring_queue* queue, void* out_value) {
- if (queue->len == 0) {
- // queue is empty
- return false;
- }
-
- memcpy(out_value, queue->data + (queue->head * queue->type_size), queue->type_size);
- return true;
-} \ No newline at end of file
diff --git a/src/std/containers/ring_queue.h b/src/std/containers/ring_queue.h
deleted file mode 100644
index 15d5da4..0000000
--- a/src/std/containers/ring_queue.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file ring_queue.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-02-24
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-#include "defines.h"
-
-/**
- * @brief a fixed-size ring queue
- */
-typedef struct ring_queue {
- size_t len;
- size_t capacity;
- size_t type_size;
- void* data;
- bool owns_memory;
- int32_t head;
- int32_t tail;
-} ring_queue;
-
-ring_queue* ring_queue_new(size_t type_size, size_t capacity, void* memory_block);
-
-void ring_queue_free(ring_queue* queue);
-
-bool ring_queue_enqueue(ring_queue* queue, const void* value);
-
-bool ring_queue_dequeue(ring_queue* queue, void* out_value);
-
-bool ring_queue_peek(const ring_queue* queue, void* out_value); \ No newline at end of file
diff --git a/src/std/containers/stack_array.h b/src/std/containers/stack_array.h
deleted file mode 100644
index d2b6bdd..0000000
--- a/src/std/containers/stack_array.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-#include <stdbool.h>
-
-// Defines "_sarray" types
-
-#define TYPED_STACK_ARRAY(T, Name, Len) \
- typedef struct Name##_sarray { \
- T items[ Len ]; \
- size_t len; \
- } Name##_sarray; \
- Name##_sarray Name##_sarray_create() { \
- Name##_sarray arr = { .len = 0 }; \
- return arr; \
- } \
- bool Name##_sarray_push(Name##_sarray* arr, T item) { \
- if (arr->len == Len) { return false; }\
- arr->items[arr->len++] = item;\
- return true;\
- }
diff --git a/src/std/mem.c b/src/std/mem.c
deleted file mode 100644
index 1f9078b..0000000
--- a/src/std/mem.c
+++ /dev/null
@@ -1,135 +0,0 @@
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "log.h"
-#include "mem.h"
-
-#ifndef DEFAULT_ALIGNMENT
-#define DEFAULT_ALIGNMENT (2 * sizeof(void*))
-#endif
-
-// --- Arena
-
-void* arena_alloc_align(arena* a, size_t size, size_t align) {
- ptrdiff_t padding = -(uintptr_t)a->curr & (align - 1);
- ptrdiff_t available = a->end - a->curr - padding;
- // TRACE("Padding %td available %td", padding, available);
- if (available < 0 || (ptrdiff_t)size > available) {
- ERROR_EXIT("Arena ran out of memory\n");
- }
- void* p = a->curr + padding;
- a->curr += padding + size;
- return memset(p, 0, size);
-}
-void* arena_alloc(arena* a, size_t size) { return arena_alloc_align(a, size, DEFAULT_ALIGNMENT); }
-
-arena arena_create(void* backing_buffer, size_t capacity) {
- return (arena){ .begin = backing_buffer,
- .curr = backing_buffer,
- .end = backing_buffer + (ptrdiff_t)capacity };
-}
-
-void arena_free_all(arena* a) {
- a->curr = a->begin; // pop everything at once and reset to the start.
-}
-
-void arena_free_storage(arena* a) { free(a->begin); }
-
-arena_save arena_savepoint(arena* a) {
- arena_save savept = { .arena = a, .savepoint = a->curr };
- return savept;
-}
-
-void arena_rewind(arena_save savepoint) { savepoint.arena->curr = savepoint.savepoint; }
-
-// --- Pool
-
-void_pool void_pool_create(arena* a, const char* debug_label, u64 capacity, u64 entry_size) {
- size_t memory_requirements = capacity * entry_size;
- void* backing_buf = arena_alloc(a, memory_requirements);
-
- assert(entry_size >= sizeof(void_pool_header)); // TODO: create my own assert with error message
-
- void_pool pool = { .capacity = capacity,
- .entry_size = entry_size,
- .count = 0,
- .backing_buffer = backing_buf,
- .free_list_head = NULL,
- .debug_label = debug_label };
-
- void_pool_free_all(&pool);
-
- return pool;
-}
-
-void void_pool_free_all(void_pool* pool) {
- // set all entries to be free
- for (u64 i = 0; i < pool->capacity; i++) {
- void* ptr = &pool->backing_buffer[i * pool->entry_size];
- void_pool_header* free_node =
- (void_pool_header*)ptr; // we reuse the actual entry itself to hold the header
- if (i == (pool->capacity - 1)) {
- // if the last one we make its next pointer NULL indicating its full
- free_node->next = NULL;
- }
- free_node->next = pool->free_list_head;
- // now the head points to this entry
- pool->free_list_head = free_node;
- }
-}
-
-void* void_pool_get(void_pool* pool, u32 raw_handle) {
- // An handle is an index into the array essentially
- void* ptr = pool->backing_buffer + (raw_handle * pool->entry_size);
- return ptr;
-}
-
-void* void_pool_alloc(void_pool* pool, u32* out_raw_handle) {
- // get the next free node
- if (pool->count == pool->capacity) {
- WARN("Pool is full!");
- return NULL;
- }
- if (pool->free_list_head == NULL) {
- ERROR("%s Pool is full (head = null)", pool->debug_label);
- return NULL;
- }
- void_pool_header* free_node = pool->free_list_head;
-
- // What index does this become?
- uintptr_t start = (uintptr_t)pool->backing_buffer;
- uintptr_t cur = (uintptr_t)free_node;
- // TRACE("%ld %ld ", start, cur);
- assert(cur > start);
- u32 index = (u32)((cur - start) / pool->entry_size);
- /* printf("Index %d\n", index); */
- if (out_raw_handle != NULL) {
- *out_raw_handle = index;
- }
-
- pool->free_list_head = free_node->next;
-
- memset(free_node, 0, pool->entry_size);
- pool->count++;
- return (void*)free_node;
-}
-
-void void_pool_dealloc(void_pool* pool, u32 raw_handle) {
- // push free node back onto the free list
- void* ptr = void_pool_get(pool, raw_handle);
- void_pool_header* freed_node = (void_pool_header*)ptr;
-
- freed_node->next = pool->free_list_head;
- pool->free_list_head = freed_node;
-
- pool->count--;
-}
-
-u32 void_pool_insert(void_pool* pool, void* item) {
- u32 raw_handle;
- void* item_dest = void_pool_alloc(pool, &raw_handle);
- memcpy(item_dest, item, pool->entry_size);
- return raw_handle;
-}
diff --git a/src/std/mem.h b/src/std/mem.h
deleted file mode 100644
index 56c1230..0000000
--- a/src/std/mem.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * @file mem.h
- * @brief Allocators, memory tracking
- * @version 0.1
- * @date 2024-02-24
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include <stddef.h>
-#include "defines.h"
-
-typedef void* (*alloc_fn)(size_t size);
-typedef void (*free_fn)(void* ptr);
-
-typedef struct allocator_t {
- alloc_fn alloc;
- free_fn free;
-} allocator_t;
-
-// --- Arena
-
-// Inspired by https://nullprogram.com/blog/2023/09/27/
-typedef struct arena {
- char* begin;
- char* curr;
- char* end;
-} arena;
-
-typedef struct arena_save {
- arena* arena;
- char* savepoint;
-} arena_save;
-
-arena arena_create(void* backing_buffer, size_t capacity);
-void* arena_alloc(arena* a, size_t size);
-void* arena_alloc_align(arena* a, size_t size, size_t align);
-void arena_free_all(arena* a);
-void arena_free_storage(arena* a);
-arena_save arena_savepoint(arena* a);
-void arena_rewind(arena_save savepoint);
-// TODO: arena_resize
-
-// --- Pool
-
-typedef struct void_pool_header void_pool_header;
-struct void_pool_header {
- void_pool_header* next;
-};
-
-typedef struct void_pool {
- u64 capacity;
- u64 entry_size;
- u64 count;
- void* backing_buffer;
- void_pool_header* free_list_head;
- const char* debug_label;
-} void_pool;
-
-void_pool void_pool_create(arena* a, const char* debug_label, u64 capacity, u64 entry_size);
-void void_pool_free_all(void_pool* pool);
-bool void_pool_is_empty(void_pool* pool);
-bool void_pool_is_full(void_pool* pool);
-void* void_pool_get(void_pool* pool, u32 raw_handle);
-void* void_pool_alloc(void_pool* pool, u32* out_raw_handle);
-void void_pool_dealloc(void_pool* pool, u32 raw_handle);
-u32 void_pool_insert(void_pool* pool, void* item);
-// TODO: fn to dealloc from the pointer that was handed out
-
-// TODO: macro that lets us specialise
-
-/* typedef struct Name##_handle Name##_handle; \ */
-#define TYPED_POOL(T, Name) \
- typedef struct Name##_pool { \
- void_pool inner; \
- } Name##_pool; \
- \
- static Name##_pool Name##_pool_create(arena* a, u64 cap, u64 entry_size) { \
- void_pool p = void_pool_create(a, "\"" #Name "\"", cap, entry_size); \
- return (Name##_pool){ .inner = p }; \
- } \
- static inline T* Name##_pool_get(Name##_pool* pool, Name##Handle handle) { \
- return (T*)void_pool_get(&pool->inner, handle.raw); \
- } \
- static inline T* Name##_pool_alloc(Name##_pool* pool, Name##Handle* out_handle) { \
- return (T*)void_pool_alloc(&pool->inner, &out_handle->raw); \
- } \
- static inline void Name##_pool_dealloc(Name##_pool* pool, Name##Handle handle) { \
- void_pool_dealloc(&pool->inner, handle.raw); \
- } \
- static Name##Handle Name##_pool_insert(Name##_pool* pool, T* item) { \
- u32 raw_handle = void_pool_insert(pool, item); \
- return (Name##Handle){ .raw = raw_handle }; \
- }
diff --git a/src/std/str.c b/src/std/str.c
deleted file mode 100644
index 89c76a0..0000000
--- a/src/std/str.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include "str.h"
-#include <assert.h>
-#include <string.h>
-#include "log.h"
-#include "mem.h"
-
-Str8 Str8_create(u8* buf, size_t len) { return (Str8){ .buf = buf, .len = len }; }
-
-Str8 Str8_cstr_view(char* string) { return Str8_create((u8*)string, strlen(string)); }
-
-bool Str8_equals(Str8 a, Str8 b) {
- if (a.len != b.len) {
- return false;
- }
-
- for (size_t i = 0; i < a.len; i++) {
- if (a.buf[i] != b.buf[i]) {
- return false;
- }
- }
- return true;
-}
-
-char* Str8_to_cstr(arena* a, Str8 s) {
- bool is_null_terminated = s.buf[s.len - 1] == 0;
- size_t n_bytes = is_null_terminated ? s.len : s.len + 1;
-
- u8* dest = arena_alloc(a, n_bytes);
-
- memcpy(dest, s.buf, s.len);
- if (is_null_terminated) {
- dest[s.len] = '\0';
- }
- return (char*)dest;
-}
-
-char* Clone_cstr(arena* a, const char* s) {
- if (s == NULL) {
- WARN("Tried to clone a NULL char*");
- return NULL;
- }
- Str8 st = Str8_cstr_view(s);
- return Str8_to_cstr(a, st);
-}
-
-Str8 Str8_concat(arena* a, Str8 left, Str8 right) {
- size_t n_bytes = left.len + right.len + 1;
-
- u8* dest = arena_alloc(a, n_bytes);
- memcpy(dest, left.buf, left.len);
- memcpy(dest + right.len, right.buf, right.len);
-
- dest[n_bytes - 1] = '\0';
-
- return Str8_create(dest, n_bytes);
-}
-
-Str8 Str8_substr(Str8 s, u64 min, u64 max) {
- assert(min >= 0);
- assert(min < s.len);
- assert(max >= 0);
- assert(max <= s.len);
- uint8_t* start = s.buf + (ptrdiff_t)min;
- size_t new_len = max - min;
- return (Str8){ .buf = start, .len = new_len };
-}
-
-Str8 Str8_take(Str8 s, u64 first_n) { return Str8_substr(s, 0, first_n); }
-
-Str8 Str8_drop(Str8 s, u64 last_n) { return Str8_substr(s, s.len - last_n, s.len); }
-
-Str8 Str8_skip(Str8 s, u64 n) { return Str8_substr(s, n, s.len); }
-
-Str8 Str8_chop(Str8 s, u64 n) { return Str8_substr(s, 0, s.len - n); }
diff --git a/src/std/str.h b/src/std/str.h
deleted file mode 100644
index a29bf9a..0000000
--- a/src/std/str.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file str.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-02-25
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include <ctype.h>
-
-#include "defines.h"
-#include "mem.h"
-
-/**
- * @brief Fat pointer representing a UTF8 (TODO some APIs supporting utf8) encoded string
- * @note when using `printf` you must use %s.*s length, string until our own modified
- print routines are written. alternatively wrap in `cstr()` and pass to `%s`.
- */
-typedef struct {
- u8* buf;
- size_t len;
-} Str8;
-
-// --- Constructors
-
-/** @brief Take a string literal and turn it into a `str8` */
-#define str8(s) \
- (Str8) { (u8*)s, ((sizeof(s) / sizeof(*(s)) - 1)) }
-
-Str8 Str8_create(u8* buf, size_t len);
-
-// TODO: Str8_OntoArena(arena* a, Str8 s);
-
-/** @brief Return a null-terminated C string cloned onto an arena */
-char* Str8_to_cstr(arena* a, Str8 s);
-
-#define cstr(a, s) (Str8_to_cstr(a, s)) // Shorthand
-
-/** @brief Return a Str8 that references a statically allocated string.
- `string` therefore must already be null-terminated.
- @note The backing `string` cannot be modified. */
-Str8 Str8_cstr_view(char* string);
-
-char* Clone_cstr(arena* a, const char* s);
-
-// --- Comparisons
-
-/** @brief Compare two strings for exact equality */
-bool Str8_equals(Str8 a, Str8 b);
-
-/**
- * @brief Compare the first `first_nchars` of each string for equality
- * @details If either of the strings are shorter than the number only the characters up until the
- end of the shorter string will be compared.
- * @returns 0 if they are fully equal up until `first_nchars`, i.e they never differed, else it
- returns the index at which the first string differed from the second string.
-*/
-size_t Str8_nequals(Str8 a, Str8 b, size_t first_nchars);
-
-bool Str8_ends_with(Str8 input_str, Str8 suffix);
-
-/// --- Subviews
-
-Str8 Str8_substr(Str8 s, u64 min, u64 max);
-/** @brief Keeps only the `first_n` chars of `s` */
-Str8 Str8_take(Str8 s, u64 first_n);
-/** @brief Keeps only the `last_n` chars of `s` */
-Str8 Str8_drop(Str8 s, u64 last_n);
-/** @brief Keeps everything after the first `n` chars of `s` */
-Str8 Str8_skip(Str8 s, u64 n);
-/** @brief Keeps everything before the last `n` chars of `s` */
-Str8 Str8_chop(Str8 s, u64 n);
-
-Str8 Str8_concat(arena* a, Str8 left, Str8 right);
-
-/// --- Misc
-
-static inline bool Str8_is_null_term(Str8 a) {
- return a.buf[a.len] == 0; // This doesn't seem safe. YOLO
-}
-
-// TODO: move or delete this and replace with handling using our internal type
-static void skip_space(char* p) {
- while (isspace((unsigned char)*p)) ++p;
-}
diff --git a/src/std/utils.h b/src/std/utils.h
deleted file mode 100644
index c9827a3..0000000
--- a/src/std/utils.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#pragma once
-#include <stdbool.h>
-
-const char* bool_str(bool input) { return input ? "True" : "False"; } \ No newline at end of file
diff --git a/src/systems/grid.c b/src/systems/grid.c
deleted file mode 100644
index e907865..0000000
--- a/src/systems/grid.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "grid.h"
-#include "file.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"
-#include "render.h"
-#include "render_types.h"
-#include "shader_layouts.h"
-
-void Grid_Init(Grid_Storage* storage) {
- INFO("Infinite Grid initialisation");
- Geometry plane_geo = Geo_CreatePlane(f32x2(1.0, 1.0), 1, 1);
- Mesh plane_mesh = Mesh_Create(&plane_geo, true);
- storage->plane_vertices = plane_mesh.vertex_buffer;
-
- u32 indices[6] = { 5, 4, 3, 2, 1, 0 };
- storage->plane_indices =
- GPU_BufferCreate(6 * sizeof(u32), BUFFER_INDEX, BUFFER_FLAG_GPU, &indices);
-
- GPU_RenderpassDesc rpass_desc = {
- .default_framebuffer = true,
- };
- storage->renderpass = GPU_Renderpass_Create(rpass_desc);
-
- arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
-
- Str8 vert_path = str8("assets/shaders/grid.vert");
- Str8 frag_path = str8("assets/shaders/grid.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")
- }
-
- ShaderDataLayout camera_data = Binding_Camera_GetLayout(NULL);
-
- GraphicsPipelineDesc pipeline_desc = {
- .debug_name = "Infinite grid pipeline",
- .vertex_desc = static_3d_vertex_description(),
- .data_layouts = { camera_data },
- .data_layouts_count = 1,
- .vs = {
- .debug_name = "Grid vertex shader",
- .filepath = vert_path,
- .code = vertex_shader.contents,
- },
- .fs = {
- .debug_name = "Grid fragment shader",
- .filepath = frag_path,
- .code = fragment_shader.contents,
- },
- .wireframe = false,
- };
- storage->pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, storage->renderpass);
-}
-
-void Grid_Draw() {
- Grid_Storage* grid = Render_GetGridStorage();
- Grid_Execute(grid);
-}
-
-void Grid_Execute(Grid_Storage* storage) {
- RenderScene* scene = Render_GetScene();
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
- GPU_CmdEncoder_BeginRender(enc, storage->renderpass);
- GPU_EncodeBindPipeline(enc, storage->pipeline);
- Mat4 view, proj;
- u32x2 dimensions = GPU_Swapchain_GetDimensions();
- Camera camera = scene->camera;
- Camera_ViewProj(&camera, (f32)dimensions.x, (f32)dimensions.y, &view, &proj);
- Binding_Camera camera_data = { .view = view,
- .projection = proj,
- .viewPos = vec4(camera.position.x, camera.position.y,
- camera.position.z, 1.0) };
- GPU_EncodeBindShaderData(enc, 0, Binding_Camera_GetLayout(&camera_data));
- GPU_EncodeSetVertexBuffer(enc, storage->plane_vertices);
- GPU_EncodeSetIndexBuffer(enc, storage->plane_indices);
- GPU_EncodeDrawIndexedTris(enc, 6);
- GPU_CmdEncoder_EndRender(enc);
-}
diff --git a/src/systems/grid.h b/src/systems/grid.h
deleted file mode 100644
index d8bc567..0000000
--- a/src/systems/grid.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include "ral_impl.h"
-#include "ral_types.h"
-
-typedef struct Grid_Storage {
- GPU_Renderpass* renderpass;
- GPU_Pipeline* pipeline;
- BufferHandle plane_vertices;
- BufferHandle plane_indices;
-} Grid_Storage;
-
-// --- Public API
-PUB void Grid_Init(Grid_Storage* storage);
-// void Grid_Shutdown(Grid_Storage* storage);
-PUB void Grid_Draw();
-
-// --- Internal
-void Grid_Execute(Grid_Storage* storage);
-// typedef struct GridUniforms {} GridUniforms;
-// ShaderDataLayout GridUniforms_GetLayout(void* data); \ No newline at end of file
diff --git a/src/systems/input.c b/src/systems/input.c
deleted file mode 100644
index c3af96a..0000000
--- a/src/systems/input.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "input.h"
-
-#include <assert.h>
-#include <glfw3.h>
-#include <string.h>
-
-#include "keys.h"
-#include "log.h"
-
-static Input_State* g_input; // Use a global to simplify caller code
-
-bool Input_Init(Input_State* input, GLFWwindow* window) {
- INFO("Input init");
- memset(input, 0, sizeof(Input_State));
-
- input->window = window;
- // Set everything to false. Could just set memory to zero but where's the fun in that
- for (int i = KEYCODE_SPACE; i < KEYCODE_MAX; i++) {
- input->depressed_keys[i] = false;
- input->just_pressed_keys[i] = false;
- input->just_released_keys[i] = false;
- }
-
- g_input = input;
-
- assert(input->mouse.x_delta == 0);
- assert(input->mouse.y_delta == 0);
-
- INFO("Finish input init");
- return true;
-}
-
-void Input_Shutdown(Input_State* input) {}
-
-void Input_Update(Input_State* input) {
- glfwPollEvents();
- // --- update keyboard input
-
- // if we go from un-pressed -> pressed, set as "just pressed"
- // if we go from pressed -> un-pressed, set as "just released"
- for (int i = KEYCODE_SPACE; i < KEYCODE_MAX; i++) {
- bool new_state = false;
- if (glfwGetKey(input->window, i) == GLFW_PRESS) {
- new_state = true;
- } else {
- new_state = false;
- }
- if (!input->depressed_keys[i] == false && new_state) {
- input->just_pressed_keys[i] = true;
- } else {
- input->just_pressed_keys[i] = false;
- }
-
- if (input->depressed_keys[i] && !new_state) {
- input->just_released_keys[i] = true;
- } else {
- input->just_released_keys[i] = false;
- }
-
- input->depressed_keys[i] = new_state;
- }
-
- // --- update mouse input
-
- // cursor position
- f64 current_x, current_y;
- glfwGetCursorPos(input->window, &current_x, &current_y);
- i32 quantised_cur_x = (i32)current_x;
- i32 quantised_cur_y = (i32)current_y;
-
- mouse_state new_mouse_state = { 0 };
- new_mouse_state.x = quantised_cur_x;
- new_mouse_state.y = quantised_cur_y;
- new_mouse_state.x_delta = quantised_cur_x - input->mouse.x;
- new_mouse_state.y_delta = quantised_cur_y - input->mouse.y;
-
- // buttons
- int left_state = glfwGetMouseButton(input->window, GLFW_MOUSE_BUTTON_LEFT);
- int right_state = glfwGetMouseButton(input->window, GLFW_MOUSE_BUTTON_RIGHT);
-
- for (int i = 0; i < 3; i++) {
- new_mouse_state.prev_pressed_states[i] = input->mouse.cur_pressed_states[i];
- }
- new_mouse_state.cur_pressed_states[MOUSEBTN_LEFT] = left_state == GLFW_PRESS;
- new_mouse_state.cur_pressed_states[MOUSEBTN_RIGHT] = right_state == GLFW_PRESS;
-
- // this was dumb! need to also check button state changes lol
- // if (new_mouse_state.x != input->mouse.x || new_mouse_state.y != input->mouse.y)
- // TRACE("Mouse (x,y) = (%d,%d)", input->mouse.x, input->mouse.y);
-
- input->mouse = new_mouse_state;
-}
-
-bool key_is_pressed(keycode key) { return g_input->depressed_keys[key]; }
-
-bool key_just_pressed(keycode key) { return g_input->just_pressed_keys[key]; }
-
-bool key_just_released(keycode key) { return g_input->just_released_keys[key]; }
-
-bool MouseBtn_Held(MouseBtn btn) {
- assert(btn < 3);
- return g_input->mouse.prev_pressed_states[btn] && g_input->mouse.cur_pressed_states[btn];
-}
-
-mouse_state Input_GetMouseState() { return g_input->mouse; } \ No newline at end of file
diff --git a/src/systems/input.h b/src/systems/input.h
deleted file mode 100644
index c3b2500..0000000
--- a/src/systems/input.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @brief
- */
-#pragma once
-
-#include "defines.h"
-#include "keys.h"
-
-struct GLFWWindow;
-
-typedef enum MouseBtn {
- MOUSEBTN_LEFT = 0,
- MOUSEBTN_RIGHT = 1,
- MOUSEBTN_MIDDLE = 2,
-} MouseBtn;
-
-typedef struct mouse_state {
- i32 x;
- i32 y;
- i32 x_delta;
- i32 y_delta;
- bool prev_pressed_states[3];
- bool cur_pressed_states[3];
-} mouse_state;
-
-typedef struct Input_State {
- struct GLFWwindow* window;
- mouse_state mouse;
- bool depressed_keys[KEYCODE_MAX];
- bool just_pressed_keys[KEYCODE_MAX];
- bool just_released_keys[KEYCODE_MAX];
-} Input_State;
-
-/** @brief `key` is currently being held down */
-PUB bool key_is_pressed(keycode key);
-
-/** @brief `key` was just pressed */
-PUB bool key_just_pressed(keycode key);
-
-/** @brief `key` was just released */
-PUB bool key_just_released(keycode key);
-
-// TODO: right btn as well
-PUB bool MouseBtn_Held(MouseBtn btn);
-
-// --- Lifecycle
-
-PUB bool Input_Init(Input_State* input, struct GLFWwindow* window);
-PUB void Input_Shutdown(Input_State* input);
-
-PUB void Input_Update(Input_State* state); // must be run once per main loop
-
-PUB mouse_state Input_GetMouseState(); \ No newline at end of file
diff --git a/src/systems/keys.h b/src/systems/keys.h
deleted file mode 100644
index 6082a59..0000000
--- a/src/systems/keys.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-typedef enum keycode {
- // TODO: add all keycodes
- KEYCODE_SPACE = 32,
- KEYCODE_APOSTROPHE = 39,
- KEYCODE_COMMA = 44,
- KEYCODE_MINUS = 45,
- KEYCODE_PERIOD = 46,
- KEYCODE_SLASH = 47,
- KEYCODE_0 = 48,
- KEYCODE_1 = 49,
- KEYCODE_2 = 50,
- KEYCODE_3 = 51,
- KEYCODE_4 = 52,
- KEYCODE_5 = 53,
- KEYCODE_6 = 54,
- KEYCODE_7 = 55,
- KEYCODE_8 = 56,
- KEYCODE_9 = 57,
- KEYCODE_SEMICOLON = 59,
- KEYCODE_EQUAL = 61,
- KEYCODE_A = 65,
- KEYCODE_B = 66,
- KEYCODE_C = 67,
- KEYCODE_D = 68,
- KEYCODE_E = 69,
- KEYCODE_F = 70,
- KEYCODE_G = 71,
- KEYCODE_H = 72,
- KEYCODE_I = 73,
- KEYCODE_J = 74,
- KEYCODE_K = 75,
- KEYCODE_L = 76,
- KEYCODE_M = 77,
- KEYCODE_N = 78,
- KEYCODE_O = 79,
- KEYCODE_P = 80,
- KEYCODE_Q = 81,
- KEYCODE_R = 82,
- KEYCODE_S = 83,
- KEYCODE_T = 84,
- KEYCODE_U = 85,
- KEYCODE_V = 86,
- KEYCODE_W = 87,
- KEYCODE_X = 88,
- KEYCODE_Y = 89,
- KEYCODE_Z = 90,
-
- KEYCODE_ESCAPE = 256,
- KEYCODE_ENTER = 257,
- KEYCODE_TAB = 258,
- KEYCODE_BACKSPACE = 259,
- KEYCODE_KEY_RIGHT = 262,
- KEYCODE_KEY_LEFT = 263,
- KEYCODE_KEY_DOWN = 264,
- KEYCODE_KEY_UP = 265,
- KEYCODE_MAX = 348
-} keycode;
diff --git a/src/systems/screenspace.h b/src/systems/screenspace.h
deleted file mode 100644
index 5f0c579..0000000
--- a/src/systems/screenspace.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @brief Drawing shapes for UI or other reasons in screenspace
- */
-#pragma once
-
-#include "colours.h"
-#include "darray.h"
-#include "defines.h"
-#include "render_types.h"
-
-/** A draw_cmd packet for rendering a rectangle */
-struct draw_rect {
- i32 x, y; // signed ints so we can draw things offscreen (e.g. a window half inside the viewport)
- u32 width, height;
- rgba colour;
- // TODO: border colour, gradients
-};
-
-/** A draw_cmd packet for rendering a circle */
-struct draw_circle {
- i32 x, y;
- f32 radius;
- rgba colour;
-};
-
-/** @brief Tagged union that represents a UI shape to be drawn. */
-typedef struct draw_cmd {
- enum { DRAW_RECT, CIRCLE } draw_cmd_type;
- union {
- struct draw_rect rect;
- struct draw_circle circle;
- };
-} draw_cmd;
-
-KITC_DECL_TYPED_ARRAY(draw_cmd)
-
-typedef struct screenspace_state {
- u32 rect_vbo;
- u32 rect_vao;
- // shader rect_shader;
- draw_cmd_darray* draw_cmd_buf;
-} screenspace_state;
-
-// --- Lifecycle
-bool screenspace_2d_init(screenspace_state* state);
-void screenspace_2d_shutdown(screenspace_state* state);
-/** Drains the draw_cmd buffer and emits draw calls to render each one */
-void screenspace_2d_render(screenspace_state* state);
-
-struct core;
-
-/** @brief Draw a rectangle to the screen. (0,0) is the bottom-left */
-void draw_rectangle(struct core* core, rgba colour, i32 x, i32 y, u32 width, u32 height); \ No newline at end of file
diff --git a/src/systems/terrain.c b/src/systems/terrain.c
deleted file mode 100644
index 069000e..0000000
--- a/src/systems/terrain.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * @brief
- */
-#include "terrain.h"
-#include <assert.h>
-#include "file.h"
-#include "glad/glad.h"
-#include "log.h"
-#include "maths.h"
-#include "mem.h"
-#include "ral_common.h"
-#include "ral_impl.h"
-#include "ral_types.h"
-#include "render.h"
-#include "shader_layouts.h"
-#include "str.h"
-
-#define TERRAIN_GRID_U 505
-#define TERRAIN_GRID_V 505
-
-bool Terrain_Init(Terrain_Storage* storage) {
- storage->grid_dimensions = u32x2(TERRAIN_GRID_U, TERRAIN_GRID_V);
- storage->hmap_loaded = false;
-
- GPU_RenderpassDesc rpass_desc = {
- .default_framebuffer = true,
- };
- storage->hmap_renderpass = GPU_Renderpass_Create(rpass_desc);
-
- arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
-
- Str8 vert_path = str8("assets/shaders/terrain.vert");
- Str8 frag_path = str8("assets/shaders/terrain.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")
- }
-
- ShaderDataLayout camera_data = Binding_Camera_GetLayout(NULL);
- ShaderDataLayout terrain_data = TerrainUniforms_GetLayout(NULL);
-
- GraphicsPipelineDesc pipeline_desc = {
- .debug_name = "terrain rendering pipeline",
- .vertex_desc = static_3d_vertex_description(),
- .data_layouts = { camera_data, terrain_data },
- .data_layouts_count = 2,
- .vs = {
- .debug_name = "terrain vertex shader",
- .filepath = vert_path,
- .code = vertex_shader.contents,
- },
- .fs = {
- .debug_name = "terrain fragment shader",
- .filepath = frag_path,
- .code = fragment_shader.contents,
- },
- .wireframe = false,
- };
- storage->hmap_pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, storage->hmap_renderpass);
-
- storage->texture = TextureLoadFromFile("assets/demo/textures/grass2.png");
-
- return true;
-}
-
-void Terrain_Shutdown(Terrain_Storage* storage) {}
-
-void Terrain_LoadHeightmap(Terrain_Storage* storage, Heightmap hmap, f32 grid_scale,
- bool free_on_upload) {
- // If there's a current one we will delete it and reallocate buffers
- if (storage->hmap_loaded) {
- GPU_BufferDestroy(storage->vertex_buffer);
- GPU_BufferDestroy(storage->index_buffer);
- }
-
- u32 width = hmap.pixel_dimensions.x;
- u32 height = hmap.pixel_dimensions.y;
- storage->grid_scale = grid_scale;
-
- size_t num_vertices = storage->grid_dimensions.x * storage->grid_dimensions.y;
- storage->num_vertices = num_vertices;
-
- Vertex_darray* vertices = Vertex_darray_new(num_vertices);
- u32 index = 0;
- for (u32 i = 0; i < storage->grid_dimensions.x; i++) {
- for (u32 j = 0; j < storage->grid_dimensions.y; j++) {
- size_t position = j * storage->grid_dimensions.x + i;
- u8* bytes = hmap.image_data;
- u8 channel = bytes[position];
- float value = (float)channel / 255.0;
- // printf("(%d, %d) %d : %f \n", i, j, channel, value);
-
- assert(index < num_vertices);
- f32 height = Heightmap_HeightXZ(&hmap, i, j);
- Vec3 v_pos = vec3_create(i * grid_scale, height, j * grid_scale);
- Vec3 v_normal = VEC3_Y;
- float tiling_factor = 505.0f;
- Vec2 v_uv = vec2((f32)i / width * tiling_factor, (f32)j / height * tiling_factor);
- Vertex v = { .static_3d = { .position = v_pos, .normal = v_normal, .tex_coords = v_uv } };
- Vertex_darray_push(vertices, v);
- index++;
- }
- }
- BufferHandle vertices_handle = GPU_BufferCreate(num_vertices * sizeof(Vertex), BUFFER_VERTEX,
- BUFFER_FLAG_GPU, vertices->data);
- storage->vertex_buffer = vertices_handle;
-
- u32 quad_count = (width - 1) * (height - 1);
- u32 indices_count = quad_count * 6;
- storage->indices_count = indices_count;
- u32_darray* indices = u32_darray_new(indices_count);
- for (u32 i = 0; i < (width - 1); i++) { // row
- for (u32 j = 0; j < (height - 1); j++) { // col
- u32 bot_left = i * width + j;
- u32 top_left = (i + 1) * width + j;
- u32 top_right = (i + 1) * width + (j + 1);
- u32 bot_right = i * width + j + 1;
-
- // top left tri
- u32_darray_push(indices, top_right);
- u32_darray_push(indices, top_left);
- u32_darray_push(indices, bot_left);
-
- // bottom right tri
- u32_darray_push(indices, bot_right);
- u32_darray_push(indices, top_right);
- u32_darray_push(indices, bot_left);
- }
- }
-
- BufferHandle indices_handle =
- GPU_BufferCreate(indices_count * sizeof(u32), BUFFER_INDEX, BUFFER_FLAG_GPU, indices->data);
- storage->index_buffer = indices_handle;
-}
-
-Heightmap Heightmap_FromImage(Str8 filepath) {
- size_t max_size = MB(16);
- arena arena = arena_create(malloc(max_size), max_size);
- // str8_opt maybe_file = str8_from_file(&arena, filepath);
- // assert(maybe_file.has_value);
-
- TextureData hmap_tex = TextureDataLoad(Str8_to_cstr(&arena, filepath), false);
-
- // arena_free_storage(&arena);
-
- return (Heightmap){
- .pixel_dimensions = hmap_tex.description.extents,
- .filepath = filepath,
- .image_data = hmap_tex.image_data,
- .num_channels = hmap_tex.description.num_channels,
- .is_uploaded = false,
- };
-}
-
-void Terrain_Draw(Terrain_Storage* storage) {
- GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
- GPU_EncodeBindPipeline(enc, storage->hmap_pipeline);
- RenderScene* scene = Render_GetScene();
-
- Mat4 view, proj;
- u32x2 dimensions = GPU_Swapchain_GetDimensions();
- Camera_ViewProj(&scene->camera, (f32)dimensions.x, (f32)dimensions.y, &view, &proj);
- Binding_Camera camera_data = { .view = view,
- .projection = proj,
- .viewPos = vec4(scene->camera.position.x, scene->camera.position.y,
- scene->camera.position.z, 1.0) };
- GPU_EncodeBindShaderData(enc, 0, Binding_Camera_GetLayout(&camera_data));
-
- TerrainUniforms uniforms = { .tex_slot_1 = storage->texture };
- ShaderDataLayout terrain_data = TerrainUniforms_GetLayout(&uniforms);
- GPU_EncodeBindShaderData(enc, 1, terrain_data);
-
- GPU_EncodeSetVertexBuffer(enc, storage->vertex_buffer);
- GPU_EncodeSetIndexBuffer(enc, storage->index_buffer);
-
- GPU_EncodeDrawIndexedTris(enc, storage->indices_count);
- // glDrawArrays(GL_POINTS, 0, storage->num_vertices);
-}
-
-f32 Heightmap_HeightXZ(const Heightmap* hmap, u32 x, u32 z) {
- // its single channel so only one byte per pixel
- size_t position = x * hmap->pixel_dimensions.x + z;
- u8* bytes = hmap->image_data;
- u8 channel = bytes[position];
- float value = (float)channel / 2.0; /// 255.0;
- return value;
-}
-
-ShaderDataLayout TerrainUniforms_GetLayout(void* data) {
- TerrainUniforms* d = data;
- bool has_data = data != NULL;
-
- ShaderBinding b1 = {
- .label = "TextureSlot1",
- .kind = BINDING_TEXTURE,
- .vis = VISIBILITY_FRAGMENT,
- };
-
- if (has_data) {
- b1.data.texture.handle = d->tex_slot_1;
- }
- return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 };
-}
diff --git a/src/systems/terrain.h b/src/systems/terrain.h
deleted file mode 100644
index 5a96132..0000000
--- a/src/systems/terrain.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * @file terrain.h
- * @brief
- */
-
-#pragma once
-
-/*
-Future:
- - Chunked terrain
- - Dynamic LOD
-*/
-
-#include "defines.h"
-#include "maths_types.h"
-#include "ral_types.h"
-#include "render.h"
-#include "str.h"
-
-typedef struct Heightmap {
- Str8 filepath;
- u32x2 pixel_dimensions;
- void* image_data;
- u32 num_channels;
- bool is_uploaded;
-} Heightmap;
-
-typedef struct Terrain_Storage {
- // arena terrain_allocator;
- u32x2 grid_dimensions;
- f32 grid_scale;
- u32 num_vertices;
- Heightmap heightmap; // NULL = no heightmap
- GPU_Renderpass* hmap_renderpass;
- GPU_Pipeline* hmap_pipeline;
- TextureHandle texture;
-
- bool hmap_loaded;
- BufferHandle vertex_buffer;
- BufferHandle index_buffer;
- u32 indices_count;
-} Terrain_Storage;
-
-// --- Public API
-PUB bool Terrain_Init(Terrain_Storage* storage);
-PUB void Terrain_Shutdown(Terrain_Storage* storage);
-PUB void Terrain_Draw(
- Terrain_Storage* storage); // NOTE: For now it renders directly to main framebuffer
-
-/** @brief Sets the active heightmap to be rendered and collided against. */
-PUB void Terrain_LoadHeightmap(Terrain_Storage* storage, Heightmap hmap, f32 grid_scale,
- bool free_on_upload);
-PUB Heightmap Heightmap_FromImage(Str8 filepath);
-PUB Heightmap Heightmap_FromPerlin(/* TODO: perlin noise generation parameters */);
-
-PUB bool Terrain_IsActive(); // checks whether we have a loaded heightmap and it's being rendered
-
-/** @brief Get the height (the Y component) for a vertex at a particular coordinate in the heightmap
- */
-PUB f32 Heightmap_HeightXZ(const Heightmap* hmap, u32 x, u32 z);
-
-/** @brief Calculate the normal vector of a vertex at a particular coordinate in the heightmap */
-PUB Vec3 Heightmap_NormalXZ(const Heightmap* hmap, f32 x, f32 z);
-
-// /** @brief Generate the `geometry_data` for a heightmap ready to be uploaded to the GPU */
-// Geometry geo_heightmap(arena* a, Heightmap heightmap);
-
-typedef struct TerrainUniforms {
- TextureHandle tex_slot_1;
-} TerrainUniforms;
-
-ShaderDataLayout TerrainUniforms_GetLayout(void* data); \ No newline at end of file
diff --git a/src/systems/text.c b/src/systems/text.c
deleted file mode 100644
index 2bb5399..0000000
--- a/src/systems/text.c
+++ /dev/null
@@ -1 +0,0 @@
-// TODO: Port from previous repo \ No newline at end of file
diff --git a/src/systems/text.h b/src/systems/text.h
deleted file mode 100644
index 983ffd6..0000000
--- a/src/systems/text.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @brief
- */
-#pragma once
-
-#include <stb_truetype.h>
-
-#include "darray.h"
-#include "defines.h"
-#include "ral.h"
-#include "render_types.h"
-
-// struct core;
-
-// /** @brief internal font struct */
-// typedef struct font {
-// const char *name;
-// stbtt_fontinfo stbtt_font;
-// stbtt_bakedchar c_data[96];
-// texture_handle bitmap_tex;
-// } font;
-
-// typedef struct draw_text_packet {
-// char *contents;
-// f32 x;
-// f32 y;
-// } draw_text_packet;
-
-// KITC_DECL_TYPED_ARRAY(draw_text_packet)
-
-// typedef struct text_system_state {
-// font default_font;
-// shader_handle glyph_shader;
-// u32 glyph_vbo;
-// u32 glyph_vao;
-// draw_text_packet_darray *draw_cmd_buf;
-// // TODO: fonts array or hashtable
-// } text_system_state;
-
-// void text_system_render(text_system_state *text);
-
-// // --- Lifecycle functions
-// bool text_system_init(text_system_state *text);
-// void text_system_shutdown(text_system_state *text);
-
-// // --- Drawing
-
-// /**
-// * @brief immediate mode draw text.
-// * @note immediately emits draw calls causing a shader program switch if you weren't previously
-// drawing text in the current frame.
-// */
-// void draw_text(struct core *core, f32 x, f32 y, char *contents);
diff --git a/src/transform_hierarchy.c b/src/transform_hierarchy.c
deleted file mode 100644
index a5f4d97..0000000
--- a/src/transform_hierarchy.c
+++ /dev/null
@@ -1,185 +0,0 @@
-
-/**
- * @file transform_hierarchy.h
- */
-#pragma once
-#include "transform_hierarchy.h"
-#include <stdlib.h>
-#include <string.h>
-
-#include "core.h"
-#include "log.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "render_types.h"
-
-// struct transform_hierarchy {
-// transform_node root;
-// };
-
-// transform_hierarchy* transform_hierarchy_create() {
-// transform_hierarchy* tfh = malloc(sizeof(struct transform_hierarchy));
-
-// tfh->root = (transform_node){ .model = { ABSENT_MODEL_HANDLE },
-// .tf = TRANSFORM_DEFAULT,
-// .local_matrix_tf = mat4_ident(),
-// .world_matrix_tf = mat4_ident(),
-// .parent = NULL,
-// .children = { 0 },
-// .n_children = 0,
-// .tfh = tfh };
-// return tfh;
-// }
-
-// bool free_node(transform_node* node, void* _ctx_data) {
-// if (!node) return true; // leaf node
-// if (node == &node->tfh->root) {
-// WARN("You can't free the root node!");
-// return false;
-// }
-
-// printf("Freed node\n");
-// free(node);
-// return true;
-// }
-
-// void transform_hierarchy_free(transform_hierarchy* tfh) {
-// transform_hierarchy_dfs(&tfh->root, free_node, false, NULL);
-// free(tfh);
-// }
-
-// transform_node* transform_hierarchy_root_node(transform_hierarchy* tfh) { return &tfh->root; }
-
-// transform_node* transform_hierarchy_add_node(transform_node* parent, ModelHandle model,
-// Transform tf) {
-// if (!parent) {
-// WARN("You tried to add a node to a bad parent (NULL?)");
-// return NULL;
-// }
-// transform_node* node = malloc(sizeof(transform_node));
-// node->model = model;
-// node->tf = tf;
-// node->local_matrix_tf = mat4_ident();
-// node->world_matrix_tf = mat4_ident();
-// node->parent = parent;
-// memset(node->children, 0, sizeof(node->children));
-// node->n_children = 0;
-// node->tfh = parent->tfh;
-
-// // push into parent's children array
-// u32 next_index = parent->n_children;
-// if (next_index == MAX_TF_NODE_CHILDREN) {
-// ERROR("This transform hierarchy node already has MAX children. Dropping.");
-// free(node);
-// } else {
-// parent->children[next_index] = node;
-// parent->n_children++;
-// }
-
-// return node;
-// }
-
-// void transform_hierarchy_delete_node(transform_node* node) {
-// // delete all children
-// for (u32 i = 0; i < node->n_children; i++) {
-// transform_node* child = node->children[i];
-// transform_hierarchy_dfs(child, free_node, false, NULL);
-// }
-
-// if (node->parent) {
-// for (u32 i = 0; i < node->parent->n_children; i++) {
-// transform_node* child = node->parent->children[i];
-// if (child == node) {
-// node->parent->children[i] = NULL; // HACK: this will leave behind empty slots in the
-// // children array of the parent. oh well.
-// }
-// }
-// }
-
-// free(node);
-// }
-
-// void transform_hierarchy_dfs(transform_node* start_node,
-// bool (*visit_node)(transform_node* node, void* ctx_data),
-// bool is_pre_order, void* ctx_data) {
-// if (!start_node) return;
-
-// bool continue_traversal = true;
-// if (is_pre_order) {
-// continue_traversal = visit_node(start_node, ctx_data);
-// }
-
-// if (continue_traversal) {
-// for (u32 i = 0; i < start_node->n_children; i++) {
-// transform_node* child = start_node->children[i];
-// transform_hierarchy_dfs(child, visit_node, is_pre_order, ctx_data);
-// }
-// }
-
-// if (!is_pre_order) {
-// // post-order
-// visit_node(start_node, ctx_data);
-// }
-// }
-
-// // Update matrix for the current node
-// bool update_matrix(transform_node* node, void* _ctx_data) {
-// if (!node) return true; // leaf node
-
-// if (node->parent && node->parent->tf.is_dirty) {
-// node->tf.is_dirty = true;
-// }
-
-// if (node->tf.is_dirty) {
-// // invalidates children
-// Mat4 updated_local_transform = transform_to_mat(&node->tf);
-// node->local_matrix_tf = updated_local_transform;
-// if (node->parent) {
-// Mat4 updated_world_transform =
-// mat4_mult(node->parent->world_matrix_tf, updated_local_transform);
-// node->world_matrix_tf = updated_world_transform;
-// }
-// }
-
-// return true;
-// }
-
-// void transform_hierarchy_propagate_transforms(transform_hierarchy* tfh) {
-// // kickoff traversal
-// transform_hierarchy_dfs(&tfh->root, update_matrix, false, NULL);
-// }
-
-// struct print_ctx {
-// Core* core;
-// u32 indentation_lvl;
-// };
-
-// bool print_node(transform_node* node, void* ctx_data) {
-// struct print_ctx* ctx = (struct print_ctx*)ctx_data;
-
-// if (!node) return true;
-// if (!node->parent) {
-// printf("Root Node\n");
-// ctx->indentation_lvl++;
-// return true;
-// }
-
-// // Grab the model
-// // FIXME
-// // model m = ctx->core->models->data[node->model.raw];
-// for (int i = 0; i < ctx->indentation_lvl; i++) {
-// printf(" ");
-// }
-// // printf("Node %s\n", m.name.buf);
-// ctx->indentation_lvl++;
-
-// return true;
-// }
-
-// void transform_hierarchy_debug_print(transform_node* start_node, Core* core) {
-// struct print_ctx* ctx = malloc(sizeof(struct print_ctx));
-// ctx->core = core;
-// ctx->indentation_lvl = 0;
-// transform_hierarchy_dfs(start_node, print_node, true, (void*)ctx);
-// free(ctx);
-// }
diff --git a/src/transform_hierarchy.h b/src/transform_hierarchy.h
deleted file mode 100644
index 142ea99..0000000
--- a/src/transform_hierarchy.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file transform_hierarchy.h
- */
-#pragma once
-
-#include "maths_types.h"
-#include "ral.h"
-#include "render_types.h"
-
-#define MAX_TF_NODE_CHILDREN \
- 32 /** TEMP: Make it simpler to manage children in `transform_node`s */
-
-typedef struct TransformHierarchy TransformHierarchy;
-
-struct Transform_Node {
- ModelHandle model; /** A handle back to what model this node represents */
- Transform tf;
- Mat4 local_matrix_tf; /** cached local affine transform */
- Mat4 world_matrix_tf; /** cached world-space affine transform */
-
- struct transform_node* parent;
- struct transform_node* children[MAX_TF_NODE_CHILDREN];
- u32 n_children;
- struct transform_hierarchy* tfh;
-};
-typedef struct Transform_Node Transform_Node;
-typedef struct Transform_Node TF_Node;
-
-// --- Lifecycle
-
-/** @brief Allocates and returns an empty transform hierarchy with a root node */
-TransformHierarchy* TransformHierarchy_Create();
-
-// /**
-// * @brief recursively frees all the children and then finally itself
-// * @note in the future we can use an object pool for the nodes
-// */
-// void transform_hierarchy_free(transform_hierarchy* tfh);
-
-// // --- Main usecase
-
-// /** @brief Updates matrices of any invalidated nodes based on the `is_dirty` flag inside
-// `transform`
-// */
-// void transform_hierarchy_propagate_transforms(transform_hierarchy* tfh);
-
-// // --- Queries
-
-// /** @brief Get a pointer to the root node */
-// Transform_Node* TransformHierarchy_RootNode(TransformHierarchy* tfh);
-
-// // --- Mutations
-// Transform_Node* TransformHierarchy_AddNode(transform_node* parent, ModelHandle model,
-// Transform tf);
-// void transform_hierarchy_delete_node(transform_node* node);
-
-// // --- Traversal
-
-// /**
-// * @brief Perform a depth-first search traversal starting from `start_node`.
-// * @param start_node The starting node of the traversal.
-// * @param visit_node The function to call for each node visited. The callback should return false
-// to stop the traversal early.
-// * @param is_pre_order Indicates whether to do pre-order or post-order traversal i.e. when to
-// call the `visit_node` function.
-// * @param ctx_data An optional pointer to data that is be passed on each call to `visit_node`.
-// Can be used to carry additional information or context.
-// *
-// * @note The main use-cases are:
-// 1. traversing the whole tree to update cached 4x4 affine transform matrices
-// (post-order)
-// 2. freeing child nodes after deleting a node in the tree (post-order)
-// 3. debug pretty printing the whole tree (post-order)
-// */
-// void transform_hierarchy_dfs(transform_node* start_node,
-// bool (*visit_node)(transform_node* node, void* ctx_data),
-// bool is_pre_order, void* ctx_data);
-
-// struct Core;
-// void transform_hierarchy_debug_print(transform_node* start_node, struct Core* core);