summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromnisci3nce <omniscient.oce@gmail.com>2024-07-12 12:47:07 +1000
committeromnisci3nce <omniscient.oce@gmail.com>2024-07-12 12:47:07 +1000
commitf74cf52946f4e569a26bc81105537b40be95c2c7 (patch)
tree1d000367350d0e28eb7cfbc800286a0ed30a4e6c
parentfedba7ff68924ff50022405fc9103a5acf7013fe (diff)
wip: big makeover
-rw-r--r--examples/game_demo/game_demo.c70
-rw-r--r--src/animation.c56
-rw-r--r--src/animation.h106
-rw-r--r--src/core/camera.c11
-rw-r--r--src/core/camera.h12
-rw-r--r--src/core/core.c56
-rw-r--r--src/core/core.h19
-rw-r--r--src/defines.h18
-rw-r--r--src/maths/geometry.h42
-rw-r--r--src/maths/maths.h160
-rw-r--r--src/maths/maths_types.h3
-rw-r--r--src/maths/primitives.c71
-rw-r--r--src/maths/primitives.h10
-rw-r--r--src/new_render/pbr.h2
-rw-r--r--src/new_render/render.c41
-rw-r--r--src/new_render/render.h40
-rw-r--r--src/new_render/render_types.h21
-rw-r--r--src/new_render/shadows.h4
-rw-r--r--src/new_render/skybox.h26
-rw-r--r--src/ral/backends/opengl/backend_opengl.h76
-rw-r--r--src/ral/ral_common.c18
-rw-r--r--src/ral/ral_common.h53
-rw-r--r--src/ral/ral_impl.h40
-rw-r--r--src/ral/ral_types.h247
-rw-r--r--src/render/ral_types.h153
-rw-r--r--src/render/render.h10
-rw-r--r--src/resources/gltf.c146
-rw-r--r--src/resources/loaders.h10
-rw-r--r--src/resources/obj.c14
-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.h36
-rw-r--r--src/systems/input.c12
-rw-r--r--src/systems/input.h6
-rw-r--r--src/systems/terrain.c15
-rw-r--r--src/systems/terrain.h8
-rw-r--r--src/systems/text.h82
-rw-r--r--src/transform_hierarchy.c15
-rw-r--r--src/transform_hierarchy.h27
-rw-r--r--xmake.lua185
42 files changed, 1130 insertions, 943 deletions
diff --git a/examples/game_demo/game_demo.c b/examples/game_demo/game_demo.c
new file mode 100644
index 0000000..5e76ced
--- /dev/null
+++ b/examples/game_demo/game_demo.c
@@ -0,0 +1,70 @@
+// 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 };
+ while (!ShouldExit()) {
+ Frame_Begin();
+
+ // BEGIN Draw calls
+
+ // draw the player model with shadows
+
+ Render_DrawTerrain();
+ Skybox_Draw(&skybox);
+
+ // END Draw calls
+ Frame_Draw();
+ Frame_End();
+ }
+
+ Core_Shutdown();
+ return 0;
+}
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/core/camera.c b/src/core/camera.c
index 50c4054..428a50d 100644
--- a/src/core/camera.c
+++ b/src/core/camera.c
@@ -2,16 +2,15 @@
#include "maths.h"
-Camera Camera_Create(vec3 pos, vec3 front, vec3 up, f32 fov) {
+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);
+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;
}
diff --git a/src/core/camera.h b/src/core/camera.h
index 233f5f3..bacbca9 100644
--- a/src/core/camera.h
+++ b/src/core/camera.h
@@ -8,14 +8,14 @@
#include "maths_types.h"
typedef struct Camera {
- vec3 position;
- vec3 front;
- vec3 up;
+ Vec3 position;
+ Vec3 front;
+ Vec3 up;
f32 fov;
} Camera;
/** @brief create a camera */
-Camera Camera_Create(vec3 pos, vec3 front, vec3 up, f32 fov);
+Camera Camera_Create(Vec3 pos, Vec3 front, Vec3 up, f32 fov);
/**
* @brief Get 3D camera transform matrix
@@ -23,10 +23,10 @@ Camera Camera_Create(vec3 pos, vec3 front, vec3 up, f32 fov);
* @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);
+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
+PUB Mat4 Camera_View2D(Camera* c); // TODO: 2D cameras
// TODO: Basic reusable camera controls
diff --git a/src/core/core.c b/src/core/core.c
index a022366..602d35c 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -11,37 +11,35 @@
#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;
- Renderer renderer;
- input_state input;
- model_pool models;
+ GLFWwindow* window;
+ Renderer* renderer;
+ Input_State input;
};
/** @brief Gets the global `Core` singleton */
inline Core* GetCore() { return &g_core; }
-void core_bringup() {
+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 } };
-
- g_core.renderer.backend_context = NULL;
+ .scr_width = SCR_WIDTH,
+ .scr_height = SCR_HEIGHT,
+ .clear_colour = (Vec3){ .08, .08, .1 } };
// initialise all subsystems
- if (!Renderer_Init(conf, &g_core.renderer)) {
+ 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.renderer.window)) {
+ if (!Input_Init(&g_core.input, g_core.window)) {
// the input system needs the glfw window which is created by the renderer
// hence the order here is important
ERROR_EXIT("Failed to start input system\n");
@@ -50,34 +48,28 @@ void core_bringup() {
size_t model_data_max = 1024 * 1024 * 1024;
arena model_arena = arena_create(malloc(model_data_max), model_data_max);
- model_pool model_pool = model_pool_create(&model_arena, 256, sizeof(model));
- g_core.models = model_pool;
- INFO("Created model pool allocator");
+ // 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);
+ // 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);
+void Core_Shutdown() {
+ Input_Shutdown(&g_core.input);
+ Renderer_Shutdown(g_core.renderer);
}
-bool should_exit() {
- return key_just_released(KEYCODE_ESCAPE) || glfwWindowShouldClose(g_core.renderer.window);
+bool ShouldExit() {
+ return key_just_released(KEYCODE_ESCAPE) || glfwWindowShouldClose(g_core.window);
}
-void frame_begin() {
+void Frame_Begin() {
glfwPollEvents();
- render_frame_begin(&g_core.renderer);
+ Render_FrameBegin(g_core.renderer);
}
-void frame_draw() {}
-void frame_end() { render_frame_end(&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
index 469f8d1..7916143 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -9,18 +9,13 @@
typedef struct Core Core;
-
-core* get_global_core();
-
-// --- Lifecycle
+Core* get_global_core();
/** @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_Bringup();
+void Core_Shutdown();
+bool ShouldExit();
-void core_input_update();
+void Frame_Begin();
+void Frame_Draw();
+void Frame_End();
diff --git a/src/defines.h b/src/defines.h
index e0a7782..1f0eae7 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -53,21 +53,6 @@ CORE_DEFINE_HANDLE(Handle); // Untyped handle that can be casted to a strongly t
#define PUB // For collecting public APIs to expose in an amalgamation header file
-/*
-Possible platform defines:
-#define CEL_PLATFORM_LINUX 1
-#define CEL_PLATFORM_WINDOWS 1
-#define CEL_PLATFORM_MAC 1
-#define CEL_PLATFORM_HEADLESS 1
-*/
-
-/*
-Renderer backend defines:
-#define CEL_REND_BACKEND_OPENGL 1
-#define CEL_REND_BACKEND_VULKAN 1
-#define CEL_REND_BACKEND_METAL 1
-*/
-
// NOTE: The below is now handled in xmake.lua
// Platform will inform renderer backend (unless user overrides)
#if defined(CEL_PLATFORM_LINUX)
@@ -76,8 +61,9 @@ 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)
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 5bfc43c..f256a9b 100644
--- a/src/maths/maths_types.h
+++ b/src/maths/maths_types.h
@@ -40,10 +40,9 @@ typedef struct Vec4 {
typedef Vec4 Quat;
/** @brief 4x4 Matrix */
-typedef union Mat4 {
+typedef struct Mat4 {
// TODO: use this format for more readable code: vec4 x_axis, y_axis, z_axis, w_axis;
f32 data[16];
- Vec4 cols[4];
} Mat4;
/** @brief Three dimensional bounding box */
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/pbr.h b/src/new_render/pbr.h
index dd29301..7573563 100644
--- a/src/new_render/pbr.h
+++ b/src/new_render/pbr.h
@@ -44,6 +44,8 @@ typedef struct PBR_Textures {
// --- Internal
+typedef struct MaterialMap MaterialMap;
+typedef struct RenderEnt RenderEnt;
GPU_Renderpass* PBR_RPassCreate();
GPU_Pipeline* PBR_PipelineCreate(GPU_Renderpass* rpass);
diff --git a/src/new_render/render.c b/src/new_render/render.c
index 455b730..f5547d5 100644
--- a/src/new_render/render.c
+++ b/src/new_render/render.c
@@ -4,34 +4,31 @@
#include "render.h"
#include "maths_types.h"
-#include "shadow.h"
-
-struct RendererConfig {
- char window_name[256];
- u32 scr_width, scr_height;
- Vec3 clear_colour;
-};
+#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;
- ResourcePools* resource_pools;
+ 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
+ // set the RAL backend up
- // create our renderpasses
- Shadow_Init(&renderer->shadows);
+ // create our renderpasses
+ Shadow_Init(renderer->shadows);
- return true;
+ return true;
}
diff --git a/src/new_render/render.h b/src/new_render/render.h
index 93b2366..7c6a4a5 100644
--- a/src/new_render/render.h
+++ b/src/new_render/render.h
@@ -4,9 +4,47 @@
#pragma once
#include "defines.h"
+#include "maths_types.h"
+#include "ral_types.h"
+#include "render_types.h"
typedef struct Renderer Renderer;
-typedef struct RendererConfig RendererConfig;
+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);
+PUB void Render_FrameDraw(Renderer* renderer);
+
+// --- 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_types.h b/src/new_render/render_types.h
index 63c472e..384a18f 100644
--- a/src/new_render/render_types.h
+++ b/src/new_render/render_types.h
@@ -7,6 +7,11 @@
#include "defines.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;
@@ -27,6 +32,11 @@ typedef struct Mesh {
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,
@@ -46,6 +56,8 @@ typedef struct Model {
// materials
} Model;
+// TODO: function to create a model from a single mesh (like when using primitives)
+
// --- Lights
typedef struct PointLight {
Vec3 position;
@@ -61,3 +73,12 @@ typedef struct DirectionalLight {
Vec3 diffuse;
Vec3 specular;
} DirectionalLight;
+
+// ---
+
+// A renderable 'thing'
+typedef struct RenderEnt {
+ ModelHandle model;
+ Mat4 affine;
+ bool casts_shadows;
+} RenderEnt;
diff --git a/src/new_render/shadows.h b/src/new_render/shadows.h
index fd1c45d..82ded5c 100644
--- a/src/new_render/shadows.h
+++ b/src/new_render/shadows.h
@@ -5,11 +5,11 @@
#pragma once
#include "defines.h"
-#include "ral/ral_types.h"
+#include "ral.h"
+#include "render_types.h"
typedef struct Shadow_Storage Shadow_Storage;
-typedef struct RenderEnt RenderEnt;
typedef struct Camera Camera;
typedef struct Mat4 Mat4;
diff --git a/src/new_render/skybox.h b/src/new_render/skybox.h
index 10ec4f9..9bdc2ec 100644
--- a/src/new_render/skybox.h
+++ b/src/new_render/skybox.h
@@ -3,4 +3,30 @@
*/
#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/ral/backends/opengl/backend_opengl.h b/src/ral/backends/opengl/backend_opengl.h
index e69de29..22162f3 100644
--- a/src/ral/backends/opengl/backend_opengl.h
+++ 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/ral_common.c b/src/ral/ral_common.c
index 755b489..89d475b 100644
--- a/src/ral/ral_common.c
+++ b/src/ral/ral_common.c
@@ -1,19 +1,19 @@
#include "ral_common.h"
#include "ral_impl.h"
-void backend_pools_init(arena* a, gpu_backend_pools* backend_pools) {
- pipeline_layout_pool pipeline_layout_pool =
- pipeline_layout_pool_create(a, MAX_PIPELINES, sizeof(gpu_pipeline_layout));
+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));
+ 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));
+ 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 resource_pools* res_pools) {
- buffer_pool buf_pool = buffer_pool_create(a, MAX_BUFFERS, sizeof(gpu_buffer));
+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));
+ Texture_pool tex_pool = Texture_pool_create(a, MAX_TEXTURES, sizeof(GPU_Texture));
res_pools->textures = tex_pool;
-} \ No newline at end of file
+}
diff --git a/src/ral/ral_common.h b/src/ral/ral_common.h
index fabf264..1088404 100644
--- a/src/ral/ral_common.h
+++ b/src/ral/ral_common.h
@@ -1,46 +1,39 @@
#pragma once
#include "defines.h"
+#include "buf.h"
#include "mem.h"
#include "ral_types.h"
#include "ral_impl.h"
-CORE_DEFINE_HANDLE(BufferHandle);
-CORE_DEFINE_HANDLE(TextureHandle);
-CORE_DEFINE_HANDLE(SamplerHandle);
-CORE_DEFINE_HANDLE(ShaderHandle);
-
-CORE_DEFINE_HANDLE(pipeline_layout_handle);
-CORE_DEFINE_HANDLE(pipeline_handle);
-CORE_DEFINE_HANDLE(renderpass_handle);
-
-#define MAX_SHADER_DATA_LAYOUTS 8
-#define MAX_BUFFERS 256
-#define MAX_TEXTURES 256
-#define MAX_PIPELINES 128
-#define MAX_RENDERPASSES 128
TYPED_POOL(GPU_Buffer, Buffer);
-TYPED_POOL(gpu_texture, texture);
-TYPED_POOL(gpu_pipeline_layout, pipeline_layout);
-TYPED_POOL(gpu_pipeline, pipeline);
-TYPED_POOL(gpu_renderpass, renderpass);
+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_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;
+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 resource_pools* res_pools);
+void resource_pools_init(arena* a, struct ResourcePools* res_pools);
+
+
+// --- Vertex formats
+bytebuffer vertices_as_bytebuffer(arena* a, VertexFormat format, Vertex_darray* vertices);
-// vertex_description static_3d_vertex_description();
+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
index 8edf211..4d1c17a 100644
--- a/src/ral/ral_impl.h
+++ b/src/ral/ral_impl.h
@@ -1,22 +1,38 @@
+/**
+ * @brief
+*/
#pragma once
#include "defines.h"
#include "ral_types.h"
struct GLFWwindow;
-bool gpu_backend_init(const char* window_name, struct GLFWwindow* window);
-void gpu_backend_shutdown();
+// 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_device_create(gpu_device* out_device);
-void gpu_device_destroy(gpu_device* device);
+bool GPU_Backend_Init(const char* window_name, struct GLFWwindow* window);
+void GPU_Backend_Shutdown();
-gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description);
-void gpu_pipeline_destroy(gpu_pipeline* pipeline);
+bool GPU_Device_Create(GPU_Device* out_device);
+void GPU_Device_Destroy(GPU_Device* device);
-// --- Renderpass
-gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description);
-void gpu_renderpass_destroy(gpu_renderpass* pass);
+bool GPU_Swapchain_Create(GPU_Swapchain* out_swapchain);
+void GPU_Swapchain_Destroy(GPU_Swapchain* swapchain);
-// --- Swapchain
-bool gpu_swapchain_create(gpu_swapchain* out_swapchain);
-void gpu_swapchain_destroy(gpu_swapchain* swapchain); \ No newline at end of file
+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
index 5987fbf..0ba7f87 100644
--- a/src/ral/ral_types.h
+++ b/src/ral/ral_types.h
@@ -1,45 +1,124 @@
#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
-// Forward declare structs - these must be defined in the backend implementation
-typedef struct gpu_swapchain gpu_swapchain;
-typedef struct gpu_device gpu_device;
-typedef struct gpu_pipeline_layout gpu_pipeline_layout;
-typedef struct gpu_pipeline gpu_pipeline;
-typedef struct gpu_renderpass gpu_renderpass;
-typedef struct gpu_cmd_encoder gpu_cmd_encoder; // Recording
-typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission
-typedef struct gpu_buffer gpu_buffer;
-typedef struct gpu_texture gpu_texture;
-
-typedef struct GPU_Renderpass GPU_Renderpass;
-typedef struct GPU_Pipeline GPU_Pipeline;
-
-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
-} gpu_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;
-
-// Vertex attributes
/// @strip_prefix(ATTR_)
-typedef enum vertex_attrib_type {
+typedef enum VertexAttribType {
ATTR_F32,
ATTR_F32x2,
ATTR_F32x3,
@@ -52,35 +131,93 @@ typedef enum vertex_attrib_type {
ATTR_I32x2,
ATTR_I32x3,
ATTR_I32x4,
-} vertex_attrib_type;
+} 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 vertex_description {} vertex_description;
-typedef struct shader_desc {} shader_desc;
+typedef struct ShaderDataLayout {
+ ShaderBinding* bindings;
+ size_t binding_count;
+} ShaderDataLayout;
-typedef struct graphics_pipeline_desc {
+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;
- vertex_description vertex_desc;
- shader_desc vs; /** @brief Vertex shader stage */
- shader_desc fs; /** @brief Fragment shader stage */
+ 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
- shader_data data_layouts[MAX_SHADER_DATA_LAYOUTS];
+ ShaderData data_layouts[MAX_SHADER_DATA_LAYOUTS];
u32 data_layouts_count;
- // gpu_pipeline_layout* layout;
- gpu_renderpass* renderpass;
-
bool wireframe;
bool depth_test;
-} graphics_pipeline_desc;
+} GraphicsPipelineDesc;
-typedef struct gpu_renderpass_desc {
+typedef struct GPU_RenderpassDesc {
bool default_framebuffer;
bool has_color_target;
- texture_handle color_target; // for now only support one
+ TextureHandle color_target; // for now only support one
bool has_depth_stencil;
- texture_handle depth_stencil;
-} gpu_renderpass_desc;
+ TextureHandle depth_stencil;
+} GPU_RenderpassDesc;
diff --git a/src/render/ral_types.h b/src/render/ral_types.h
index 5f21846..be95902 100644
--- a/src/render/ral_types.h
+++ b/src/render/ral_types.h
@@ -26,139 +26,6 @@ CORE_DEFINE_HANDLE(pipeline_handle);
CORE_DEFINE_HANDLE(renderpass_handle);
#define ABSENT_MODEL_HANDLE 999999999
-// 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
@@ -218,32 +85,12 @@ typedef struct shader_binding {
} 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
diff --git a/src/render/render.h b/src/render/render.h
index 19a8d1a..f0e9a64 100644
--- a/src/render/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/resources/gltf.c b/src/resources/gltf.c
index c51e30d..5947bad 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);
+ 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;
}
@@ -86,30 +86,30 @@ typedef struct model {
} 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 };
- cgltf_data *data = NULL;
- cgltf_result result = cgltf_parse_file(&options, filepath, &data);
- if (result != cgltf_result_success) {
- WARN("gltf load failed");
- // TODO: cleanup arrays(allocate all from arena ?)
- return false;
- }
-
- cgltf_load_buffers(&options, data, filepath);
- DEBUG("loaded buffers");
+ 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_load_buffers(&options, data, filepath);
+ // DEBUG("loaded buffers");
// // --- Skin
// size_t num_skins = data->skins_count;
@@ -204,7 +204,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
// DEBUG("Number of this primitive %d", primitive.)
for (cgltf_size a = 0; a < data->meshes[m].primitives[0].attributes_count; a++) {
- cgltf_attribute attribute = data->meshes[m].primitives[0].attributes[a];
+ // cgltf_attribute attribute = data->meshes[m].primitives[0].attributes[a];
if (attribute.type == cgltf_attribute_type_position) {
TRACE("Load positions from accessor");
@@ -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) {
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..bf2f353 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,
+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 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) {
+model_handle 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);
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.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 1ef7940..11c40ea 100644
--- a/src/systems/input.h
+++ b/src/systems/input.h
@@ -36,7 +36,7 @@ bool key_just_released(keycode key);
// --- Lifecycle
-bool Input_Init(Input_state *input, struct GLFWwindow *window);
-void Input_Shutdown(Input_state *input);
+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
+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 a8e8b48..1d23cc3 100644
--- a/src/systems/terrain.c
+++ b/src/systems/terrain.c
@@ -1,30 +1,19 @@
/**
- * @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"
struct Terrain_Storage {
arena terrain_allocator;
- heightmap* heightmap; // NULL = no heightmap
+ Heightmap* heightmap; // NULL = no heightmap
GPU_Renderpass* hmap_renderpass;
GPU_Pipeline* hmap_pipeline;
};
-PUB bool Terrain_Init(Terrain_Storage* storage) {
-
- return true;
-}
+PUB bool Terrain_Init(Terrain_Storage* storage) { return true; }
PUB void Terrain_Shutdown(Terrain_Storage* storage);
-
/* bool terrain_system_init(terrain_state* state) { */
/* gpu_renderpass_desc rpass_desc = { */
/* .default_framebuffer = true, */
diff --git a/src/systems/terrain.h b/src/systems/terrain.h
index a65ecec..890cb90 100644
--- a/src/systems/terrain.h
+++ b/src/systems/terrain.h
@@ -19,7 +19,7 @@ Future:
#include "str.h"
typedef struct Heightmap {
- str8 filepath;
+ Str8 filepath;
u32x2 size;
void* image_data;
bool is_uploaded;
@@ -32,9 +32,13 @@ 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
-PUB Heightmap Heightmap_FromImage(str8 filepath);
+/** @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 */);
+PUB bool Terrain_IsActive(); // checks whether we have a loaded heightmap and it's being rendered
+
// --- Internal
// TODO: void terrain_system_render_hmap(renderer* rend, terrain_state* state);
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..b08e545 100644
--- a/src/transform_hierarchy.c
+++ b/src/transform_hierarchy.c
@@ -11,6 +11,7 @@
#include "log.h"
#include "maths.h"
#include "maths_types.h"
+#include "render_types.h"
struct transform_hierarchy {
transform_node root;
@@ -49,8 +50,8 @@ void transform_hierarchy_free(transform_hierarchy* 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) {
+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;
@@ -131,10 +132,10 @@ bool update_matrix(transform_node* node, void* _ctx_data) {
if (node->tf.is_dirty) {
// invalidates children
- mat4 updated_local_transform = transform_to_mat(&node->tf);
+ Mat4 updated_local_transform = transform_to_mat(&node->tf);
node->local_matrix_tf = updated_local_transform;
if (node->parent) {
- mat4 updated_world_transform =
+ Mat4 updated_world_transform =
mat4_mult(node->parent->world_matrix_tf, updated_local_transform);
node->world_matrix_tf = updated_world_transform;
}
@@ -149,7 +150,7 @@ void transform_hierarchy_propagate_transforms(transform_hierarchy* tfh) {
}
struct print_ctx {
- core* core;
+ Core* core;
u32 indentation_lvl;
};
@@ -175,10 +176,10 @@ bool print_node(transform_node* node, void* ctx_data) {
return true;
}
-void transform_hierarchy_debug_print(transform_node* start_node, core* core) {
+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
+}
diff --git a/src/transform_hierarchy.h b/src/transform_hierarchy.h
index 0921c19..0a506de 100644
--- a/src/transform_hierarchy.h
+++ b/src/transform_hierarchy.h
@@ -10,25 +10,26 @@
#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();
+TransformHierarchy* TransformHierarchy_Create();
/**
* @brief recursively frees all the children and then finally itself
@@ -45,11 +46,11 @@ 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);
+Transform_Node* TransformHierarchy_RootNode(TransformHierarchy* tfh);
// --- Mutations
-transform_node* transform_hierarchy_add_node(transform_node* parent, model_handle model,
- transform tf);
+Transform_Node* TransformHierarchy_AddNode(transform_node* parent, ModelHandle model,
+ Transform tf);
void transform_hierarchy_delete_node(transform_node* node);
// --- Traversal
@@ -73,5 +74,5 @@ 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
+struct Core;
+void transform_hierarchy_debug_print(transform_node* start_node, struct Core* core);
diff --git a/xmake.lua b/xmake.lua
index 8cbb910..009b9fd 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,6 +56,7 @@ 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",
@@ -79,91 +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/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
+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")
@@ -286,6 +288,13 @@ target("core_shared")
-- add_files("examples/demo/demo.c")
-- set_rundir("$(projectdir)")
+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")