summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindgen/BINDGEN.md1
-rw-r--r--examples/game_demo/game_demo.c73
-rw-r--r--scripts/gen_amalgamation.sh5
-rw-r--r--scripts/gen_apidocs.sh3
-rw-r--r--scripts/header_check.sh1
-rw-r--r--src/animation.c56
-rw-r--r--src/animation.h106
-rw-r--r--src/camera.c17
-rw-r--r--src/camera.h34
-rw-r--r--src/core.c89
-rw-r--r--src/core.h40
-rw-r--r--src/core/README.md3
-rw-r--r--src/core/camera.c21
-rw-r--r--src/core/camera.h37
-rw-r--r--src/core/core.c75
-rw-r--r--src/core/core.h21
-rw-r--r--src/defines.h22
-rw-r--r--src/maths/geometry.h42
-rw-r--r--src/maths/maths.h160
-rw-r--r--src/maths/maths_types.h49
-rw-r--r--src/maths/primitives.c71
-rw-r--r--src/maths/primitives.h10
-rw-r--r--src/new_render/draw.h13
-rw-r--r--src/new_render/immdraw.h14
-rw-r--r--src/new_render/pbr.h62
-rw-r--r--src/new_render/render.c34
-rw-r--r--src/new_render/render.h54
-rw-r--r--src/new_render/render_scene.h20
-rw-r--r--src/new_render/render_types.h86
-rw-r--r--src/new_render/shadows.h29
-rw-r--r--src/new_render/skybox.h32
-rw-r--r--src/platform/file.c6
-rw-r--r--src/platform/file.h6
-rw-r--r--src/platform/path.h4
-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.h76
-rw-r--r--src/ral/backends/vulkan/backend_vulkan.h0
-rw-r--r--src/ral/ral.h5
-rw-r--r--src/ral/ral_common.c19
-rw-r--r--src/ral/ral_common.h39
-rw-r--r--src/ral/ral_impl.h38
-rw-r--r--src/ral/ral_types.h223
-rw-r--r--src/render/backends/backend_test.c (renamed from src/renderer/backends/backend_test.c)0
-rw-r--r--src/render/backends/metal/README.md (renamed from src/renderer/backends/metal/README.md)0
-rw-r--r--src/render/backends/metal/backend_metal.h (renamed from src/renderer/backends/metal/backend_metal.h)0
-rw-r--r--src/render/backends/metal/backend_metal.m (renamed from src/renderer/backends/metal/backend_metal.m)0
-rw-r--r--src/render/backends/opengl/README.md (renamed from src/renderer/backends/opengl/README.md)0
-rw-r--r--src/render/backends/opengl/backend_opengl.c (renamed from src/renderer/backends/opengl/backend_opengl.c)0
-rw-r--r--src/render/backends/opengl/backend_opengl.h (renamed from src/renderer/backends/opengl/backend_opengl.h)0
-rw-r--r--src/render/backends/opengl/opengl_helpers.h (renamed from src/renderer/backends/opengl/opengl_helpers.h)0
-rw-r--r--src/render/backends/vulkan/README.md (renamed from src/renderer/backends/vulkan/README.md)0
-rw-r--r--src/render/backends/vulkan/backend_vulkan.c (renamed from src/renderer/backends/backend_vulkan.c)0
-rw-r--r--src/render/backends/vulkan/backend_vulkan.h (renamed from src/renderer/backends/backend_vulkan.h)0
-rw-r--r--src/render/backends/vulkan/vulkan_glossary.md (renamed from src/renderer/backends/vulkan/vulkan_glossary.md)0
-rw-r--r--src/render/backends/vulkan_helpers.h (renamed from src/renderer/backends/vulkan_helpers.h)0
-rw-r--r--src/render/bind_group_layouts.h (renamed from src/renderer/bind_group_layouts.h)0
-rw-r--r--src/render/builtin_materials.h (renamed from src/renderer/builtin_materials.h)0
-rw-r--r--src/render/immediate.c (renamed from src/renderer/immediate.c)0
-rw-r--r--src/render/immediate.h (renamed from src/renderer/immediate.h)0
-rw-r--r--src/render/ral.c (renamed from src/renderer/ral.c)0
-rw-r--r--src/render/ral.h (renamed from src/renderer/ral.h)50
-rw-r--r--src/render/ral_types.h104
-rw-r--r--src/render/render.c (renamed from src/renderer/render.c)0
-rw-r--r--src/render/render.h (renamed from src/renderer/render.h)10
-rw-r--r--src/render/render_types.h (renamed from src/renderer/render_types.h)0
-rw-r--r--src/render/renderpasses.c (renamed from src/renderer/renderpasses.c)0
-rw-r--r--src/render/renderpasses.h (renamed from src/renderer/renderpasses.h)0
-rw-r--r--src/render/static_pipeline.h (renamed from src/renderer/static_pipeline.h)0
-rw-r--r--src/renderer/backends/backend_dx11.c5
-rw-r--r--src/renderer/backends/backend_dx11.h29
-rw-r--r--src/renderer/ral_types.h268
-rw-r--r--src/resources/gltf.c232
-rw-r--r--src/resources/loaders.h10
-rw-r--r--src/resources/obj.c372
-rw-r--r--src/scene.c91
-rw-r--r--src/scene.h44
-rw-r--r--src/std/containers/darray.h11
-rw-r--r--src/std/mem.h6
-rw-r--r--src/std/str.c88
-rw-r--r--src/std/str.h36
-rw-r--r--src/systems/input.c12
-rw-r--r--src/systems/input.h13
-rw-r--r--src/systems/terrain.c35
-rw-r--r--src/systems/terrain.h50
-rw-r--r--src/systems/text.h82
-rw-r--r--src/transform_hierarchy.c343
-rw-r--r--src/transform_hierarchy.h109
-rw-r--r--src/ui/ui.h13
-rw-r--r--xmake.lua337
90 files changed, 2334 insertions, 1717 deletions
diff --git a/bindgen/BINDGEN.md b/bindgen/BINDGEN.md
new file mode 100644
index 0000000..20ba803
--- /dev/null
+++ b/bindgen/BINDGEN.md
@@ -0,0 +1 @@
+This is where we host code generation tools for generating bindings to `celeritas-core` in other languages.
diff --git a/examples/game_demo/game_demo.c b/examples/game_demo/game_demo.c
new file mode 100644
index 0000000..a9f91ea
--- /dev/null
+++ b/examples/game_demo/game_demo.c
@@ -0,0 +1,73 @@
+// Load a model
+// Animate it
+// Collide with the ground
+// Have a skybox
+
+#include <assert.h>
+#include "camera.h"
+#include "core.h"
+#include "maths.h"
+#include "render.h"
+#include "render_scene.h"
+#include "render_types.h"
+#include "skybox.h"
+#include "str.h"
+#include "terrain.h"
+#include "transform_hierarchy.h"
+
+static const char* faces[6] = { "assets/demo/skybox/left.jpg", "assets/demo/skybox/right.jpg",
+ "assets/demo/skybox/front.jpg", "assets/demo/skybox/back.jpg",
+ "assets/demo/skybox/top.jpg", "assets/demo/skybox/bottom.jpg" };
+
+int main() {
+ Core_Bringup();
+
+ Vec3 camera_pos = vec3(0.0, 4.0, 8.0);
+ Camera cam = Camera_Create(camera_pos, vec3_negate(camera_pos), VEC3_Y, 45.0);
+ SetCamera(cam); // update the camera in RenderScene
+
+ // TODO: Load humanoid model + weapon
+ // TODO: Animate it with WASD keys
+ // TODO: Skybox
+ // TODO: Add a ground terrain
+ // TODO: Move camera with model
+
+ // --- Terrain
+ Heightmap terrain = Heightmap_FromImage(str8("assets/demo/heightmap.png"));
+ Terrain_LoadHeightmap(terrain, true);
+ assert(Terrain_IsActive());
+
+ // --- Skybox
+ Skybox skybox = Skybox_Create(faces, 6);
+
+ // --- Models
+ ModelHandle player_model = ModelLoad("Player Model", "assets/demo/player.gltf");
+ ModelHandle sword_model = ModelLoad("Sword Model", "assets/demo/sword.gltf");
+
+ // --- Transforms
+ // TransformHierarchy* scene_tree = TransformHierarchy_Create();
+ // TODO: parent camera to model - to start with I can just manually update it every frame
+ // TODO: query joints of the gltf to get the hand bone to parent a sword to
+
+ RenderEnt player_r = { .model = player_model, .affine = mat4_ident(), .casts_shadows = true };
+
+ RenderEnt entities[] = { player_r };
+
+ while (!ShouldExit()) {
+ Frame_Begin();
+
+ // BEGIN Draw calls
+
+ // draw the player model with shadows
+ Render_RenderEntities(entities, 1);
+ Render_DrawTerrain();
+ Skybox_Draw(&skybox);
+
+ // END Draw calls
+ Frame_Draw();
+ Frame_End();
+ }
+
+ Core_Shutdown();
+ return 0;
+}
diff --git a/scripts/gen_amalgamation.sh b/scripts/gen_amalgamation.sh
new file mode 100644
index 0000000..56df62e
--- /dev/null
+++ b/scripts/gen_amalgamation.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+# Generates a single amalgamation C header file that includes all public types and functions.
+#
+# This makes including and linking Celeritas very easy.
diff --git a/scripts/gen_apidocs.sh b/scripts/gen_apidocs.sh
new file mode 100644
index 0000000..afad30e
--- /dev/null
+++ b/scripts/gen_apidocs.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+# Generates a static webpage for the public C-API of `celeritas-core`
diff --git a/scripts/header_check.sh b/scripts/header_check.sh
deleted file mode 100644
index 2edd9fe..0000000
--- a/scripts/header_check.sh
+++ /dev/null
@@ -1 +0,0 @@
-# TODO - check .h files for a valid header with @brief and #pragma once \ No newline at end of file
diff --git a/src/animation.c b/src/animation.c
index 7a79529..1c5d893 100644
--- a/src/animation.c
+++ b/src/animation.c
@@ -2,37 +2,37 @@
#include "log.h"
#include "maths.h"
-keyframe animation_sample(animation_sampler *sampler, f32 t) {
- size_t previous_index = 0;
- f32 previous_time = 0.0;
- // look forwards
- // DEBUG("%d\n", 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;
- }
+// keyframe animation_sample(animation_sampler *sampler, f32 t) {
+// size_t previous_index = 0;
+// f32 previous_time = 0.0;
+// // look forwards
+// // DEBUG("%d\n", 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);
+// 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];
+// 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);
+// 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;
+// f32 time_diff =
+// sampler->animation.timestamps[next_index] - sampler->animation.timestamps[previous_index];
+// f32 percent = (t - previous_time) / time_diff;
- quat interpolated_rot =
- quat_slerp(sampler->animation.values.values[previous_index].rotation,
- sampler->animation.values.values[next_index].rotation, percent);
+// quat interpolated_rot =
+// quat_slerp(sampler->animation.values.values[previous_index].rotation,
+// sampler->animation.values.values[next_index].rotation, percent);
- return (keyframe){ .rotation = interpolated_rot };
-} \ No newline at end of file
+// return (keyframe){ .rotation = interpolated_rot };
+// }
diff --git a/src/animation.h b/src/animation.h
index 5462e65..9c7faab 100644
--- a/src/animation.h
+++ b/src/animation.h
@@ -6,67 +6,67 @@
KITC_DECL_TYPED_ARRAY(f32)
-typedef enum interpolation { INTERPOLATION_LINEAR, INTERPOLATION_COUNT } interpolation;
+// typedef enum interpolation { INTERPOLATION_LINEAR, INTERPOLATION_COUNT } interpolation;
-typedef enum keyframe_kind {
- KEYFRAME_ROTATION,
- KEYFRAME_TRANSLATION,
- KEYFRAME_SCALE,
- KEYFRAME_WEIGHTS,
-} keyframe_kind;
+// typedef enum keyframe_kind {
+// KEYFRAME_ROTATION,
+// KEYFRAME_TRANSLATION,
+// KEYFRAME_SCALE,
+// KEYFRAME_WEIGHTS,
+// } keyframe_kind;
-typedef union keyframe {
- quat rotation;
- vec3 translation;
- vec3 scale;
- float* weights;
-} keyframe;
+// typedef union keyframe {
+// quat rotation;
+// vec3 translation;
+// vec3 scale;
+// float* weights;
+// } keyframe;
-typedef struct keyframes {
- keyframe_kind kind;
- keyframe* values;
- size_t count;
-} keyframes;
+// typedef struct keyframes {
+// keyframe_kind kind;
+// keyframe* values;
+// size_t count;
+// } keyframes;
-typedef struct joint {
- char* name; // optional
- transform transform_components;
- mat4 inverse_bind_matrix;
- mat4 local_transform;
-} joint;
+// typedef struct joint {
+// char* name; // optional
+// transform transform_components;
+// mat4 inverse_bind_matrix;
+// mat4 local_transform;
+// } joint;
-typedef struct animation_spline {
- f32* timestamps;
- size_t n_timestamps;
- keyframes values;
- interpolation interpolation;
-} animation_spline;
+// typedef struct animation_spline {
+// f32* timestamps;
+// size_t n_timestamps;
+// keyframes values;
+// interpolation interpolation;
+// } animation_spline;
-typedef struct animation_sampler {
- int current_index;
- f32 min;
- f32 max;
- animation_spline animation;
-} animation_sampler;
+// typedef struct animation_sampler {
+// int current_index;
+// f32 min;
+// f32 max;
+// animation_spline animation;
+// } animation_sampler;
-/** @brief Sample an animation at a given time `t` */
-keyframe animation_sample(animation_sampler* sampler, f32 t);
+// /** @brief Sample an animation at a given time `t` */
+// keyframe animation_sample(animation_sampler* sampler, f32 t);
-typedef struct animation_clip {
- // A clip contains one or more animation curves
- // for now I think we can just enumerate all of the properties (assuming *only* one per type is in
- // a clip) NULL = this property is not animated in this clip
- animation_sampler* rotation;
- animation_sampler* translation;
- animation_sampler* scale;
- animation_sampler* weights;
-} animation_clip;
+// typedef struct animation_clip {
+// // A clip contains one or more animation curves
+// // for now I think we can just enumerate all of the properties (assuming *only* one per type is in
+// // a clip) NULL = this property is not animated in this clip
+// animation_sampler* rotation;
+// animation_sampler* translation;
+// animation_sampler* scale;
+// animation_sampler* weights;
+// } animation_clip;
-typedef struct skinned_animation {
- mat4* joint_matrices;
- size_t n_joints;
-} skinned_animation;
+// typedef struct skinned_animation {
+// mat4* joint_matrices;
+// size_t n_joints;
+// } skinned_animation;
-// void animation_update_joint_matrices(animation_clip* )
+// // void animation_update_joint_matrices(animation_clip* )
-void animation_play(animation_clip* clip); \ No newline at end of file
+// void animation_play(animation_clip* clip);
diff --git a/src/camera.c b/src/camera.c
deleted file mode 100644
index 8ec1251..0000000
--- a/src/camera.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "camera.h"
-
-#include "maths.h"
-
-camera camera_create(vec3 pos, vec3 front, vec3 up, f32 fov) {
- camera c = { .position = pos, .front = front, .up = up, .fov = fov };
- return c;
-}
-
-void camera_view_projection(camera *c, f32 screen_height, f32 screen_width, mat4 *out_view,
- mat4 *out_proj) {
- mat4 proj = mat4_perspective(c->fov, screen_width / screen_height, 0.1, 100.0);
- vec3 camera_direction = vec3_add(c->position, c->front);
- mat4 view = mat4_look_at(c->position, camera_direction, c->up);
- *out_view = view;
- *out_proj = proj;
-} \ No newline at end of file
diff --git a/src/camera.h b/src/camera.h
deleted file mode 100644
index ec867c5..0000000
--- a/src/camera.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * @file camera.h
- * @author your name (you@domain.com)
- * @brief
- * @version 0.1
- * @date 2024-02-24
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include "maths_types.h"
-
-typedef struct camera {
- vec3 position;
- vec3 front;
- vec3 up;
- f32 fov;
-} camera;
-
-/** @brief create a camera */
-camera camera_create(vec3 pos, vec3 front, vec3 up, f32 fov);
-
-/** @brief get a 4x4 transform matrix for the view and perspective projection */
-void camera_view_projection(camera *c, f32 screen_height, f32 screen_width, mat4 *out_view,
- mat4 *out_proj);
-
-// TODO: Basic reusable camera controls
-/*
-Right click + move = pan
-Left click = orbit camera
-WASD = forward/backward/left/right
-*/ \ No newline at end of file
diff --git a/src/core.c b/src/core.c
deleted file mode 100644
index 1d8fe91..0000000
--- a/src/core.c
+++ /dev/null
@@ -1,89 +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"
-#include "scene.h"
-// #include "threadpool.h"
-
-#define SCR_WIDTH 1000
-#define SCR_HEIGHT 1000
-
-core g_core; /** @brief global `core` that other files can use */
-
-inline core* get_global_core() { return &g_core; }
-
-void core_bringup() {
- INFO("Initiate Core bringup");
- renderer_config conf = { .window_name = { "Celeritas Engine Core" },
- .scr_width = SCR_WIDTH,
- .scr_height = SCR_HEIGHT,
- .clear_colour = (vec3){ .08, .08, .1 } };
- g_core.renderer.config = conf;
- g_core.renderer.backend_context = NULL;
-
- // threadpool_create(&c->threadpool, 6, 256);
- // threadpool_set_ctx(&c->threadpool, c); // Gives the threadpool access to the core
-
- // initialise all subsystems
- if (!renderer_init(&g_core.renderer)) {
- // FATAL("Failed to start renderer");
- ERROR_EXIT("Failed to start renderer\n");
- }
- if (!input_system_init(&g_core.input, g_core.renderer.window)) {
- // the input system needs the glfw window which is created by the renderer
- // hence the order here is important
- FATAL("Failed to start input system");
- ERROR_EXIT("Failed to start input system\n");
- }
- /*
- if (!text_system_init(&c->text)) {
- // FATAL("Failed to start text system");
- ERROR_EXIT("Failed to start text system\n");
- }
- if (!screenspace_2d_init(&c->screenspace)) {
- // FATAL("Failed to start screenspace 2d plugin");
- ERROR_EXIT("Failed to start screenspace 2d plugin\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");
-
- INFO("Creating default scene");
- scene_init(&g_core.default_scene);
-}
-
-#include <glfw3.h>
-
-/* bool should_window_close(core* core) { glfwWindowShouldClose(core->renderer.window); } */
-void core_input_update() { input_update(&g_core.input); }
-void core_frame_begin(core* core) { render_frame_begin(&core->renderer); }
-void core_frame_end(core* core) { render_frame_end(&core->renderer); }
-
-void core_shutdown() {
- // threadpool_destroy(&core->threadpool);
- input_system_shutdown(&g_core.input);
- renderer_shutdown(&g_core.renderer);
-}
-
-bool should_exit() {
- return key_just_released(KEYCODE_ESCAPE) || glfwWindowShouldClose(g_core.renderer.window);
-}
-
-void frame_begin() {
- glfwPollEvents();
- render_frame_begin(&g_core.renderer);
-}
-void frame_draw() {}
-void frame_end() { render_frame_end(&g_core.renderer); }
diff --git a/src/core.h b/src/core.h
deleted file mode 100644
index 89702fd..0000000
--- a/src/core.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include "input.h"
-#include "render_types.h"
-#include "scene.h"
-#include "screenspace.h"
-#include "terrain.h"
-#include "text.h"
-// #include "threadpool.h"
-
-typedef struct core {
- const char* app_name;
- // foundations
- renderer renderer;
- // threadpool threadpool;
- // systems
- input_state input;
- text_system_state text;
- terrain_state terrain;
- screenspace_state screenspace;
- // data storage
- scene default_scene;
- model_pool models;
- // model_darray* models;
-} core;
-
-core* get_global_core();
-
-// --- Lifecycle
-
-/** @brief Throws error if the core cannot be instantiated */
-void core_bringup();
-void core_shutdown();
-bool should_exit();
-
-void frame_begin();
-void frame_draw();
-void frame_end();
-
-void core_input_update();
diff --git a/src/core/README.md b/src/core/README.md
new file mode 100644
index 0000000..19cc1d0
--- /dev/null
+++ b/src/core/README.md
@@ -0,0 +1,3 @@
+# Core
+
+Core engine facilities
diff --git a/src/core/camera.c b/src/core/camera.c
new file mode 100644
index 0000000..428a50d
--- /dev/null
+++ b/src/core/camera.c
@@ -0,0 +1,21 @@
+#include "camera.h"
+
+#include "maths.h"
+
+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, 100.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);
+}
diff --git a/src/core/camera.h b/src/core/camera.h
new file mode 100644
index 0000000..bacbca9
--- /dev/null
+++ b/src/core/camera.h
@@ -0,0 +1,37 @@
+/**
+ * @file camera.h
+ * @brief
+ */
+#pragma once
+
+#include "defines.h"
+#include "maths_types.h"
+
+typedef struct Camera {
+ Vec3 position;
+ Vec3 front;
+ Vec3 up;
+ f32 fov;
+} Camera;
+
+/** @brief create a camera */
+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
+
+
+// TODO: 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
new file mode 100644
index 0000000..602d35c
--- /dev/null
+++ b/src/core/core.c
@@ -0,0 +1,75 @@
+#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"
+#include "scene.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 */
+
+struct Core {
+ const char* app_name;
+ GLFWwindow* window;
+ Renderer* renderer;
+ Input_State input;
+};
+
+/** @brief Gets the global `Core` singleton */
+inline Core* GetCore() { return &g_core; }
+
+void Core_Bringup() {
+ INFO("Initiate Core bringup");
+ RendererConfig conf = { .window_name = { "Celeritas Engine Core" },
+ .scr_width = SCR_WIDTH,
+ .scr_height = SCR_HEIGHT,
+ .clear_colour = (Vec3){ .08, .08, .1 } };
+
+ // initialise all subsystems
+ if (!Renderer_Init(conf, g_core.renderer)) {
+ // FATAL("Failed to start renderer");
+ ERROR_EXIT("Failed to start renderer\n");
+ }
+ 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");
+
+ // INFO("Creating default scene");
+ // scene_init(&g_core.default_scene);
+}
+
+#include <glfw3.h>
+
+void Core_Shutdown() {
+ Input_Shutdown(&g_core.input);
+ Renderer_Shutdown(g_core.renderer);
+}
+
+bool ShouldExit() {
+ return key_just_released(KEYCODE_ESCAPE) || glfwWindowShouldClose(g_core.window);
+}
+
+void Frame_Begin() {
+ glfwPollEvents();
+ Render_FrameBegin(g_core.renderer);
+}
+void Frame_Draw() {}
+void Frame_End() { Render_FrameEnd(g_core.renderer); }
diff --git a/src/core/core.h b/src/core/core.h
new file mode 100644
index 0000000..7916143
--- /dev/null
+++ b/src/core/core.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "input.h"
+#include "render_types.h"
+#include "scene.h"
+#include "screenspace.h"
+#include "terrain.h"
+#include "text.h"
+
+typedef struct Core Core;
+
+Core* get_global_core();
+
+/** @brief Throws error if the core cannot be instantiated */
+void Core_Bringup();
+void Core_Shutdown();
+bool ShouldExit();
+
+void Frame_Begin();
+void Frame_Draw();
+void Frame_End();
diff --git a/src/defines.h b/src/defines.h
index a35dbf4..1f0eae7 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -38,7 +38,7 @@ _Static_assert(sizeof(i64) == 8, "type i64 should be 8 byte");
_Static_assert(sizeof(f32) == 4, "type f32 should be 4 bytes");
_Static_assert(sizeof(f64) == 8, "type f64 should be 8 bytes");
-_Static_assert(sizeof(ptrdiff_t) == 8, "");
+_Static_assert(sizeof(ptrdiff_t) == 8, "type ptrdiff_t should be 8 bytes");
#define alignof(x) _Alignof(x)
@@ -49,20 +49,9 @@ _Static_assert(sizeof(ptrdiff_t) == 8, "");
u32 raw; \
}
-/*
-Possible platform defines:
-#define CEL_PLATFORM_LINUX 1
-#define CEL_PLATFORM_WINDOWS 1
-#define CEL_PLATFORM_MAC 1
-#define CEL_PLATFORM_HEADLESS 1
-*/
+CORE_DEFINE_HANDLE(Handle); // Untyped handle that can be casted to a strongly typed resource handle
-/*
-Renderer backend defines:
-#define CEL_REND_BACKEND_OPENGL 1
-#define CEL_REND_BACKEND_VULKAN 1
-#define CEL_REND_BACKEND_METAL 1
-*/
+#define PUB // For collecting public APIs to expose in an amalgamation header file
// NOTE: The below is now handled in xmake.lua
// Platform will inform renderer backend (unless user overrides)
@@ -72,11 +61,12 @@ Renderer backend defines:
#endif
#if defined(CEL_PLATFORM_WINDOWS)
+#define CEL_REND_BACKEND_OPENGL 1
// #define CEL_REND_BACKEND_DX11 1
-#define CEL_REND_BACKEND_VULKAN 1
+// #define CEL_REND_BACKEND_VULKAN 1
#endif
#if defined(CEL_PLATFORM_MAC)
// #define CEL_REND_BACKEND_METAL 1
#define CEL_REND_BACKEND_OPENGL 1
-#endif \ No newline at end of file
+#endif
diff --git a/src/maths/geometry.h b/src/maths/geometry.h
index 937c38a..0df80fc 100644
--- a/src/maths/geometry.h
+++ b/src/maths/geometry.h
@@ -11,31 +11,31 @@
#include "maths.h"
-typedef struct line_3d {
- vec3 start, end;
-} line_3d;
+// typedef struct line_3d {
+// vec3 start, end;
+// } line_3d;
-typedef struct plane {
- vec3 normal;
-} plane;
+// typedef struct plane {
+// vec3 normal;
+// } plane;
-typedef struct cuboid {
- vec3 half_extents;
-} cuboid;
+// typedef struct cuboid {
+// vec3 half_extents;
+// } cuboid;
-typedef struct sphere {
- f32 radius;
-} sphere;
+// typedef struct sphere {
+// f32 radius;
+// } sphere;
-typedef struct cylinder {
- f32 radius;
- f32 half_height;
-} cylinder;
+// typedef struct cylinder {
+// f32 radius;
+// f32 half_height;
+// } cylinder;
-typedef struct cone {
- f32 radius;
- f32 half_height;
-} cone;
+// typedef struct cone {
+// f32 radius;
+// f32 half_height;
+// } cone;
// TODO:
// capsule
@@ -47,4 +47,4 @@ typedef struct cone {
// 2d...
// line
-// circle \ No newline at end of file
+// circle
diff --git a/src/maths/maths.h b/src/maths/maths.h
index 7c0e06e..76790ea 100644
--- a/src/maths/maths.h
+++ b/src/maths/maths.h
@@ -21,65 +21,65 @@
// --- Vector Implementations
// Dimension 3
-static inline vec3 vec3_create(f32 x, f32 y, f32 z) { return (vec3){ x, y, z }; }
-#define vec3(x, y, z) ((vec3){ x, y, z })
-static inline vec3 vec3_add(vec3 a, vec3 b) { return (vec3){ a.x + b.x, a.y + b.y, a.z + b.z }; }
-static inline vec3 vec3_sub(vec3 a, vec3 b) { return (vec3){ a.x - b.x, a.y - b.y, a.z - b.z }; }
-static inline vec3 vec3_mult(vec3 a, f32 s) { return (vec3){ a.x * s, a.y * s, a.z * s }; }
-static inline vec3 vec3_div(vec3 a, f32 s) { return (vec3){ a.x / s, a.y / s, a.z / s }; }
-
-static inline f32 vec3_len_squared(vec3 a) { return (a.x * a.x) + (a.y * a.y) + (a.z * a.z); }
-static inline f32 vec3_len(vec3 a) { return sqrtf(vec3_len_squared(a)); }
-static inline vec3 vec3_negate(vec3 a) { return (vec3){ -a.x, -a.y, -a.z }; }
-static inline vec3 vec3_normalise(vec3 a) {
+static inline Vec3 vec3_create(f32 x, f32 y, f32 z) { return (Vec3){ x, y, z }; }
+#define vec3(x, y, z) ((Vec3){ x, y, z })
+static inline Vec3 vec3_add(Vec3 a, Vec3 b) { return (Vec3){ a.x + b.x, a.y + b.y, a.z + b.z }; }
+static inline Vec3 vec3_sub(Vec3 a, Vec3 b) { return (Vec3){ a.x - b.x, a.y - b.y, a.z - b.z }; }
+static inline Vec3 vec3_mult(Vec3 a, f32 s) { return (Vec3){ a.x * s, a.y * s, a.z * s }; }
+static inline Vec3 vec3_div(Vec3 a, f32 s) { return (Vec3){ a.x / s, a.y / s, a.z / s }; }
+
+static inline f32 vec3_len_squared(Vec3 a) { return (a.x * a.x) + (a.y * a.y) + (a.z * a.z); }
+static inline f32 vec3_len(Vec3 a) { return sqrtf(vec3_len_squared(a)); }
+static inline Vec3 vec3_negate(Vec3 a) { return (Vec3){ -a.x, -a.y, -a.z }; }
+static inline Vec3 vec3_normalise(Vec3 a) {
f32 length = vec3_len(a);
return vec3_div(a, length);
}
-static inline f32 vec3_dot(vec3 a, vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
-static inline vec3 vec3_cross(vec3 a, vec3 b) {
+static inline f32 vec3_dot(Vec3 a, Vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
+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 };
+ 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 };
}
-#define VEC3_ZERO ((vec3){ .x = 0.0, .y = 0.0, .z = 0.0 })
-#define VEC3_X ((vec3){ .x = 1.0, .y = 0.0, .z = 0.0 })
-#define VEC3_NEG_X ((vec3){ .x = -1.0, .y = 0.0, .z = 0.0 })
-#define VEC3_Y ((vec3){ .x = 0.0, .y = 1.0, .z = 0.0 })
-#define VEC3_NEG_Y ((vec3){ .x = 0.0, .y = -1.0, .z = 0.0 })
-#define VEC3_Z ((vec3){ .x = 0.0, .y = 0.0, .z = 1.0 })
-#define VEC3_NEG_Z ((vec3){ .x = 0.0, .y = 0.0, .z = -1.0 })
+#define VEC3_ZERO ((Vec3){ .x = 0.0, .y = 0.0, .z = 0.0 })
+#define VEC3_X ((Vec3){ .x = 1.0, .y = 0.0, .z = 0.0 })
+#define VEC3_NEG_X ((Vec3){ .x = -1.0, .y = 0.0, .z = 0.0 })
+#define VEC3_Y ((Vec3){ .x = 0.0, .y = 1.0, .z = 0.0 })
+#define VEC3_NEG_Y ((Vec3){ .x = 0.0, .y = -1.0, .z = 0.0 })
+#define VEC3_Z ((Vec3){ .x = 0.0, .y = 0.0, .z = 1.0 })
+#define VEC3_NEG_Z ((Vec3){ .x = 0.0, .y = 0.0, .z = -1.0 })
-static inline void print_vec3(vec3 v) { printf("{ x: %f, y: %f, z: %f )\n", v.x, v.y, v.z); }
+static inline 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 inline vec2 vec2_create(f32 x, f32 y) { return (vec2){ x, y }; }
-#define vec2(x, y) ((vec2){ x, y })
-static inline vec2 vec2_div(vec2 a, f32 s) { return (vec2){ a.x / s, a.y / s }; }
+static inline Vec2 vec2_create(f32 x, f32 y) { return (Vec2){ x, y }; }
+#define vec2(x, y) ((Vec2){ x, y })
+static inline Vec2 vec2_div(Vec2 a, f32 s) { return (Vec2){ a.x / s, a.y / s }; }
// TODO: Dimension 4
-static inline vec4 vec4_create(f32 x, f32 y, f32 z, f32 w) { return (vec4){ x, y, z, w }; }
+static inline 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 })
+#define VEC4_ZERO ((Vec4){ .x = 0.0, .y = 0.0, .z = 0.0, .w = 0.0 })
// --- Quaternion Implementations
-static inline 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 inline 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 inline quat quat_normalise(quat a) {
+static inline 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 };
+ return (Quat){ a.x / length, a.y / length, a.z / length, a.w / length };
}
-static inline quat quat_ident() { return (quat){ .x = 0.0, .y = 0.0, .z = 0.0, .w = 1.0 }; }
+static inline 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) {
+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 };
+ Quat q = (Quat){ s * axis.x, s * axis.y, s * axis.z, c };
if (normalize) {
return quat_normalise(q);
}
@@ -87,11 +87,11 @@ static quat quat_from_axis_angle(vec3 axis, f32 angle, bool normalize) {
}
// TODO: grok this.
-static inline quat quat_slerp(quat a, quat b, f32 percentage) {
- quat out_quaternion;
+static inline Quat quat_slerp(Quat a, Quat b, f32 percentage) {
+ Quat out_quaternion;
- quat q0 = quat_normalise(a);
- quat q1 = quat_normalise(b);
+ 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);
@@ -113,41 +113,43 @@ static inline quat quat_slerp(quat a, quat b, f32 percentage) {
// 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),
+ (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
- f32 theta_0 = cos(dot); // theta_0 = angle between input vectors
- f32 theta = theta_0 * percentage; // theta = angle between v0 and result
- f32 sin_theta = sin(theta); // compute this value only once
- f32 sin_theta_0 = sin(theta_0); // compute this value only once
+ 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) - dot * sin_theta / sin_theta_0; // == sin(theta_0 - theta) / sin(theta_0)
+ 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),
+ 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
-static inline mat4 mat4_ident() {
- return (mat4){ .data = { 1.0, 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.0 } };
+static inline Mat4 mat4_ident() {
+ return (Mat4){ .data = { 1.0, 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.0 } };
}
-static inline mat4 mat4_translation(vec3 position) {
- mat4 out_matrix = mat4_ident();
+static inline 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 inline mat4 mat4_scale(f32 scale) {
- mat4 out_matrix = mat4_ident();
+static inline Mat4 mat4_scale(f32 scale) {
+ Mat4 out_matrix = mat4_ident();
out_matrix.data[0] = scale;
out_matrix.data[5] = scale;
out_matrix.data[10] = scale;
@@ -155,9 +157,9 @@ static inline mat4 mat4_scale(f32 scale) {
}
// TODO: double check this
-static inline mat4 mat4_rotation(quat rotation) {
- mat4 out_matrix = mat4_ident();
- quat n = quat_normalise(rotation);
+static inline 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;
@@ -174,8 +176,8 @@ static inline mat4 mat4_rotation(quat rotation) {
return out_matrix;
}
-static inline mat4 mat4_mult(mat4 lhs, mat4 rhs) {
- mat4 out_matrix = mat4_ident();
+static inline Mat4 mat4_mult(Mat4 lhs, Mat4 rhs) {
+ Mat4 out_matrix = mat4_ident();
const f32 *m1_ptr = lhs.data;
const f32 *m2_ptr = rhs.data;
@@ -193,8 +195,8 @@ static inline mat4 mat4_mult(mat4 lhs, mat4 rhs) {
return out_matrix;
}
-static mat4 mat4_transposed(mat4 matrix) {
- mat4 out_matrix = mat4_ident();
+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];
@@ -216,10 +218,10 @@ static mat4 mat4_transposed(mat4 matrix) {
#if defined(CEL_REND_BACKEND_VULKAN)
/** @brief Creates a perspective projection matrix compatible with Vulkan */
-static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip,
+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 } };
+ 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
@@ -231,10 +233,10 @@ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_
}
#else
/** @brief Creates a perspective projection matrix */
-static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip,
+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 } };
+ 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));
@@ -245,10 +247,10 @@ static inline mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_
#endif
/** @brief Creates an orthographic projection matrix */
-static inline mat4 mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 near_clip,
+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();
+ Mat4 out_matrix = mat4_ident();
f32 lr = 1.0f / (left - right);
f32 bt = 1.0f / (bottom - top);
@@ -265,16 +267,16 @@ static inline mat4 mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top, f
return out_matrix;
}
-static inline mat4 mat4_look_at(vec3 position, vec3 target, vec3 up) {
- mat4 out_matrix;
- vec3 z_axis;
+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);
+ 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;
@@ -301,26 +303,26 @@ static inline mat4 mat4_look_at(vec3 position, vec3 target, vec3 up) {
// --- Transform Implementations
#define TRANSFORM_DEFAULT \
- ((transform){ .position = VEC3_ZERO, \
- .rotation = (quat){ .x = 0., .y = 0., .z = 0., .w = 1. }, \
+ ((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, f32 scale) {
- return (transform){ .position = pos, .rotation = rot, .scale = scale, .is_dirty = true };
+static Transform transform_create(Vec3 pos, Quat rot, f32 scale) {
+ return (Transform){ .position = pos, .rotation = rot, .scale = scale, .is_dirty = true };
}
-static inline mat4 transform_to_mat(transform *tf) {
- mat4 scale = mat4_scale(tf->scale);
- mat4 rotation = mat4_rotation(tf->rotation);
- mat4 translation = mat4_translation(tf->position);
+static inline 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);
}
// --- 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(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");
+_Static_assert(alignof(Vec4) == 4, "Vec4 is 4 byte aligned");
diff --git a/src/maths/maths_types.h b/src/maths/maths_types.h
index 609672c..f256a9b 100644
--- a/src/maths/maths_types.h
+++ b/src/maths/maths_types.h
@@ -22,54 +22,53 @@
// --- Types
/** @brief 2D Vector */
-typedef struct vec2 {
+typedef struct Vec2 {
f32 x, y;
-} vec2;
+} Vec2;
/** @brief 3D Vector */
-typedef struct vec3 {
+typedef struct Vec3 {
f32 x, y, z;
-} vec3;
+} Vec3;
/** @brief 4D Vector */
-typedef struct vec4 {
+typedef struct Vec4 {
f32 x, y, z, w;
-} vec4;
+} Vec4;
/** @brief Quaternion */
-typedef vec4 quat;
+typedef Vec4 Quat;
/** @brief 4x4 Matrix */
-typedef struct mat4 {
+typedef struct Mat4 {
// TODO: use this format for more readable code: vec4 x_axis, y_axis, z_axis, w_axis;
f32 data[16];
-} mat4;
+} 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;
+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;
+typedef Bbox_3d Aabb_3D;
/** @brief 3D affine transformation */
-typedef struct transform {
- vec3 position;
- quat rotation;
+typedef struct Transform {
+ Vec3 position;
+ Quat rotation;
f32 scale;
bool is_dirty;
-} transform;
-typedef transform transform3d;
+} Transform;
-typedef struct vec4i {
+typedef struct Vec4i {
i32 x, y, z, w;
-} vec4i;
+} Vec4i;
-typedef struct vec4u {
+typedef struct Vec4u {
u32 x, y, z, w;
-} vec4u;
+} Vec4u;
// --- Some other types
typedef struct u32x3 {
@@ -96,8 +95,8 @@ typedef struct u32x2 {
// Type aliass
-typedef struct vec2 f32x2;
+typedef struct Vec2 f32x2;
#define f32x2(x, y) ((f32x2){ x, y })
-typedef struct vec3 f32x3;
+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
index 753dd83..def2712 100644
--- a/src/maths/primitives.c
+++ b/src/maths/primitives.c
@@ -8,7 +8,7 @@
// --- Helpers
#define VERT_3D(arr, pos, norm, uv) \
{ \
- vertex v = { .static_3d = { .position = pos, .normal = norm, .tex_coords = uv } }; \
+ Vertex v = { .static_3d = { .position = pos, .normal = norm, .tex_coords = uv } }; \
vertex_darray_push(arr, v); \
}
@@ -19,23 +19,23 @@ void push_triangle(u32_darray* arr, u32 i0, u32 i1, u32 i2) {
}
// TODO: move to another file
-void geo_free_data(geometry_data* geo) {
+void geo_free_data(Geometry* geo) {
vertex_darray_free(geo->vertices);
geo->vertices = NULL;
}
-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 },
+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_data geo_create_plane(f32x2 extents) {
- vertex_darray* vertices = vertex_darray_new(4);
+Geometry geo_create_plane(f32x2 extents) {
+ Vertex_darray* vertices = vertex_darray_new(4);
u32_darray* indices = u32_darray_new(vertices->len);
- vec3 vert_pos[4];
+ 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;
@@ -51,26 +51,25 @@ geometry_data geo_create_plane(f32x2 extents) {
push_triangle(indices, 2, 1, 0);
push_triangle(indices, 3, 1, 2);
- geometry_data geo = { .format = VERTEX_STATIC_3D,
- .vertices = vertices,
- .has_indices = true,
- .indices = indices,
- .colour = (rgba){ 0, 0, 0, 1 } };
+ Geometry geo = {
+ .format = VERTEX_STATIC_3D, .vertices = vertices, .has_indices = true, .indices = indices
+ };
+ // .colour = (rgba){ 0, 0, 0, 1 } };
return geo;
}
-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 };
+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 };
-geometry_data geo_create_cuboid(f32x3 extents) {
- vertex_darray* vertices = vertex_darray_new(36);
+Geometry geo_create_cuboid(f32x3 extents) {
+ Vertex_darray* vertices = vertex_darray_new(36);
// back faces
VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_NEG_Z, vec2(1, 0));
@@ -126,12 +125,11 @@ geometry_data geo_create_cuboid(f32x3 extents) {
u32_darray_push(indices, i);
}
- geometry_data geo = {
+ Geometry geo = {
.format = VERTEX_STATIC_3D,
.vertices = vertices,
.has_indices = true,
.indices = indices, // FIXME: make darray methods that return stack allocated struct
- .colour = (rgba){ 0, 0, 0, 1 }
};
return geo;
@@ -139,28 +137,28 @@ geometry_data geo_create_cuboid(f32x3 extents) {
// --- Spheres
-vec3 spherical_to_cartesian_coords(f32 rho, f32 theta, f32 phi) {
+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_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_west_lines) {
+Geometry geo_create_uvsphere(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);
+ 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),
+ 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);
+ Vertex_darray_push(vertices, top);
// parallels
for (u32 i = 0; i < (east_west_lines - 1); i++) {
@@ -171,12 +169,12 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
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);
+ 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 = {
+ Vertex v = { .static_3d = {
.position = position,
.normal =
vec3_normalise(position), // normal vector on sphere is same as position
@@ -187,7 +185,7 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
}
// Bottom point
- vertex bot = { .static_3d = { .position = vec3(0, -radius, 0),
+ 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);
@@ -234,12 +232,11 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
}
}
- geometry_data geo = {
+ Geometry geo = {
.format = VERTEX_STATIC_3D,
.vertices = vertices,
.has_indices = true,
.indices = indices,
- .colour = RED_800,
};
return geo;
}
diff --git a/src/maths/primitives.h b/src/maths/primitives.h
index be2c6ff..38ae1de 100644
--- a/src/maths/primitives.h
+++ b/src/maths/primitives.h
@@ -6,8 +6,8 @@
#include "maths_types.h"
#include "render_types.h"
-geometry_data geo_create_plane(f32x2 extents);
-geometry_data geo_create_cuboid(f32x3 extents);
-geometry_data geo_create_cylinder(f32 radius, f32 height, u32 resolution);
-geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_west_lines);
-geometry_data geo_create_icosphere(f32 radius, f32 n_subdivisions); \ No newline at end of file
+Geometry Geo_CreatePlane(f32x2 extents);
+Geometry Geo_CreateCuboid(f32x3 extents);
+Geometry Geo_CreateCylinder(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);
diff --git a/src/new_render/draw.h b/src/new_render/draw.h
new file mode 100644
index 0000000..58e104e
--- /dev/null
+++ b/src/new_render/draw.h
@@ -0,0 +1,13 @@
+/**
+ * @file draw.h
+ * @brief
+ */
+#pragma once
+#include "defines.h"
+#include "maths_types.h"
+#include "render_types.h"
+
+// --- Public APIs
+
+PUB void EncodeDrawModel(Handle model, Mat4 transform);
+PUB void EncodeDrawMesh(Mesh* mesh, Material* material, Mat4 affine);
diff --git a/src/new_render/immdraw.h b/src/new_render/immdraw.h
new file mode 100644
index 0000000..c2c3a24
--- /dev/null
+++ b/src/new_render/immdraw.h
@@ -0,0 +1,14 @@
+/**
+ * @brief Immediate-mode drawing APIs
+ */
+
+#pragma once
+#include "defines.h"
+#include "maths_types.h"
+
+// --- Public API
+
+
+void Immdraw_Cuboid(Transform tf);
+void Immdraw_Sphere(Transform tf, f32 size);
+void Immdraw_TransformGizmo(Transform tf, f32 size);
diff --git a/src/new_render/pbr.h b/src/new_render/pbr.h
new file mode 100644
index 0000000..7573563
--- /dev/null
+++ b/src/new_render/pbr.h
@@ -0,0 +1,62 @@
+/**
+ * @file pbr.h
+ * @brief PBR render pass
+ */
+
+#pragma once
+#include "defines.h"
+#include "camera.h"
+#include "maths_types.h"
+#include "ral/ral.h"
+#include "ral/ral_common.h"
+
+// PBR;
+
+// --- Public API
+typedef struct PBR_Storage PBR_Storage; // Stores all necessary data and handles
+
+PUB void PBR_Init(PBR_Storage* storage);
+
+// NOTE: For simplicity's sake we will render this pass directly to the default framebuffer
+PUB void PBR_Run(
+ PBR_Storage* storage
+ // light data
+ // camera
+ // geometry
+ // materials
+);
+
+typedef struct PBR_Params {
+ Vec3 albedo;
+ f32 metallic;
+ f32 roughness;
+ f32 ao;
+} PBR_Params;
+
+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;
+
+// --- Internal
+
+typedef struct MaterialMap MaterialMap;
+typedef struct RenderEnt RenderEnt;
+
+GPU_Renderpass* PBR_RPassCreate();
+GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass);
+void PBR_Execute(
+ PBR_Storage* storage,
+ Camera camera,
+ TextureHandle shadowmap_tex,
+ MaterialMap* materials, // map of String -> Material
+ RenderEnt* entities,
+ size_t entity_count
+
+);
+
+// Internally this will need to update material parameters
diff --git a/src/new_render/render.c b/src/new_render/render.c
new file mode 100644
index 0000000..f5547d5
--- /dev/null
+++ b/src/new_render/render.c
@@ -0,0 +1,34 @@
+/**
+ * @brief
+ */
+
+#include "render.h"
+#include "maths_types.h"
+#include "pbr.h"
+#include "ral_common.h"
+#include "render_scene.h"
+#include "shadows.h"
+
+struct Renderer {
+ struct GLFWwindow* window;
+ RendererConfig config;
+ GPU_Device device;
+ GPU_Swapchain swapchain;
+ GPU_Renderpass* default_renderpass;
+ bool frame_aborted;
+ RenderScene scene;
+ PBR_Storage* pbr;
+ Shadow_Storage* shadows;
+ // Terrain_Storage terrain;
+ // Text_Storage text;
+ struct ResourcePools* resource_pools;
+};
+
+bool Renderer_Init(RendererConfig config, Renderer* renderer) {
+ // set the RAL backend up
+
+ // create our renderpasses
+ Shadow_Init(renderer->shadows);
+
+ return true;
+}
diff --git a/src/new_render/render.h b/src/new_render/render.h
new file mode 100644
index 0000000..b0b5495
--- /dev/null
+++ b/src/new_render/render.h
@@ -0,0 +1,54 @@
+/**
+ * @brief
+ */
+
+#pragma once
+#include "defines.h"
+#include "maths_types.h"
+#include "ral_types.h"
+#include "render_types.h"
+
+typedef struct Renderer Renderer;
+typedef struct RendererConfig {
+ char window_name[256];
+ u32 scr_width, scr_height;
+ Vec3 clear_colour;
+} RendererConfig;
+
+typedef struct RenderCtx {
+ Mat4 view;
+ Mat4 projection;
+} RenderCtx;
+
+// --- Lifecycle
+
+PUB bool Renderer_Init(RendererConfig config, Renderer* renderer);
+PUB void Renderer_Shutdown(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 TextureHandle TextureUpload();
+PUB ModelHandle ModelLoad(const char* name, const char* filepath);
+
+// --- Rendering Data
+
+PUB Mesh Mesh_Create(Geometry* geometry, bool free_on_upload);
+PUB void Mesh_Delete(Mesh* mesh);
+
+// --- 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();
diff --git a/src/new_render/render_scene.h b/src/new_render/render_scene.h
new file mode 100644
index 0000000..7591d8f
--- /dev/null
+++ b/src/new_render/render_scene.h
@@ -0,0 +1,20 @@
+/**
+ * @file render_scene.h
+ * @brief
+ */
+#pragma once
+#include "defines.h"
+#include "render_types.h"
+#include "camera.h"
+
+/** @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;
+ PointLight light;
+} RenderScene;
+
+// --- Public APIs
+
+PUB void SetCamera(Camera camera);
+PUB void SetPointLight(PointLight light);
diff --git a/src/new_render/render_types.h b/src/new_render/render_types.h
new file mode 100644
index 0000000..b27bf2f
--- /dev/null
+++ b/src/new_render/render_types.h
@@ -0,0 +1,86 @@
+/**
+ * @file render_types.h
+ * @brief
+*/
+
+#pragma once
+#include "defines.h"
+#include "maths_types.h"
+#include "ral.h"
+#include "maths.h"
+#include "ral_types.h"
+
+// --- Handles
+CORE_DEFINE_HANDLE(ModelHandle);
+#define ABSENT_MODEL_HANDLE 999999999
+
+typedef struct Geometry {
+ VertexFormat format;
+ Vertex_darray* vertices;
+ bool has_indices;
+ u32_darray* indices;
+} Geometry;
+
+typedef struct u32_opt {
+ u32 value;
+ bool has_value;
+} u32_opt;
+
+typedef struct Mesh {
+ BufferHandle vextex_buffer;
+ BufferHandle index_buffer;
+ Geometry* geometry; // NULL means it has been freed CPU-side
+ bool is_uploaded; // has the data been uploaded to the GPU
+} Mesh;
+
+typedef struct TextureData {
+ TextureDesc description;
+ void* image_data;
+} TextureData;
+
+// --- Supported materials
+typedef enum MaterialKind {
+ MAT_BLINN_PHONG,
+ MAT_PBR,
+ 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)" };
+
+typedef struct Material {
+ char name[64];
+} Material;
+
+typedef struct Model {
+ // meshes
+ // materials
+} Model;
+
+// 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;
+
+// ---
+
+// A renderable 'thing'
+typedef struct RenderEnt {
+ ModelHandle model;
+ Mat4 affine; // In the future this should be updated by the transform graph
+ // Bbox_3D bounding_box;
+ bool casts_shadows;
+} RenderEnt;
diff --git a/src/new_render/shadows.h b/src/new_render/shadows.h
new file mode 100644
index 0000000..82ded5c
--- /dev/null
+++ b/src/new_render/shadows.h
@@ -0,0 +1,29 @@
+/**
+ * @brief Functions for adding shadows to scene rendering.
+*/
+
+
+#pragma once
+#include "defines.h"
+#include "ral.h"
+#include "render_types.h"
+
+typedef struct Shadow_Storage Shadow_Storage;
+
+typedef struct Camera Camera;
+typedef struct Mat4 Mat4;
+
+// --- Public API
+PUB void Shadow_Init(Shadow_Storage* storage);
+
+/** @brief Run shadow map generation for given entities, and store in a texture.
+ * @note Uses active directional light for now */
+PUB void Shadow_Run(Shadow_Storage* storage, RenderEnt* entities, size_t entity_count);
+
+/** @brief Get the shadow texture generated from shadowmap pass */
+PUB Handle Shadow_GetShadowMapTexture(Shadow_Storage* storage);
+
+// --- Internal
+GPU_Renderpass* Shadow_RPassCreate(); // Creates the render pass
+GPU_Pipeline* Shadow_PipelineCreate(GPU_Renderpass* rpass); // Creates the pipeline
+void Shadow_ShadowmapExecute(Shadow_Storage* storage, Mat4 light_space_transform, RenderEnt* entites, size_t entity_count);
diff --git a/src/new_render/skybox.h b/src/new_render/skybox.h
new file mode 100644
index 0000000..9bdc2ec
--- /dev/null
+++ b/src/new_render/skybox.h
@@ -0,0 +1,32 @@
+/**
+ * @brief
+ */
+
+#pragma once
+#include "backend_opengl.h"
+#include "defines.h"
+#include "ral_types.h"
+
+typedef struct CubeMapData {
+ void* top_image_data;
+ void* bottom_image_data;
+ void* left_image_data;
+ void* right_image_data;
+ void* front_image_data;
+ void* back_image_data;
+ u32 width, height, num_channels;
+} CubeMapData;
+
+PUB void CubeMapData_Load(const char** face_paths, int n); // should always pass n = 6 for now
+PUB void CubeMapData_Free(CubeMapData* cubemap); // Frees all the image data for a cubemap
+PUB TextureHandle CubeMapData_Upload(CubeMapData* cubemap);
+
+typedef struct Skybox {
+ BufferHandle vertex_buffer;
+ TextureHandle texture;
+ 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);
diff --git a/src/platform/file.c b/src/platform/file.c
index 6030620..33194d7 100644
--- a/src/platform/file.c
+++ b/src/platform/file.c
@@ -33,7 +33,7 @@ const char *string_from_file(const char *path) {
return string;
}
-str8_opt str8_from_file(arena *a, str8 path) {
+str8_opt str8_from_file(arena *a, Str8 path) {
char *p = cstr(a, path);
str8_opt result = { .has_value = false };
@@ -51,7 +51,7 @@ str8_opt str8_from_file(arena *a, str8 path) {
rewind(f);
u8 *raw = arena_alloc(a, fsize + 1);
- str8 contents = str8_create(raw, fsize);
+ Str8 contents = str8_create(raw, fsize);
contents.buf[contents.len] = '\0';
fread(raw, fsize, 1, f);
@@ -90,4 +90,4 @@ FileData load_spv_file(const char *path) {
fclose(f);
return (FileData){ data, bytesRead };
-} \ No newline at end of file
+}
diff --git a/src/platform/file.h b/src/platform/file.h
index a8aa8ea..5e5e1e1 100644
--- a/src/platform/file.h
+++ b/src/platform/file.h
@@ -10,17 +10,17 @@
#include "str.h"
typedef struct str8_opt {
- str8 contents;
+ Str8 contents;
bool has_value;
} str8_opt;
const char* string_from_file(const char* path);
-str8_opt str8_from_file(arena* a, str8 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); \ No newline at end of file
+FileData load_spv_file(const char* path);
diff --git a/src/platform/path.h b/src/platform/path.h
index 73063ea..ce53339 100644
--- a/src/platform/path.h
+++ b/src/platform/path.h
@@ -9,8 +9,8 @@
#include "str.h"
typedef struct path_opt {
- str8 path;
+ Str8 path;
bool has_value;
} path_opt;
-path_opt path_parent(arena* a, const char* path); // TODO: convert to using str8 \ No newline at end of file
+path_opt path_parent(arena* a, const char* path); // TODO: convert to using str8
diff --git a/src/ral/README.md b/src/ral/README.md
new file mode 100644
index 0000000..f66b95a
--- /dev/null
+++ b/src/ral/README.md
@@ -0,0 +1,5 @@
+# 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
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ral/backends/metal/backend_metal.h
diff --git a/src/ral/backends/opengl/backend_opengl.h b/src/ral/backends/opengl/backend_opengl.h
new file mode 100644
index 0000000..22162f3
--- /dev/null
+++ b/src/ral/backends/opengl/backend_opengl.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "ral_impl.h"
+#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_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_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/ral/backends/vulkan/backend_vulkan.h b/src/ral/backends/vulkan/backend_vulkan.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ral/backends/vulkan/backend_vulkan.h
diff --git a/src/ral/ral.h b/src/ral/ral.h
new file mode 100644
index 0000000..ce3b27d
--- /dev/null
+++ b/src/ral/ral.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "ral_types.h"
+#include "ral_common.h"
+#include "ral_impl.h" \ No newline at end of file
diff --git a/src/ral/ral_common.c b/src/ral/ral_common.c
new file mode 100644
index 0000000..89d475b
--- /dev/null
+++ b/src/ral/ral_common.c
@@ -0,0 +1,19 @@
+#include "ral_common.h"
+#include "ral_impl.h"
+
+void backend_pools_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 resource_pools_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;
+}
diff --git a/src/ral/ral_common.h b/src/ral/ral_common.h
new file mode 100644
index 0000000..1088404
--- /dev/null
+++ b/src/ral/ral_common.h
@@ -0,0 +1,39 @@
+#pragma once
+#include "defines.h"
+#include "buf.h"
+#include "mem.h"
+#include "ral_types.h"
+#include "ral_impl.h"
+
+
+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))
+
+// --- Pools
+typedef struct GPU_BackendPools{
+ Pipeline_pool pipelines;
+ PipelineLayout_pool pipeline_layouts;
+ Renderpass_pool renderpasses;
+} GPU_BackendPools;
+void backend_pools_init(arena* a, GPU_BackendPools* backend_pools);
+
+struct ResourcePools {
+ Buffer_pool buffers;
+ Texture_pool textures;
+};
+void resource_pools_init(arena* a, struct ResourcePools* res_pools);
+
+
+// --- Vertex formats
+bytebuffer vertices_as_bytebuffer(arena* a, VertexFormat format, Vertex_darray* vertices);
+
+void vertex_desc_add(VertexDescription* builder, const char* name, VertexAttribType type);
+VertexDescription static_3d_vertex_description();
+size_t vertex_attrib_size(VertexAttribType attr);
diff --git a/src/ral/ral_impl.h b/src/ral/ral_impl.h
new file mode 100644
index 0000000..4d1c17a
--- /dev/null
+++ b/src/ral/ral_impl.h
@@ -0,0 +1,38 @@
+/**
+ * @brief
+*/
+#pragma once
+#include "defines.h"
+#include "ral_types.h"
+
+struct GLFWwindow;
+
+// Forward declare structs - these must be defined in the backend implementation
+typedef struct GPU_Swapchain GPU_Swapchain;
+typedef struct GPU_Device GPU_Device;
+typedef struct GPU_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);
+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);
+
+GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description);
+void GPU_Renderpass_Destroy(GPU_Renderpass* pass);
+
+GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description, GPU_Renderpass* renderpass);
+void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline);
+
+#if defined(CEL_REND_BACKEND_OPENGL)
+#include "backend_opengl.h"
+#endif
diff --git a/src/ral/ral_types.h b/src/ral/ral_types.h
new file mode 100644
index 0000000..0ba7f87
--- /dev/null
+++ b/src/ral/ral_types.h
@@ -0,0 +1,223 @@
+#pragma once
+#include "defines.h"
+#include "darray.h"
+#include "maths_types.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);
+
+// --- 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;
+
+// --- Textures
+typedef enum GPU_TextureType {
+ TEXTURE_TYPE_2D,
+ TEXTURE_TYPE_3D,
+ TEXTURE_TYPE_2D_ARRAY,
+ TEXTURE_TYPE_CUBE_MAP,
+ TEXTURE_TYPE_COUNT
+} GPU_TextureType;
+
+typedef enum GPU_TextureFormat {
+ TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
+ TEXTURE_FORMAT_DEPTH_DEFAULT,
+ TEXTURE_FORMAT_COUNT
+} GPU_TextureFormat;
+
+/** @brief Texture Description - used by texture creation functions */
+typedef struct TextureDesc {
+ GPU_TextureType tex_type;
+ GPU_TextureFormat format;
+ u32x2 extents;
+} TextureDesc;
+
+// --- Vertices
+
+typedef enum VertexFormat {
+ VERTEX_STATIC_3D,
+ VERTEX_SPRITE,
+ VERTEX_SKINNED,
+ VERTEX_COLOURED_STATIC_3D,
+ VERTEX_RAW_POS_COLOUR,
+ VERTEX_COUNT
+} VertexFormat;
+
+typedef union Vertex {
+ struct {
+ Vec3 position;
+ Vec3 normal;
+ Vec2 tex_coords;
+ } static_3d; /** @brief standard vertex format for static geometry in 3D */
+
+ struct {
+ Vec2 position;
+ Vec4 colour;
+ Vec2 tex_coords;
+ } sprite; /** @brief vertex format for 2D sprites or quads */
+
+ struct {
+ Vec3 position;
+ Vec4 colour;
+ Vec2 tex_coords;
+ Vec3 normal;
+ Vec4i bone_ids; // Integer vector for bone IDs
+ Vec4 bone_weights; // Weight of each bone's influence
+ } skinned_3d; /** @brief vertex format for skeletal (animated) geometry in 3D */
+
+ struct {
+ Vec3 position;
+ Vec2 tex_coords;
+ Vec3 normal;
+ Vec4 colour;
+ } coloured_static_3d; /** @brief vertex format used for debugging */
+
+ struct {
+ Vec2 position;
+ Vec3 colour;
+ } raw_pos_colour;
+} Vertex;
+
+#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 {
+ 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 ShaderVisibility {
+ VISIBILITY_VERTEX = 1 << 0,
+ VISIBILITY_FRAGMENT = 1 << 1,
+ VISIBILITY_COMPUTE = 1 << 2,
+} ShaderVisibility ;
+
+typedef struct ShaderDesc {} ShaderDesc;
+
+typedef enum ShaderBindingKind {
+ BINDING_BUFFER,
+ BINDING_BUFFER_ARRAY,
+ BINDING_TEXTURE,
+ BINDING_TEXTURE_ARRAY,
+ // TODO: sampler
+ BINDING_COUNT
+} ShaderBindingKind;
+
+typedef struct ShaderBinding {
+ const char* label;
+ ShaderBindingKind kind;
+ ShaderVisibility vis;
+ union {
+ struct { u32 size; } bytes;
+ struct { BufferHandle handle; } buffer;
+ struct { TextureHandle handle; } texture;
+ } data;
+} ShaderBinding;
+
+typedef struct ShaderDataLayout {
+ ShaderBinding* bindings;
+ size_t binding_count;
+} ShaderDataLayout;
+
+typedef ShaderDataLayout (*FN_GetBindingLayout)(void);
+
+typedef struct ShaderData {
+ FN_GetBindingLayout get_layout;
+ void* data;
+} ShaderData;
+
+// --- Miscellaneous
+
+typedef enum PrimitiveTopology {
+ PRIMITIVE_TOPOLOGY_POINT,
+ PRIMITIVE_TOPOLOGY_LINE,
+ PRIMITIVE_TOPOLOGY_LINE_STRIP,
+ PRIMITIVE_TOPOLOGY_TRIANGLE,
+ PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+ PRIMITIVE_TOPOLOGY_COUNT
+} PrimitiveTopology;
+
+typedef enum CullMode { CULL_BACK_FACE, CULL_FRONT_FACE, CULL_COUNT } CullMode;
+
+typedef struct GraphicsPipelineDesc {
+ // GPU_Renderpass* renderpass -> takes a renderpass in the create function
+ const char* debug_name;
+ VertexDescription vertex_desc;
+ ShaderDesc vs; /** @brief Vertex shader stage */
+ ShaderDesc fs; /** @brief Fragment shader stage */
+
+ // Roughly equivalent to a descriptor set layout each. each layout can have multiple bindings
+ // examples:
+ // - uniform buffer reprensenting view projection matrix
+ // - texture for shadow map
+ ShaderData data_layouts[MAX_SHADER_DATA_LAYOUTS];
+ u32 data_layouts_count;
+
+ bool wireframe;
+ bool depth_test;
+} GraphicsPipelineDesc;
+
+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/renderer/backends/backend_test.c b/src/render/backends/backend_test.c
index 6347e27..6347e27 100644
--- a/src/renderer/backends/backend_test.c
+++ b/src/render/backends/backend_test.c
diff --git a/src/renderer/backends/metal/README.md b/src/render/backends/metal/README.md
index f87f5c1..f87f5c1 100644
--- a/src/renderer/backends/metal/README.md
+++ b/src/render/backends/metal/README.md
diff --git a/src/renderer/backends/metal/backend_metal.h b/src/render/backends/metal/backend_metal.h
index 9561bb6..9561bb6 100644
--- a/src/renderer/backends/metal/backend_metal.h
+++ b/src/render/backends/metal/backend_metal.h
diff --git a/src/renderer/backends/metal/backend_metal.m b/src/render/backends/metal/backend_metal.m
index 4787755..4787755 100644
--- a/src/renderer/backends/metal/backend_metal.m
+++ b/src/render/backends/metal/backend_metal.m
diff --git a/src/renderer/backends/opengl/README.md b/src/render/backends/opengl/README.md
index f87f5c1..f87f5c1 100644
--- a/src/renderer/backends/opengl/README.md
+++ b/src/render/backends/opengl/README.md
diff --git a/src/renderer/backends/opengl/backend_opengl.c b/src/render/backends/opengl/backend_opengl.c
index 70e10d7..70e10d7 100644
--- a/src/renderer/backends/opengl/backend_opengl.c
+++ b/src/render/backends/opengl/backend_opengl.c
diff --git a/src/renderer/backends/opengl/backend_opengl.h b/src/render/backends/opengl/backend_opengl.h
index 8b88cf8..8b88cf8 100644
--- a/src/renderer/backends/opengl/backend_opengl.h
+++ b/src/render/backends/opengl/backend_opengl.h
diff --git a/src/renderer/backends/opengl/opengl_helpers.h b/src/render/backends/opengl/opengl_helpers.h
index 41018cb..41018cb 100644
--- a/src/renderer/backends/opengl/opengl_helpers.h
+++ b/src/render/backends/opengl/opengl_helpers.h
diff --git a/src/renderer/backends/vulkan/README.md b/src/render/backends/vulkan/README.md
index 220ed64..220ed64 100644
--- a/src/renderer/backends/vulkan/README.md
+++ b/src/render/backends/vulkan/README.md
diff --git a/src/renderer/backends/backend_vulkan.c b/src/render/backends/vulkan/backend_vulkan.c
index 8801230..8801230 100644
--- a/src/renderer/backends/backend_vulkan.c
+++ b/src/render/backends/vulkan/backend_vulkan.c
diff --git a/src/renderer/backends/backend_vulkan.h b/src/render/backends/vulkan/backend_vulkan.h
index 6ca0bb5..6ca0bb5 100644
--- a/src/renderer/backends/backend_vulkan.h
+++ b/src/render/backends/vulkan/backend_vulkan.h
diff --git a/src/renderer/backends/vulkan/vulkan_glossary.md b/src/render/backends/vulkan/vulkan_glossary.md
index 4214f9d..4214f9d 100644
--- a/src/renderer/backends/vulkan/vulkan_glossary.md
+++ b/src/render/backends/vulkan/vulkan_glossary.md
diff --git a/src/renderer/backends/vulkan_helpers.h b/src/render/backends/vulkan_helpers.h
index 23666c6..23666c6 100644
--- a/src/renderer/backends/vulkan_helpers.h
+++ b/src/render/backends/vulkan_helpers.h
diff --git a/src/renderer/bind_group_layouts.h b/src/render/bind_group_layouts.h
index 246d1ef..246d1ef 100644
--- a/src/renderer/bind_group_layouts.h
+++ b/src/render/bind_group_layouts.h
diff --git a/src/renderer/builtin_materials.h b/src/render/builtin_materials.h
index f2db5f4..f2db5f4 100644
--- a/src/renderer/builtin_materials.h
+++ b/src/render/builtin_materials.h
diff --git a/src/renderer/immediate.c b/src/render/immediate.c
index 63a62b8..63a62b8 100644
--- a/src/renderer/immediate.c
+++ b/src/render/immediate.c
diff --git a/src/renderer/immediate.h b/src/render/immediate.h
index f4b1729..f4b1729 100644
--- a/src/renderer/immediate.h
+++ b/src/render/immediate.h
diff --git a/src/renderer/ral.c b/src/render/ral.c
index 9ca99ce..9ca99ce 100644
--- a/src/renderer/ral.c
+++ b/src/render/ral.c
diff --git a/src/renderer/ral.h b/src/render/ral.h
index b76de27..792bb4e 100644
--- a/src/renderer/ral.h
+++ b/src/render/ral.h
@@ -31,36 +31,36 @@ typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission
typedef struct gpu_buffer gpu_buffer;
typedef struct gpu_texture gpu_texture;
-#define MAX_SHADER_DATA_LAYOUTS 5
-#define MAX_BUFFERS 256
-#define MAX_TEXTURES 256
-#define MAX_PIPELINES 128
-#define MAX_RENDERPASSES 128
+// #define MAX_SHADER_DATA_LAYOUTS 5
+// #define MAX_BUFFERS 256
+// #define MAX_TEXTURES 256
+// #define MAX_PIPELINES 128
+// #define MAX_RENDERPASSES 128
-TYPED_POOL(gpu_buffer, buffer);
-TYPED_POOL(gpu_texture, texture);
+// TYPED_POOL(gpu_buffer, buffer);
+// TYPED_POOL(gpu_texture, texture);
-TYPED_POOL(gpu_pipeline_layout, pipeline_layout);
-TYPED_POOL(gpu_pipeline, pipeline);
-TYPED_POOL(gpu_renderpass, renderpass);
+// TYPED_POOL(gpu_pipeline_layout, pipeline_layout);
+// TYPED_POOL(gpu_pipeline, pipeline);
+// TYPED_POOL(gpu_renderpass, renderpass);
-// --- Handy macros
-#define BUFFER_GET(h) (buffer_pool_get(&context.resource_pools->buffers, h))
-#define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h))
+// // --- Handy macros
+// #define BUFFER_GET(h) (buffer_pool_get(&context.resource_pools->buffers, h))
+// #define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h))
// --- Pools
-typedef struct gpu_backend_pools {
- pipeline_pool pipelines;
- pipeline_layout_pool pipeline_layouts;
- renderpass_pool renderpasses;
-} gpu_backend_pools;
-void backend_pools_init(arena* a, gpu_backend_pools* backend_pools);
-
-struct resource_pools {
- buffer_pool buffers;
- texture_pool textures;
-};
-void resource_pools_init(arena* a, struct resource_pools* res_pools);
+// typedef struct gpu_backend_pools {
+// pipeline_pool pipelines;
+// pipeline_layout_pool pipeline_layouts;
+// renderpass_pool renderpasses;
+// } gpu_backend_pools;
+// void backend_pools_init(arena* a, gpu_backend_pools* backend_pools);
+
+// struct resource_pools {
+// buffer_pool buffers;
+// texture_pool textures;
+// };
+// void resource_pools_init(arena* a, struct resource_pools* res_pools);
// --- Pipeline description
typedef enum pipeline_kind {
diff --git a/src/render/ral_types.h b/src/render/ral_types.h
new file mode 100644
index 0000000..be95902
--- /dev/null
+++ b/src/render/ral_types.h
@@ -0,0 +1,104 @@
+/**
+ * @file ral_types.h
+ * @author your name (you@domain.com)
+ * @brief Struct and enum definitions for RAL
+ * @version 0.1
+ * @date 2024-04-27
+ *
+ * @copyright Copyright (c) 2024
+ *
+ */
+#pragma once
+
+#include "darray.h"
+#include "defines.h"
+#include "maths_types.h"
+
+#define MAX_VERTEX_ATTRIBUTES 16
+
+/* #ifndef RENDERER_TYPED_HANDLES */
+CORE_DEFINE_HANDLE(buffer_handle);
+CORE_DEFINE_HANDLE(texture_handle);
+CORE_DEFINE_HANDLE(sampler_handle);
+CORE_DEFINE_HANDLE(shader_handle);
+CORE_DEFINE_HANDLE(pipeline_layout_handle);
+CORE_DEFINE_HANDLE(pipeline_handle);
+CORE_DEFINE_HANDLE(renderpass_handle);
+#define ABSENT_MODEL_HANDLE 999999999
+
+
+// --- Shaders & Bindings
+
+typedef enum shader_visibility {
+ VISIBILITY_VERTEX = 1 << 0,
+ VISIBILITY_FRAGMENT = 1 << 1,
+ VISIBILITY_COMPUTE = 1 << 2,
+} shader_visibility;
+
+/** @brief Describes the kind of binding a `shader_binding` is for. This changes how we create
+ * backing data for it. */
+typedef enum shader_binding_type {
+ /**
+ * @brief Binds a buffer to a shader
+ * @note Vulkan: Becomes a Storage Buffer
+ */
+ SHADER_BINDING_BUFFER,
+ SHADER_BINDING_BUFFER_ARRAY,
+ SHADER_BINDING_TEXTURE,
+ SHADER_BINDING_TEXTURE_ARRAY,
+ SHADER_BINDING_SAMPLER,
+ /**
+ * @brief Binds raw data to a shader
+ * @note Vulkan: Becomes a Uniform Buffer
+ */
+ SHADER_BINDING_BYTES,
+ // TODO: Acceleration Structure
+ SHADER_BINDING_COUNT
+} shader_binding_type;
+
+static const char* shader_binding_type_name[] = { "BUFFER", "BUFFER ARRAY", "TEXTURE",
+ "TEXTURE ARRAY", "SAMPLER", "BYTES",
+ "COUNT" };
+
+// pub trait ShaderBindable: Clone + Copy {
+// fn bind_to(&self, context: &mut PipelineContext, index: u32);
+// }
+
+typedef struct shader_binding {
+ const char* label;
+ shader_binding_type type;
+ shader_visibility vis;
+ bool stores_data; /** @brief if this is true then the shader binding has references to live data,
+ if false then its just being used to describe a layout and .data
+ should be zeroed */
+ union {
+ struct {
+ buffer_handle handle;
+ } buffer;
+ struct {
+ void* data;
+ size_t size;
+ } bytes;
+ struct {
+ texture_handle handle;
+ } texture;
+ } data; /** @brief can store any kind of data that we can bind to a shader / descriptor set */
+} shader_binding;
+
+
+void print_shader_binding(shader_binding b);
+
+/** @brief A list of bindings that describe what data a shader / pipeline expects
+ @note This roughly correlates to a descriptor set layout in Vulkan
+*/
+
+// ? How to tie together materials and shaders
+
+// Three registers
+// 1. low level graphics api calls "ral"
+// 2. higher level render calls
+// 3. simplified immediate mode API
+
+// 3 - you don't need to know how the renderer works at all
+// 2 - you need to know how the overall renderer is designed
+// 1 - you need to understand graphics API specifics
diff --git a/src/renderer/render.c b/src/render/render.c
index f52e2be..f52e2be 100644
--- a/src/renderer/render.c
+++ b/src/render/render.c
diff --git a/src/renderer/render.h b/src/render/render.h
index 19a8d1a..f0e9a64 100644
--- a/src/renderer/render.h
+++ b/src/render/render.h
@@ -69,11 +69,6 @@ texture_handle texture_data_upload(texture_data data, bool free_on_upload);
material pbr_material_load(char* albedo_path, char* normal_path, bool metal_roughness_combined,
char* metallic_path, char* roughness_map, char* ao_map);
-buffer_handle buffer_create(const char* debug_name, u64 size);
-bool buffer_destroy(buffer_handle buffer);
-sampler_handle sampler_create();
-
-// models and meshes are implemented **in terms of the above**
/**
* @brief Creates buffers and returns a struct that holds handles to our resources
@@ -89,8 +84,3 @@ void mesh_delete(mesh* mesh); // TODO
void draw_mesh(mesh* mesh, mat4* model, camera* cam);
model_handle model_load(const char* debug_name, const char* filepath);
-
-void geo_free_data(geometry_data* geo);
-void geo_set_vertex_colours(geometry_data* geo, vec4 colour);
-
-vertex_description static_3d_vertex_description();
diff --git a/src/renderer/render_types.h b/src/render/render_types.h
index b25fa14..b25fa14 100644
--- a/src/renderer/render_types.h
+++ b/src/render/render_types.h
diff --git a/src/renderer/renderpasses.c b/src/render/renderpasses.c
index b93d487..b93d487 100644
--- a/src/renderer/renderpasses.c
+++ b/src/render/renderpasses.c
diff --git a/src/renderer/renderpasses.h b/src/render/renderpasses.h
index 5a5ffee..5a5ffee 100644
--- a/src/renderer/renderpasses.h
+++ b/src/render/renderpasses.h
diff --git a/src/renderer/static_pipeline.h b/src/render/static_pipeline.h
index bf5bc42..bf5bc42 100644
--- a/src/renderer/static_pipeline.h
+++ b/src/render/static_pipeline.h
diff --git a/src/renderer/backends/backend_dx11.c b/src/renderer/backends/backend_dx11.c
deleted file mode 100644
index 7e48853..0000000
--- a/src/renderer/backends/backend_dx11.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#if defined(CEL_REND_BACKEND_DX11)
-#include <d3d11.h>
-#include <d3dcompiler.h>
-
-#endif \ No newline at end of file
diff --git a/src/renderer/backends/backend_dx11.h b/src/renderer/backends/backend_dx11.h
deleted file mode 100644
index 53738aa..0000000
--- a/src/renderer/backends/backend_dx11.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include <d3d11.h>
-#include <d3dcompiler.h>
-
-#include "ral.h"
-
-#define GPU_SWAPCHAIN_IMG_COUNT 2
-
-// typedef struct gpu_swapchain gpu_swapchain;
-typedef struct gpu_device {
- // VkPhysicalDevice physical_device;
- // VkDevice logical_device;
- // VkPhysicalDeviceProperties properties;
- // VkPhysicalDeviceFeatures features;
- // VkPhysicalDeviceMemoryProperties memory;
- // VkCommandPool pool;
-} gpu_device;
-typedef struct gpu_pipeline {
-} gpu_pipeline;
-
-typedef struct gpu_renderpass {
- // VkRenderPass vk_handle;
- // VkFramebuffer framebuffers[GPU_SWAPCHAIN_IMG_COUNT];
- // u32
-} gpu_renderpass;
-
-typedef struct gpu_cmd_encoder {
- // VkCommandBuffer cmd_buffer;
-} gpu_cmd_encoder; \ No newline at end of file
diff --git a/src/renderer/ral_types.h b/src/renderer/ral_types.h
deleted file mode 100644
index f1f261d..0000000
--- a/src/renderer/ral_types.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/**
- * @file ral_types.h
- * @author your name (you@domain.com)
- * @brief Struct and enum definitions for RAL
- * @version 0.1
- * @date 2024-04-27
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include "darray.h"
-#include "defines.h"
-#include "maths_types.h"
-
-#define MAX_VERTEX_ATTRIBUTES 16
-
-/* #ifndef RENDERER_TYPED_HANDLES */
-CORE_DEFINE_HANDLE(buffer_handle);
-CORE_DEFINE_HANDLE(texture_handle);
-CORE_DEFINE_HANDLE(sampler_handle);
-CORE_DEFINE_HANDLE(shader_handle);
-CORE_DEFINE_HANDLE(pipeline_layout_handle);
-CORE_DEFINE_HANDLE(pipeline_handle);
-CORE_DEFINE_HANDLE(renderpass_handle);
-#define ABSENT_MODEL_HANDLE 999999999
-
-/* #define RENDERER_TYPED_HANDLES */
-/* #endif */
-
-/* typedef struct gpu_buffer { */
-/* u32 a; */
-/* } gpu_buffer; */
-
-/* #ifndef RAL_TYPED_POOLS */
-/* #define RAL_TYPED_POOLS */
-/* #endif */
-
-// gpu types
-typedef enum gpu_primitive_topology {
- CEL_PRIMITIVE_TOPOLOGY_POINT,
- CEL_PRIMITIVE_TOPOLOGY_LINE,
- CEL_PRIMITIVE_TOPOLOGY_LINE_STRIP,
- CEL_PRIMITIVE_TOPOLOGY_TRIANGLE,
- CEL_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
- CEL_PRIMITIVE_TOPOLOGY_COUNT
-} cel_primitive_topology;
-
-typedef enum gpu_texture_type {
- CEL_TEXTURE_TYPE_2D,
- CEL_TEXTURE_TYPE_3D,
- CEL_TEXTURE_TYPE_2D_ARRAY,
- CEL_TEXTURE_TYPE_CUBE_MAP,
- CEL_TEXTURE_TYPE_COUNT
-} gpu_texture_type;
-
-typedef enum gpu_texture_format {
- CEL_TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
- CEL_TEXTURE_FORMAT_DEPTH_DEFAULT,
- CEL_TEXTURE_FORMAT_COUNT
-} gpu_texture_format;
-
-/** @brief Texture Description - used by texture creation functions */
-typedef struct texture_desc {
- gpu_texture_type tex_type;
- gpu_texture_format format;
- u32x2 extents;
-} texture_desc;
-
-typedef enum gpu_buffer_type {
- CEL_BUFFER_DEFAULT, // on Vulkan this would be a storage buffer?
- CEL_BUFFER_VERTEX,
- CEL_BUFFER_INDEX,
- CEL_BUFFER_UNIFORM,
- CEL_BUFFER_COUNT
-} gpu_buffer_type;
-
-static const char* buffer_type_names[] = {
- "RAL Buffer Default", "RAL Buffer Vertex", "RAL Buffer Index",
- "RAL Buffer Uniform", "RAL Buffer Count",
-};
-
-typedef enum gpu_buffer_flag {
- CEL_BUFFER_FLAG_CPU = 1 << 0,
- CEL_BUFFER_FLAG_GPU = 1 << 1,
- CEL_BUFFER_FLAG_STORAGE = 1 << 2,
- CEL_BUFFER_FLAG_COUNT
-} gpu_buffer_flag;
-typedef u32 gpu_buffer_flags;
-
-typedef enum vertex_format {
- VERTEX_STATIC_3D,
- VERTEX_SPRITE,
- VERTEX_SKINNED,
- VERTEX_COLOURED_STATIC_3D,
- VERTEX_RAW_POS_COLOUR,
- VERTEX_COUNT
-} vertex_format;
-
-typedef union vertex {
- struct {
- vec3 position;
- vec3 normal;
- vec2 tex_coords;
- } static_3d; /** @brief standard vertex format for static geometry in 3D */
-
- struct {
- vec2 position;
- vec4 colour;
- vec2 tex_coords;
- } sprite; /** @brief vertex format for 2D sprites or quads */
-
- struct {
- vec3 position;
- vec4 colour;
- vec2 tex_coords;
- vec3 normal;
- vec4i bone_ids; // Integer vector for bone IDs
- vec4 bone_weights; // Weight of each bone's influence
- } skinned_3d; /** @brief vertex format for skeletal (animated) geometry in 3D */
-
- struct {
- vec3 position;
- vec2 tex_coords;
- vec3 normal;
- vec4 colour;
- } coloured_static_3d; /** @brief vertex format used for debugging */
-
- struct {
- vec2 position;
- vec3 colour;
- } raw_pos_colour;
-} vertex;
-
-#ifndef TYPED_VERTEX_ARRAY
-KITC_DECL_TYPED_ARRAY(vertex)
-KITC_DECL_TYPED_ARRAY(u32)
-#define TYPED_VERTEX_ARRAY
-#endif
-
-// TEMP
-typedef struct custom_vertex {
- vec2 pos;
- vec3 color;
-} custom_vertex;
-
-// Vertex attributes
-/// @strip_prefix(ATTR_)
-typedef enum vertex_attrib_type {
- ATTR_F32,
- ATTR_F32x2,
- ATTR_F32x3,
- ATTR_F32x4,
- ATTR_U32,
- ATTR_U32x2,
- ATTR_U32x3,
- ATTR_U32x4,
- ATTR_I32,
- ATTR_I32x2,
- ATTR_I32x3,
- ATTR_I32x4,
-} vertex_attrib_type;
-
-typedef struct vertex_description {
- char* debug_label;
- const char* attr_names[MAX_VERTEX_ATTRIBUTES];
- vertex_attrib_type attributes[MAX_VERTEX_ATTRIBUTES];
- u32 attributes_count;
- size_t stride;
- bool use_full_vertex_size;
-} vertex_description;
-
-// --- Shaders & Bindings
-
-typedef enum shader_visibility {
- VISIBILITY_VERTEX = 1 << 0,
- VISIBILITY_FRAGMENT = 1 << 1,
- VISIBILITY_COMPUTE = 1 << 2,
-} shader_visibility;
-
-/** @brief Describes the kind of binding a `shader_binding` is for. This changes how we create
- * backing data for it. */
-typedef enum shader_binding_type {
- /**
- * @brief Binds a buffer to a shader
- * @note Vulkan: Becomes a Storage Buffer
- */
- SHADER_BINDING_BUFFER,
- SHADER_BINDING_BUFFER_ARRAY,
- SHADER_BINDING_TEXTURE,
- SHADER_BINDING_TEXTURE_ARRAY,
- SHADER_BINDING_SAMPLER,
- /**
- * @brief Binds raw data to a shader
- * @note Vulkan: Becomes a Uniform Buffer
- */
- SHADER_BINDING_BYTES,
- // TODO: Acceleration Structure
- SHADER_BINDING_COUNT
-} shader_binding_type;
-
-static const char* shader_binding_type_name[] = { "BUFFER", "BUFFER ARRAY", "TEXTURE",
- "TEXTURE ARRAY", "SAMPLER", "BYTES",
- "COUNT" };
-
-// pub trait ShaderBindable: Clone + Copy {
-// fn bind_to(&self, context: &mut PipelineContext, index: u32);
-// }
-
-typedef struct shader_binding {
- const char* label;
- shader_binding_type type;
- shader_visibility vis;
- bool stores_data; /** @brief if this is true then the shader binding has references to live data,
- if false then its just being used to describe a layout and .data
- should be zeroed */
- union {
- struct {
- buffer_handle handle;
- } buffer;
- struct {
- void* data;
- size_t size;
- } bytes;
- struct {
- texture_handle handle;
- } texture;
- } data; /** @brief can store any kind of data that we can bind to a shader / descriptor set */
-} shader_binding;
-
-#define MAX_LAYOUT_BINDINGS 8
-
-void print_shader_binding(shader_binding b);
-
-/** @brief A list of bindings that describe what data a shader / pipeline expects
- @note This roughly correlates to a descriptor set layout in Vulkan
-*/
-typedef struct shader_data_layout {
- char* name;
- shader_binding bindings[MAX_LAYOUT_BINDINGS];
- u32 bindings_count;
-} shader_data_layout;
-
-typedef struct shader_data {
- shader_data_layout (*shader_data_get_layout)(void* data);
- void* data;
-} shader_data;
-
-/*
- Usage:
- 1. When we create the pipeline, we must call a function that return a layout without .data
- fields
- 2. When binding
-*/
-
-typedef enum gpu_cull_mode { CULL_BACK_FACE, CULL_FRONT_FACE, CULL_COUNT } gpu_cull_mode;
-
-// ? How to tie together materials and shaders
-
-// Three registers
-// 1. low level graphics api calls "ral"
-// 2. higher level render calls
-// 3. simplified immediate mode API
-
-// 3 - you don't need to know how the renderer works at all
-// 2 - you need to know how the overall renderer is designed
-// 1 - you need to understand graphics API specifics
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
index c51e30d..e381954 100644
--- a/src/resources/gltf.c
+++ b/src/resources/gltf.c
@@ -21,24 +21,24 @@
#define CGLTF_IMPLEMENTATION
#include <cgltf.h>
-extern core g_core;
+extern Core g_core;
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(vec4)
+KITC_DECL_TYPED_ARRAY(Vec3)
+KITC_DECL_TYPED_ARRAY(Vec2)
+KITC_DECL_TYPED_ARRAY(Vec4u)
+KITC_DECL_TYPED_ARRAY(Vec4)
KITC_DECL_TYPED_ARRAY(face)
// KITC_DECL_TYPED_ARRAY(joint)
-bool model_load_gltf_str(const char *file_string, const char *filepath, str8 relative_path,
- model *out_model, bool invert_textures_y);
+bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 relative_path,
+ Model *out_model, bool invert_textures_y);
-model_handle model_load_gltf(const char *path, bool invert_texture_y) {
+ModelHandle model_load_gltf(const char *path, bool invert_texture_y) {
size_t arena_size = 1024;
arena scratch = arena_create(malloc(arena_size), arena_size);
@@ -49,22 +49,22 @@ model_handle model_load_gltf(const char *path, bool invert_texture_y) {
}
const char *file_string = string_from_file(path);
- model_handle handle;
- model *model = model_pool_alloc(&g_core.models, &handle);
- model->name = str8_cstr_view(path);
- model->meshes = mesh_darray_new(1);
- model->materials = material_darray_new(1);
+ ModelHandle handle;
+ // modfl *model = model_pool_alloc(&g_core.models, &handle);
+ // model->name = str8_cstr_view(path);
+ // model->meshes = mesh_darray_new(1);
+ // model->materials = material_darray_new(1);
- bool success =
- model_load_gltf_str(file_string, path, relative_path.path, model, invert_texture_y);
+ // 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");
- }
+ // 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);
+ // arena_free_all(&scratch);
+ // arena_free_storage(&scratch);
return handle;
}
@@ -85,31 +85,31 @@ typedef struct model {
u32 mesh_count;
} model;
*/
-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);
- vec4u_darray *tmp_joint_indices = vec4u_darray_new(1000);
- vec4_darray *tmp_weights = vec4_darray_new(1000);
- // FIXME
- // joint_darray *tmp_joints = joint_darray_new(256);
- // vertex_bone_data_darray *tmp_vertex_bone_data = vertex_bone_data_darray_new(1000);
-
- cgltf_options options = { 0 };
+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);
+ // vec4u_darray *tmp_joint_indices = vec4u_darray_new(1000);
+ // vec4_darray *tmp_weights = vec4_darray_new(1000);
+ // // FIXME
+ // // joint_darray *tmp_joints = joint_darray_new(256);
+ // // vertex_bone_data_darray *tmp_vertex_bone_data = vertex_bone_data_darray_new(1000);
+
+ // 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_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");
+ // cgltf_load_buffers(&options, data, filepath);
+ // DEBUG("loaded buffers");
// // --- Skin
// size_t num_skins = data->skins_count;
@@ -183,13 +183,13 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
snprintf(normal_map_path, sizeof(normal_map_path), "%s/%s", relative_path.buf,
normal_tex_view.texture->image->uri);
- material our_material =
- pbr_material_load(albedo_map_path, normal_map_path, true, metal_rough_map_path, NULL, NULL);
+ // material our_material =
+ // pbr_material_load(albedo_map_path, normal_map_path, true, metal_rough_map_path, NULL, NULL);
- our_material.name = malloc(strlen(gltf_material.name) + 1);
- strcpy(our_material.name, gltf_material.name);
+ // our_material.name = malloc(strlen(gltf_material.name) + 1);
+ // strcpy(our_material.name, gltf_material.name);
- material_darray_push(out_model->materials, our_material);
+ // material_darray_push(out_model->materials, our_material);
}
// TEMP
@@ -214,11 +214,11 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
TRACE("Loading %d vec3 components", accessor->count);
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- vec3 pos;
- cgltf_accessor_read_float(accessor, v, &pos.x, 3);
- vec3_darray_push(tmp_positions, pos);
- }
+ // for (cgltf_size v = 0; v < accessor->count; ++v) {
+ // vec3 pos;
+ // cgltf_accessor_read_float(accessor, v, &pos.x, 3);
+ // vec3_darray_push(tmp_positions, pos);
+ // }
} else if (attribute.type == cgltf_attribute_type_normal) {
TRACE("Load normals from accessor");
@@ -227,11 +227,11 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
assert(accessor->component_type == cgltf_component_type_r_32f);
// CASSERT_MSG(accessor->type == cgltf_type_vec3, "Normal vectors 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(tmp_normals, pos);
- }
+ // for (cgltf_size v = 0; v < accessor->count; ++v) {
+ // vec3 pos;
+ // cgltf_accessor_read_float(accessor, v, &pos.x, 3);
+ // vec3_darray_push(tmp_normals, pos);
+ // }
} else if (attribute.type == cgltf_attribute_type_texcoord) {
TRACE("Load texture coordinates from accessor");
@@ -241,12 +241,12 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
// 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(tmp_uvs, tex);
+ // vec2 tex;
+ // bool success = cgltf_accessor_read_float(accessor, v, &tex.x, 2);
+ // if (!success) {
+ // ERROR("Error loading tex coord");
+ // }
+ // vec2_darray_push(tmp_uvs, tex);
}
} else if (attribute.type == cgltf_attribute_type_joints) {
// FIXME: joints
@@ -289,18 +289,18 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
}
// mesh.vertex_bone_data = vertex_bone_data_darray_new(1);
- if (primitive.material != NULL) {
- ERROR("Primitive Material %s", primitive.material->name);
- for (u32 i = 0; i < material_darray_len(out_model->materials); i++) {
- printf("%s vs %s \n", primitive.material->name, out_model->materials->data[i].name);
- if (strcmp(primitive.material->name, out_model->materials->data[i].name) == 0) {
- INFO("Found material");
- mat_idx = i;
- // mesh.material_index = i;
- break;
- }
- }
- }
+ // if (primitive.material != NULL) {
+ // ERROR("Primitive Material %s", primitive.material->name);
+ // for (u32 i = 0; i < material_darray_len(out_model->materials); i++) {
+ // printf("%s vs %s \n", primitive.material->name, out_model->materials->data[i].name);
+ // if (strcmp(primitive.material->name, out_model->materials->data[i].name) == 0) {
+ // INFO("Found material");
+ // mat_idx = i;
+ // // mesh.material_index = i;
+ // break;
+ // }
+ // }
+ // }
// // FIXME
// // if (is_skinned) {
@@ -322,34 +322,34 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
// // }
bool has_indices = false;
- vertex_darray *geo_vertices = vertex_darray_new(3);
+ 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);
- for (u32 v_i = 0; v_i < tmp_positions->len; v_i++) {
- vertex v = { .static_3d = {
- .position = tmp_positions->data[v_i],
- .normal = tmp_normals->data[v_i],
- .tex_coords = tmp_uvs->data[v_i],
- } };
- vertex_darray_push(geo_vertices, v);
+ // 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);
+ // for (u32 v_i = 0; v_i < tmp_positions->len; v_i++) {
+ // vertex v = { .static_3d = {
+ // .position = tmp_positions->data[v_i],
+ // .normal = tmp_normals->data[v_i],
+ // .tex_coords = tmp_uvs->data[v_i],
+ // } };
+ // vertex_darray_push(geo_vertices, v);
}
// Store indices
- cgltf_accessor *indices = primitive.indices;
- if (primitive.indices > 0) {
- WARN("indices! %d", indices->count);
- has_indices = true;
-
- // 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);
- }
+ // cgltf_accessor *indices = primitive.indices;
+ // if (primitive.indices > 0) {
+ // WARN("indices! %d", indices->count);
+ // has_indices = true;
+
+ // // 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);
+ // }
// fetch and store vertices for each index
// for (cgltf_size i = 0; i < indices->count; ++i) {
@@ -366,23 +366,23 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
// }
// // for each vertex do the bone data
// }
- } else {
- has_indices = false;
- return false; // TODO: handle this
- }
-
- geometry_data *geometry = malloc(sizeof(geometry_data));
- geometry->format = VERTEX_STATIC_3D;
- geometry->colour = (rgba){ 1, 1, 1, 1 };
- geometry->vertices = geo_vertices;
- geometry->indices = geo_indices;
- geometry->has_indices = has_indices;
-
- mesh m = mesh_create(geometry, true);
- m.material_index = (u32_opt){ .has_value = mat_idx == 9999, .value = mat_idx };
-
- mesh_darray_push(out_model->meshes, m);
- }
+ // } else {
+ // has_indices = false;
+ // return false; // TODO: handle this
+ // }
+
+ // geometry_data *geometry = malloc(sizeof(geometry_data));
+ // geometry->format = VERTEX_STATIC_3D;
+ // geometry->colour = (rgba){ 1, 1, 1, 1 };
+ // geometry->vertices = geo_vertices;
+ // geometry->indices = geo_indices;
+ // geometry->has_indices = has_indices;
+
+ // mesh m = mesh_create(geometry, true);
+ // m.material_index = (u32_opt){ .has_value = mat_idx == 9999, .value = mat_idx };
+
+ // mesh_darray_push(out_model->meshes, m);
+ // }
// // clear data for each mesh
// vec3_darray_clear(tmp_positions);
diff --git a/src/resources/loaders.h b/src/resources/loaders.h
index fe03ed9..d8437b9 100644
--- a/src/resources/loaders.h
+++ b/src/resources/loaders.h
@@ -2,8 +2,12 @@
#include "defines.h"
#include "render_types.h"
+#include "str.h"
-struct core;
+// --- Public API
+ModelHandle Model_Load_obj(const char *path, bool invert_texture_y);
+ModelHandle Model_Load_gltf(const char *path, bool invert_texture_y);
-model_handle model_load_obj(const char *path, bool invert_texture_y);
-model_handle model_load_gltf(const char *path, bool invert_texture_y);
+// --- 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
index 411ad82..87d3ed6 100644
--- a/src/resources/obj.c
+++ b/src/resources/obj.c
@@ -22,7 +22,7 @@
#include "render_types.h"
#include "str.h"
-extern core g_core;
+extern Core g_core;
struct face {
u32 vertex_indices[3];
@@ -31,19 +31,19 @@ struct face {
};
typedef struct face face;
-KITC_DECL_TYPED_ARRAY(vec3)
-KITC_DECL_TYPED_ARRAY(vec2)
+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);
-
-model_handle model_load_obj(core *core, const char *path, bool invert_textures_y) {
+// 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);
@@ -54,24 +54,24 @@ model_handle model_load_obj(core *core, const char *path, bool invert_textures_y
}
const char *file_string = string_from_file(path);
- model_handle handle;
- model *model = model_pool_alloc(&g_core.models, &handle);
- model->name = str8_cstr_view(path);
- model->meshes = mesh_darray_new(1);
+ 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);
+ // 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");
- }
+ // 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);
+ // 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 model_load_obj_str(const char *file_string, Str8 relative_path, Model *out_model,
bool invert_textures_y) {
TRACE("Load OBJ from string");
@@ -232,166 +232,166 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_
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;
-}
+// /**
+// * @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/scene.c b/src/scene.c
index d9fea05..f6f5fb7 100644
--- a/src/scene.c
+++ b/src/scene.c
@@ -1,56 +1,57 @@
#include "scene.h"
+#include "camera.h"
#include "core.h"
#include "log.h"
#include "maths.h"
#include "render_types.h"
-extern core g_core;
+extern Core g_core;
-void scene_init(scene *s) {
- memset(s, 0, sizeof(scene));
- s->renderables = render_entity_darray_new(10);
- // default camera position - moved slightly along Z axis looking at 0,0,0
- vec3 cam_pos = vec3_create(0, 0, -5);
- s->camera = camera_create(cam_pos, vec3_negate(cam_pos), VEC3_Y, deg_to_rad(45.0));
-}
-void scene_free(scene *s) { render_entity_darray_free(s->renderables); }
+// void scene_init(scene *s) {
+// memset(s, 0, sizeof(scene));
+// s->renderables = render_entity_darray_new(10);
+// // default camera position - moved slightly along Z axis looking at 0,0,0
+// Vec3 cam_pos = vec3_create(0, 0, -5);
+// s->camera = Camera_Create(cam_pos, vec3_negate(cam_pos), VEC3_Y, deg_to_rad(45.0));
+// }
+// void scene_free(scene *s) { render_entity_darray_free(s->renderables); }
-void scene_set_dir_light(directional_light light) { g_core.default_scene.dir_light = light; }
-void scene_add_point_light(point_light light) {
- scene s = g_core.default_scene;
- if (s.point_lights_count == 4) {
- WARN("Already 4 point lights, we can't add more.");
- } else {
- s.point_lights[s.point_lights_count] = light;
- s.point_lights_count++;
- }
-}
-void scene_add_model(model_handle model, transform3d transform) {
- render_entity renderable = { .model = model, .tf = transform };
- render_entity_darray_push(g_core.default_scene.renderables, renderable);
-}
+// void scene_set_dir_light(directional_light light) { g_core.default_scene.dir_light = light; }
+// void scene_add_point_light(point_light light) {
+// scene s = g_core.default_scene;
+// if (s.point_lights_count == 4) {
+// WARN("Already 4 point lights, we can't add more.");
+// } else {
+// s.point_lights[s.point_lights_count] = light;
+// s.point_lights_count++;
+// }
+// }
+// void scene_add_model(model_handle model, transform3d transform) {
+// render_entity renderable = { .model = model, .tf = transform };
+// render_entity_darray_push(g_core.default_scene.renderables, renderable);
+// }
-bool scene_remove_model(model_handle model) {
- scene s = g_core.default_scene;
- for (u32 i = 0; i <= s.renderables->len; i++) {
- if (s.renderables->data[i].model.raw == model.raw) {
- // TODO: add remove function to darray
- }
- }
- return true;
-}
+// bool scene_remove_model(model_handle model) {
+// scene s = g_core.default_scene;
+// for (u32 i = 0; i <= s.renderables->len; i++) {
+// if (s.renderables->data[i].model.raw == model.raw) {
+// // TODO: add remove function to darray
+// }
+// }
+// return true;
+// }
-void scene_set_model_transform(model_handle model, transform3d new_transform) {
- scene s = g_core.default_scene;
- for (u32 i = 0; i <= s.renderables->len; i++) {
- if (s.renderables->data[i].model.raw == model.raw) {
- s.renderables->data[i].tf = new_transform;
- }
- }
-}
+// void scene_set_model_transform(model_handle model, transform3d new_transform) {
+// scene s = g_core.default_scene;
+// for (u32 i = 0; i <= s.renderables->len; i++) {
+// if (s.renderables->data[i].model.raw == model.raw) {
+// s.renderables->data[i].tf = new_transform;
+// }
+// }
+// }
-void scene_set_camera(vec3 pos, vec3 front) {
- scene s = g_core.default_scene;
- s.camera.position = pos;
- s.camera.front = front;
-}
+// void scene_set_camera(vec3 pos, vec3 front) {
+// scene s = g_core.default_scene;
+// s.camera.position = pos;
+// s.camera.front = front;
+// }
diff --git a/src/scene.h b/src/scene.h
index 5ac7542..e414ea8 100644
--- a/src/scene.h
+++ b/src/scene.h
@@ -14,20 +14,20 @@
#include "maths_types.h"
#include "render_types.h"
-typedef struct scene {
- // camera
- camera camera;
- // lights
- directional_light dir_light;
- point_light point_lights[4];
- size_t point_lights_count;
- // geometry
- render_entity_darray* renderables;
- // TODO: tree - transform_hierarchy
-} scene;
-
-void scene_init(scene* s);
-void scene_free(scene* s);
+// typedef struct scene {
+// // camera
+// Camera camera;
+// // lights
+// DirectionalLight dir_light;
+// PointLight point_lights[4];
+// size_t point_lights_count;
+// // geometry
+// render_entity_darray* renderables;
+// // TODO: tree - transform_hierarchy
+// } scene;
+
+// void scene_init(scene* s);
+// void scene_free(scene* s);
// Simplified API - no scene pointer; gets and sets global scene
@@ -36,16 +36,16 @@ void scene_free(scene* s);
/* vec3 ambient; */
/* vec3 diffuse; */
/* vec3 specular; */
-void scene_set_dir_light(directional_light light);
-void _scene_set_dir_light(vec3 ambient, vec3 diffuse, vec3 specular, vec3 direction);
+// void scene_set_dir_light(directional_light light);
+// void _scene_set_dir_light(vec3 ambient, vec3 diffuse, vec3 specular, vec3 direction);
-void scene_add_point_light(point_light light);
-void scene_add_model(model_handle model, transform3d transform);
-bool scene_remove_model(model_handle model);
+// void scene_add_point_light(point_light light);
+// void scene_add_model(model_handle model, transform3d transform);
+// bool scene_remove_model(model_handle model);
-// Getter & Setters
-void scene_set_model_transform(model_handle model, transform3d new_transform);
-void scene_set_camera(vec3 pos, vec3 front);
+// // Getter & Setters
+// void scene_set_model_transform(model_handle model, transform3d new_transform);
+// void scene_set_camera(vec3 pos, vec3 front);
/* // There can only be one heightmap terrain at a time right now. */
/* bool scene_add_heightmap(scene* s /\* TODO *\/); */
diff --git a/src/std/containers/darray.h b/src/std/containers/darray.h
index b15d269..b3dbd06 100644
--- a/src/std/containers/darray.h
+++ b/src/std/containers/darray.h
@@ -86,6 +86,7 @@
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; \
@@ -97,6 +98,7 @@
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; \
@@ -116,6 +118,7 @@
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 */ \
@@ -136,14 +139,6 @@
\
PREFIX size_t Type##_darray_len(Type##_darray *d) { return d->len; } \
\
- PREFIX void Type##_darray_print(Type##_darray *d) { \
- printf("len: %zu ", d->len); \
- printf("capacity: %zu\n", d->capacity); \
- for (int i = 0; i < d->len; i++) { \
- printf("Index %d holds value %d\n", i, d->data[i]); \
- } \
- } \
- \
PREFIX Type##_darray_iter Type##_darray_iter_new(Type##_darray *d) { \
Type##_darray_iter iterator; \
iterator.array = d; \
diff --git a/src/std/mem.h b/src/std/mem.h
index 8ab6f46..789cba3 100644
--- a/src/std/mem.h
+++ b/src/std/mem.h
@@ -80,12 +80,12 @@ void void_pool_dealloc(void_pool* pool, u32 raw_handle);
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) { \
+ 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) { \
+ 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) { \
+ static inline void Name##_pool_dealloc(Name##_pool* pool, Name##Handle handle) { \
void_pool_dealloc(&pool->inner, handle.raw); \
}\
diff --git a/src/std/str.c b/src/std/str.c
index 07a8e73..e15c38f 100644
--- a/src/std/str.c
+++ b/src/std/str.c
@@ -3,62 +3,62 @@
#include <string.h>
#include "mem.h"
-str8 str8_create(u8* buf, size_t len) { return (str8){ .buf = buf, .len = len }; }
+// 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)); }
+// 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;
- }
+// 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;
-}
+// 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;
+// 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);
+// u8* dest = arena_alloc(a, n_bytes);
- memcpy(dest, s.buf, s.len);
- if (is_null_terminated) {
- dest[s.len] = '\0';
- }
- return (char*)dest;
-}
+// memcpy(dest, s.buf, s.len);
+// if (is_null_terminated) {
+// dest[s.len] = '\0';
+// }
+// return (char*)dest;
+// }
-str8 str8_concat(arena* a, str8 left, str8 right) {
- size_t n_bytes = left.len + right.len + 1;
+// 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);
+// 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';
+// dest[n_bytes - 1] = '\0';
- return str8_create(dest, n_bytes);
-}
+// 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_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_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_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_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); }
+// 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
index 1ebecac..e9c4098 100644
--- a/src/std/str.h
+++ b/src/std/str.h
@@ -23,30 +23,30 @@
typedef struct {
u8* buf;
size_t len;
-} str8;
+} Str8;
// --- Constructors
/** @brief Take a string literal and turn it into a `str8` */
-#define str8lit(s) \
- (str8) { (u8*)s, ((sizeof(s) / sizeof(*(s)) - 1)) }
+#define str8(s) \
+ (Str8) { (u8*)s, ((sizeof(s) / sizeof(*(s)) - 1)) }
-str8 str8_create(u8* buf, size_t len);
+Str8 str8_create(u8* buf, size_t len);
/** @brief Return a null-terminated C string cloned onto an arena */
-char* str8_to_cstr(arena* a, str8 s);
+char* Str8_to_cstr(arena* a, Str8 s);
-#define cstr(a, s) (str8_to_cstr(a, s)) // Shorthand
+#define cstr(a, s) (Str8_to_cstr(a, s)) // Shorthand
-/** @brief Return a str8 that references a statically allocated string.
+/** @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);
+Str8 Str8_cstr_view(char* string);
// --- Comparisons
/** @brief Compare two strings for exact equality */
-bool str8_equals(str8 a, str8 b);
+bool Str8_equals(Str8 a, Str8 b);
/**
* @brief Compare the first `first_nchars` of each string for equality
@@ -55,27 +55,27 @@ bool str8_equals(str8 a, str8 b);
* @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);
+size_t Str8_nequals(Str8 a, Str8 b, size_t first_nchars);
-bool str8_ends_with(str8 input_str, str8 suffix);
+bool Str8_ends_with(Str8 input_str, Str8 suffix);
/// --- Subviews
-str8 str8_substr(str8 s, u64 min, u64 max);
+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);
+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);
+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);
+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_chop(Str8 s, u64 n);
-str8 str8_concat(arena* a, str8 left, str8 right);
+Str8 Str8_concat(arena* a, Str8 left, Str8 right);
/// --- Misc
-static inline bool str8_is_null_term(str8 a) {
+static inline bool Str8_is_null_term(Str8 a) {
return a.buf[a.len] == 0; // This doesn't seem safe. YOLO
}
diff --git a/src/systems/input.c b/src/systems/input.c
index 0c8f768..a371ecd 100644
--- a/src/systems/input.c
+++ b/src/systems/input.c
@@ -6,11 +6,11 @@
#include "log.h"
-static input_state *g_input; // Use a global to simplify caller code
+static Input_State *g_input; // Use a global to simplify caller code
-bool input_system_init(input_state *input, GLFWwindow *window) {
+bool Input_Init(Input_State *input, GLFWwindow *window) {
INFO("Input init");
- memset(input, 0, sizeof(input_state));
+ 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
@@ -29,9 +29,9 @@ bool input_system_init(input_state *input, GLFWwindow *window) {
return true;
}
-void input_system_shutdown(input_state *input) {}
+void Input_Shutdown(Input_State *input) {}
-void input_update(input_state *input) {
+void Input_Update(Input_State *input) {
glfwPollEvents();
// --- update keyboard input
@@ -95,4 +95,4 @@ 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]; } \ No newline at end of file
+bool key_just_released(keycode key) { return g_input->just_released_keys[key]; }
diff --git a/src/systems/input.h b/src/systems/input.h
index c119016..11c40ea 100644
--- a/src/systems/input.h
+++ b/src/systems/input.h
@@ -6,7 +6,6 @@
#include "defines.h"
#include "keys.h"
-struct core;
struct GLFWWindow;
typedef struct mouse_state {
@@ -18,13 +17,13 @@ typedef struct mouse_state {
bool left_btn_pressed;
} mouse_state;
-typedef struct input_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;
+} Input_State;
/** @brief `key` is currently being held down */
bool key_is_pressed(keycode key);
@@ -36,6 +35,8 @@ bool key_just_pressed(keycode key);
bool key_just_released(keycode key);
// --- Lifecycle
-bool input_system_init(input_state *input, struct GLFWwindow *window);
-void input_system_shutdown(input_state *input);
-void input_update(input_state *state); \ No newline at end of file
+
+bool Input_Init(Input_State *input, struct GLFWwindow *window);
+void Input_Shutdown(Input_State *input);
+
+void Input_Update(Input_State *state); // must be run once per main loop
diff --git a/src/systems/terrain.c b/src/systems/terrain.c
index 6342d66..1d23cc3 100644
--- a/src/systems/terrain.c
+++ b/src/systems/terrain.c
@@ -1,24 +1,27 @@
/**
- * @file terrain.c
- * @author your name (you@domain.com)
* @brief
- * @version 0.1
- * @date 2024-06-22
- *
- * @copyright Copyright (c) 2024
- *
*/
#include "terrain.h"
#include "ral.h"
-bool terrain_system_init(terrain_state* state) {
- gpu_renderpass_desc rpass_desc = {
- .default_framebuffer = true,
- };
- struct graphics_pipeline_desc pipeline_desc = {
+struct Terrain_Storage {
+ arena terrain_allocator;
+ Heightmap* heightmap; // NULL = no heightmap
+ GPU_Renderpass* hmap_renderpass;
+ GPU_Pipeline* hmap_pipeline;
+};
- };
+PUB bool Terrain_Init(Terrain_Storage* storage) { return true; }
+PUB void Terrain_Shutdown(Terrain_Storage* storage);
- state->hmap_renderpass = gpu_renderpass_create(&rpass_desc);
- state->hmap_pipeline = gpu_graphics_pipeline_create(pipeline_desc);
-} \ No newline at end of file
+/* bool terrain_system_init(terrain_state* state) { */
+/* gpu_renderpass_desc rpass_desc = { */
+/* .default_framebuffer = true, */
+/* }; */
+/* struct graphics_pipeline_desc pipeline_desc = { */
+
+/* }; */
+
+/* state->hmap_renderpass = gpu_renderpass_create(&rpass_desc); */
+/* state->hmap_pipeline = gpu_graphics_pipeline_create(pipeline_desc); */
+/* } */
diff --git a/src/systems/terrain.h b/src/systems/terrain.h
index 888b6f4..890cb90 100644
--- a/src/systems/terrain.h
+++ b/src/systems/terrain.h
@@ -1,14 +1,10 @@
/**
* @file terrain.h
- * @author your name (you@domain.com)
* @brief
- * @version 0.1
- * @date 2024-04-27
- *
- * @copyright Copyright (c) 2024
- *
*/
+#pragma once
+
/*
Future:
- Chunked terrain
@@ -22,37 +18,37 @@ Future:
#include "render.h"
#include "str.h"
-typedef struct heightmap {
- str8 filepath;
+typedef struct Heightmap {
+ Str8 filepath;
u32x2 size;
void* image_data;
bool is_uploaded;
-} heightmap;
+} Heightmap;
+
+typedef struct Terrain_Storage Terrain_Storage;
+
+// --- Public API
+PUB bool Terrain_Init(Terrain_Storage* storage);
+PUB void Terrain_Shutdown(Terrain_Storage* storage);
+PUB void Terrain_Run(Terrain_Storage* storage); // NOTE: For now it renders directly to main framebuffer
-typedef struct terrain_state {
- arena terrain_allocator;
- heightmap* heightmap; // NULL = no heightmap
- gpu_renderpass* hmap_renderpass;
- gpu_pipeline* hmap_pipeline;
-} terrain_state;
+/** @brief Sets the active heightmap to be rendered and collided against. */
+PUB Heightmap Terrain_LoadHeightmap(Heightmap hmap, bool free_on_upload);
+PUB Heightmap Heightmap_FromImage(Str8 filepath);
+PUB Heightmap Heightmap_FromPerlin(/* TODO: perlin noise generation parameters */);
-bool terrain_system_init(terrain_state* state);
-void terrain_system_shutdown(terrain_state* state);
-void terrain_system_render_hmap(renderer* rend, terrain_state* state);
+PUB bool Terrain_IsActive(); // checks whether we have a loaded heightmap and it's being rendered
-heightmap heightmap_from_image(str8 filepath);
-heightmap heightmap_from_perlin(/* TODO: perlin noise generation parameters */);
+// --- Internal
+
+// TODO: void terrain_system_render_hmap(renderer* rend, terrain_state* state);
/** @brief Get the height (the Y component) for a vertex at a particular coordinate in the heightmap
*/
-f32 heightmap_height_at_xz(heightmap* hmap, f32 x, f32 z);
+f32 Heightmap_HeightXZ(Heightmap* hmap, f32 x, f32 z);
/** @brief Calculate the normal vector of a vertex at a particular coordinate in the heightmap */
-vec3 heightmap_normal_at_xz(heightmap* hmap, f32 x, f32 z);
+Vec3 Heightmap_NormalXZ(Heightmap* hmap, f32 x, f32 z);
/** @brief Generate the `geometry_data` for a heightmap ready to be uploaded to the GPU */
-geometry_data geo_heightmap(arena* a, heightmap heightmap);
-
-// somewhere there will be an easy way to add a heightmap
-
-// TODO: scene_add_heightmap
+Geometry geo_heightmap(arena* a, Heightmap heightmap);
diff --git a/src/systems/text.h b/src/systems/text.h
index f40cfd6..983ffd6 100644
--- a/src/systems/text.h
+++ b/src/systems/text.h
@@ -10,44 +10,44 @@
#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); \ No newline at end of file
+// 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
index b9795bc..a5f4d97 100644
--- a/src/transform_hierarchy.c
+++ b/src/transform_hierarchy.c
@@ -11,174 +11,175 @@
#include "log.h"
#include "maths.h"
#include "maths_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, model_handle 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);
-} \ No newline at end of file
+#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
index 0921c19..808baab 100644
--- a/src/transform_hierarchy.h
+++ b/src/transform_hierarchy.h
@@ -10,68 +10,69 @@
#define MAX_TF_NODE_CHILDREN \
32 /** TEMP: Make it simpler to manage children in `transform_node`s */
-typedef struct transform_hierarchy transform_hierarchy;
+typedef struct TransformHierarchy TransformHierarchy;
-struct transform_node {
- model_handle 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 {
+ 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 Transform_Node;
+typedef struct Transform_Node TF_Node;
// --- Lifecycle
/** @brief Allocates and returns an empty transform hierarchy with a root node */
-transform_hierarchy* transform_hierarchy_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* transform_hierarchy_root_node(transform_hierarchy* tfh);
-
-// --- Mutations
-transform_node* transform_hierarchy_add_node(transform_node* parent, model_handle 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); \ No newline at end of file
+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);
diff --git a/src/ui/ui.h b/src/ui/ui.h
new file mode 100644
index 0000000..c5ace97
--- /dev/null
+++ b/src/ui/ui.h
@@ -0,0 +1,13 @@
+/**
+ * @brief
+ */
+
+#pragma once
+#include "defines.h"
+
+typedef struct UI_Storage UI_Storage;
+
+PUB bool UI_Init(UI_Storage* storage);
+PUB void UI_Shutdown(UI_Storage* storage);
+
+// TODO: define immui api
diff --git a/xmake.lua b/xmake.lua
index 335e751..960923b 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -24,31 +24,31 @@ if is_plat("linux") then
elseif is_plat("windows") then
add_defines("CEL_PLATFORM_WINDOWS")
add_syslinks("user32", "gdi32", "kernel32", "shell32")
- add_requires("vulkansdk", {system=true})
+ add_requires("vulkansdk", { system = true })
-- add_links("pthreadVC2-w64")
elseif is_plat("macosx") then
add_defines("CEL_PLATFORM_MAC")
add_frameworks("Cocoa", "IOKit", "CoreVideo", "OpenGL")
- add_frameworks( "Foundation", "Metal", "QuartzCore")
+ add_frameworks("Foundation", "Metal", "QuartzCore")
set_runenv("MTL_DEBUG_LAYER", "1")
-- add_syslinks("GL")
end
-- Compile GLFW from source
package("local_glfw")
- add_deps("cmake")
- set_sourcedir(path.join(os.scriptdir(), "deps/glfw-3.3.8"))
- on_install(function (package)
- local configs = {}
- -- NOTE(omni): Keeping these around as comments in case we need to modify glfw flags
- -- table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))
- -- table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
- import("package.tools.cmake").install(package, configs)
- end)
- on_test(function (package)
- -- assert(package:has_cfuncs("add", {includes = "foo.h"}))
- end)
+add_deps("cmake")
+set_sourcedir(path.join(os.scriptdir(), "deps/glfw-3.3.8"))
+on_install(function(package)
+ local configs = {}
+ -- NOTE(omni): Keeping these around as comments in case we need to modify glfw flags
+ -- table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))
+ -- table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
+ import("package.tools.cmake").install(package, configs)
+end)
+on_test(function(package)
+ -- assert(package:has_cfuncs("add", {includes = "foo.h"}))
+end)
package_end()
add_requires("local_glfw")
@@ -56,13 +56,17 @@ add_requires("local_glfw")
local core_sources = {
"deps/glad/src/glad.c",
"src/*.c",
+ "src/core/*.c",
-- "src/logos/*.c",
"src/maths/*.c",
"src/platform/*.c",
"src/physics/*.c",
- "src/renderer/*.c",
- "src/renderer/backends/*.c",
- "src/renderer/backends/opengl/*.c",
+ "src/ral/*.c",
+ -- "src/ral/backends/opengl/*.c",
+ "src/new_render/*.c",
+ -- "src/renderer/*.c",
+ -- "src/renderer/backends/*.c",
+ -- "src/renderer/backends/opengl/*.c",
"src/resources/*.c",
"src/std/*.c",
"src/std/containers/*.c",
@@ -76,88 +80,92 @@ local unity_sources = {
}
rule("compile_glsl_vert_shaders")
- set_extensions(".vert")
- on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
- local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".vert.spv")
-
- print("Compiling shader: %s to %s", sourcefile, targetfile)
- batchcmds:vrunv('glslc', {sourcefile, "-o", targetfile})
- -- batchcmds:add_depfiles(sourcefile)
+set_extensions(".vert")
+on_buildcmd_file(function(target, batchcmds, sourcefile, opt)
+ local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".vert.spv")
+
+ print("Compiling shader: %s to %s", sourcefile, targetfile)
+ batchcmds:vrunv('glslc', { sourcefile, "-o", targetfile })
+ -- batchcmds:add_depfiles(sourcefile)
end)
rule("compile_glsl_frag_shaders")
- set_extensions(".frag")
- on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
- local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".frag.spv")
-
- print("Compiling shader: %s to %s", sourcefile, targetfile)
- batchcmds:vrunv('glslc', {sourcefile, "-o", targetfile})
- -- batchcmds:add_depfiles(sourcefile)
+set_extensions(".frag")
+on_buildcmd_file(function(target, batchcmds, sourcefile, opt)
+ local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".frag.spv")
+
+ print("Compiling shader: %s to %s", sourcefile, targetfile)
+ batchcmds:vrunv('glslc', { sourcefile, "-o", targetfile })
+ -- batchcmds:add_depfiles(sourcefile)
end)
-- TODO: Metal shaders compilation
-- common configuration for both static and shared libraries
target("core_config")
- set_kind("static") -- kind is required but you can ignore it since it's just for common settings
- add_packages("local_glfw")
- add_defines("CEL_REND_BACKEND_OPENGL")
- add_includedirs("deps/cgltf", {public = true})
- add_includedirs("deps/glfw-3.3.8/include/GLFW", {public = true})
- add_includedirs("deps/glad/include", {public = true})
- add_includedirs("deps/stb_image", {public = true})
- add_includedirs("deps/stb_image_write", {public = true})
- add_includedirs("deps/stb_truetype", {public = true})
- add_includedirs("include/", {public = true})
- add_includedirs("src/", {public = true})
- -- add_includedirs("src/logos/", {public = true})
- add_includedirs("src/maths/", {public = true})
- add_includedirs("src/platform/", {public = true})
- add_includedirs("src/physics/", {public = true})
- add_includedirs("src/renderer/", {public = true})
- add_includedirs("src/renderer/backends/", {public = true})
- add_includedirs("src/renderer/backends/opengl", {public = true})
- add_includedirs("src/renderer/backends/metal", {public = true})
- add_includedirs("src/resources/", {public = true})
- add_includedirs("src/std/", {public = true})
- add_includedirs("src/std/containers", {public = true})
- add_includedirs("src/systems/", {public = true})
- add_files("src/empty.c") -- for some reason we need this on Mac so it doesnt call 'ar' with no files and error
- -- add_rules("compile_glsl_vert_shaders")
- -- add_rules("compile_glsl_frag_shaders")
- -- add_files("assets/shaders/triangle.vert")
- -- add_files("assets/shaders/triangle.frag")
- -- add_files("assets/shaders/cube.vert")
- -- add_files("assets/shaders/cube.frag")
- -- add_files("assets/shaders/*.frag")
- if is_plat("windows") then
- add_includedirs("$(env VULKAN_SDK)/Include", {public = true})
- add_linkdirs("$(env VULKAN_SDK)/Lib", {public = true})
- add_links("vulkan-1")
- end
- if is_plat("macosx") then
- add_files("src/renderer/backends/metal/*.m")
- end
- set_default(false) -- prevents standalone building of this target
+set_kind("static") -- kind is required but you can ignore it since it's just for common settings
+add_packages("local_glfw")
+add_defines("CEL_REND_BACKEND_OPENGL")
+add_includedirs("deps/cgltf", { public = true })
+add_includedirs("deps/glfw-3.3.8/include/GLFW", { public = true })
+add_includedirs("deps/glad/include", { public = true })
+add_includedirs("deps/stb_image", { public = true })
+add_includedirs("deps/stb_image_write", { public = true })
+add_includedirs("deps/stb_truetype", { public = true })
+add_includedirs("include/", { public = true })
+add_includedirs("src/", { public = true })
+add_includedirs("src/core", { public = true })
+-- add_includedirs("src/logos/", {public = true})
+add_includedirs("src/maths/", { public = true })
+add_includedirs("src/platform/", { public = true })
+add_includedirs("src/physics/", { public = true })
+add_includedirs("src/ral", { public = true })
+add_includedirs("src/ral/backends/opengl", { public = true })
+add_includedirs("src/new_render", { public = true })
+-- add_includedirs("src/renderer/", {public = true})
+-- add_includedirs("src/renderer/backends/", {public = true})
+-- add_includedirs("src/renderer/backends/opengl", {public = true})
+-- add_includedirs("src/renderer/backends/metal", {public = true})
+add_includedirs("src/resources/", { public = true })
+add_includedirs("src/std/", { public = true })
+add_includedirs("src/std/containers", { public = true })
+add_includedirs("src/systems/", { public = true })
+add_files("src/empty.c") -- for some reason we need this on Mac so it doesnt call 'ar' with no files and error
+-- add_rules("compile_glsl_vert_shaders")
+-- add_rules("compile_glsl_frag_shaders")
+-- add_files("assets/shaders/triangle.vert")
+-- add_files("assets/shaders/triangle.frag")
+-- add_files("assets/shaders/cube.vert")
+-- add_files("assets/shaders/cube.frag")
+-- add_files("assets/shaders/*.frag")
+if is_plat("windows") then
+ add_includedirs("$(env VULKAN_SDK)/Include", { public = true })
+ add_linkdirs("$(env VULKAN_SDK)/Lib", { public = true })
+ add_links("vulkan-1")
+end
+if is_plat("macosx") then
+ add_files("src/renderer/backends/metal/*.m")
+end
+set_default(false) -- prevents standalone building of this target
target("core_static")
- set_kind("static")
- add_deps("core_config") -- inherit common configurations
- set_policy("build.merge_archive", true)
- add_files(core_sources)
- -- Link against static CRT
- if is_plat("windows") then
- add_links("libcmt", "legacy_stdio_definitions") -- for release builds
- add_links("libcmtd", "legacy_stdio_definitions") -- for debug builds
- end
+set_kind("static")
+add_deps("core_config") -- inherit common configurations
+set_policy("build.merge_archive", true)
+add_files(core_sources)
+-- Link against static CRT
+if is_plat("windows") then
+ add_links("libcmt", "legacy_stdio_definitions") -- for release builds
+ add_links("libcmtd", "legacy_stdio_definitions") -- for debug builds
+end
target("core_shared")
- set_kind("shared")
- add_deps("core_config") -- inherit common configurations
- add_files(core_sources)
- -- Link against dynamic CRT
- if is_plat("windows") then
- add_links("msvcrt", "legacy_stdio_definitions") -- for release builds
- add_links("msvcrtd", "legacy_stdio_definitions") -- for debug builds
- end
+set_kind("shared")
+add_deps("core_config") -- inherit common configurations
+add_files(core_sources)
+-- Link against dynamic CRT
+if is_plat("windows") then
+ add_links("msvcrt", "legacy_stdio_definitions") -- for release builds
+ add_links("msvcrtd", "legacy_stdio_definitions") -- for debug builds
+end
-- target("main_loop")
-- set_kind("binary")
@@ -166,84 +174,84 @@ target("core_shared")
-- add_files("examples/main_loop/ex_main_loop.c")
-- set_rundir("$(projectdir)")
-target("tri")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/triangle/ex_triangle.c")
- set_rundir("$(projectdir)")
- if is_plat("macosx") then
- before_build(function (target)
- print("build metal shaders lib")
- os.exec("mkdir -p build/shaders")
- os.exec("xcrun -sdk macosx metal -c assets/shaders/triangle.metal -o build/shaders/gfx.air")
- os.exec("xcrun -sdk macosx metallib build/shaders/gfx.air -o build/gfx.metallib")
- end)
- end
-
-target("cube")
- set_kind("binary")
- set_group("examples")
- -- add_defines("CEL_REND_BACKEND_OPENGL")
- add_deps("core_static")
- add_files("examples/cube/ex_cube.c")
- set_rundir("$(projectdir)")
-
-target("primitives")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/primitives/ex_primitives.c")
- set_rundir("$(projectdir)")
-
--- target("std")
+-- target("tri")
-- set_kind("binary")
-- set_group("examples")
-- add_deps("core_static")
--- add_files("examples/standard_lib/ex_std.c")
+-- add_files("examples/triangle/ex_triangle.c")
-- set_rundir("$(projectdir)")
+-- if is_plat("macosx") then
+-- before_build(function (target)
+-- print("build metal shaders lib")
+-- os.exec("mkdir -p build/shaders")
+-- os.exec("xcrun -sdk macosx metal -c assets/shaders/triangle.metal -o build/shaders/gfx.air")
+-- os.exec("xcrun -sdk macosx metallib build/shaders/gfx.air -o build/gfx.metallib")
+-- end)
+-- end
--- target("obj")
+-- target("cube")
-- set_kind("binary")
-- set_group("examples")
+-- -- add_defines("CEL_REND_BACKEND_OPENGL")
-- add_deps("core_static")
--- add_files("examples/obj_loading/ex_obj_loading.c")
+-- add_files("examples/cube/ex_cube.c")
-- set_rundir("$(projectdir)")
--- target("input")
+-- target("primitives")
-- set_kind("binary")
-- set_group("examples")
-- add_deps("core_static")
--- add_files("examples/input/ex_input.c")
+-- add_files("examples/primitives/ex_primitives.c")
-- set_rundir("$(projectdir)")
-target("gltf")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/gltf_loading/ex_gltf_loading.c")
- set_rundir("$(projectdir)")
-
-target("pbr_params")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/pbr_params/ex_pbr_params.c")
- set_rundir("$(projectdir)")
-
-target("pbr_textured")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/pbr_textured/ex_pbr_textured.c")
- set_rundir("$(projectdir)")
-
-target("shadows")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/shadow_maps/ex_shadow_maps.c")
- set_rundir("$(projectdir)")
+-- -- target("std")
+-- -- set_kind("binary")
+-- -- set_group("examples")
+-- -- add_deps("core_static")
+-- -- add_files("examples/standard_lib/ex_std.c")
+-- -- set_rundir("$(projectdir)")
+
+-- -- target("obj")
+-- -- set_kind("binary")
+-- -- set_group("examples")
+-- -- add_deps("core_static")
+-- -- add_files("examples/obj_loading/ex_obj_loading.c")
+-- -- set_rundir("$(projectdir)")
+
+-- -- target("input")
+-- -- set_kind("binary")
+-- -- set_group("examples")
+-- -- add_deps("core_static")
+-- -- add_files("examples/input/ex_input.c")
+-- -- set_rundir("$(projectdir)")
+
+-- target("gltf")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/gltf_loading/ex_gltf_loading.c")
+-- set_rundir("$(projectdir)")
+
+-- target("pbr_params")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/pbr_params/ex_pbr_params.c")
+-- set_rundir("$(projectdir)")
+
+-- target("pbr_textured")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/pbr_textured/ex_pbr_textured.c")
+-- set_rundir("$(projectdir)")
+
+-- target("shadows")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/shadow_maps/ex_shadow_maps.c")
+-- set_rundir("$(projectdir)")
-- target("transforms")
-- set_kind("binary")
@@ -280,13 +288,20 @@ target("shadows")
-- add_files("examples/demo/demo.c")
-- set_rundir("$(projectdir)")
-target("pool_tests")
- set_kind("binary")
- set_group("tests")
- add_deps("core_static")
- add_files(unity_sources)
- add_includedirs("deps/Unity/src", {public = true})
- add_includedirs("deps/Unity/extras/fixture/src", {public = true})
- add_includedirs("deps/Unity/extras/memory/src", {public = true})
- add_files("tests/pool_tests.c")
- add_files("tests/pool_test_runner.c")
+target("game")
+set_kind("binary")
+set_group("examples")
+add_deps("core_static")
+add_files("examples/game_demo/game_demo.c")
+set_rundir("$(projectdir)")
+
+-- target("pool_tests")
+-- set_kind("binary")
+-- set_group("tests")
+-- add_deps("core_static")
+-- add_files(unity_sources)
+-- add_includedirs("deps/Unity/src", {public = true})
+-- add_includedirs("deps/Unity/extras/fixture/src", {public = true})
+-- add_includedirs("deps/Unity/extras/memory/src", {public = true})
+-- add_files("tests/pool_tests.c")
+-- add_files("tests/pool_test_runner.c")