summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromnisci3nce <omniscient.oce@gmail.com>2024-04-27 18:15:56 +1000
committeromnisci3nce <omniscient.oce@gmail.com>2024-04-27 18:15:56 +1000
commit69b1487e3e063cbecba96706c550d417b2f24e37 (patch)
tree9e31e292ef1cbb6775c52d14bae1f536a1f51906
parent93c8d40b39fe55a626e66d412450fb4cca1f993b (diff)
getting us compiling on windows
-rw-r--r--examples/main_loop/ex_main_loop.c3
-rw-r--r--src/core.c8
-rw-r--r--src/core.h4
-rw-r--r--src/platform/path.c6
-rw-r--r--src/renderer/archive/render.c413
-rw-r--r--src/renderer/archive/render.h46
-rw-r--r--src/renderer/archive/render_backend.h (renamed from src/renderer/render_backend.h)0
-rw-r--r--src/renderer/archive/render_types.h210
-rw-r--r--src/renderer/backends/backend_dx11.c4
-rw-r--r--src/renderer/backends/backend_dx11.h27
-rw-r--r--src/renderer/cleanroom/types.h130
-rw-r--r--src/renderer/ral.h (renamed from src/renderer/cleanroom/ral.h)5
-rw-r--r--src/renderer/ral_types.h93
-rw-r--r--src/renderer/render.c395
-rw-r--r--src/renderer/render.h41
-rw-r--r--src/renderer/render_types.h277
-rw-r--r--src/resources/gltf.c810
-rw-r--r--src/resources/obj.c595
-rw-r--r--xmake.lua139
19 files changed, 1717 insertions, 1489 deletions
diff --git a/examples/main_loop/ex_main_loop.c b/examples/main_loop/ex_main_loop.c
index 8819f7c..4e1f6a9 100644
--- a/examples/main_loop/ex_main_loop.c
+++ b/examples/main_loop/ex_main_loop.c
@@ -4,7 +4,6 @@
#include "core.h"
#include "maths.h"
#include "render.h"
-#include "render_backend.h"
int main() {
core* core = core_bringup();
@@ -14,7 +13,7 @@ int main() {
// Main loop
while (!glfwWindowShouldClose(core->renderer.window)) {
input_update(&core->input);
- threadpool_process_results(&core->threadpool, 1);
+ // threadpool_process_results(&core->threadpool, 1);
render_frame_begin(&core->renderer);
diff --git a/src/core.c b/src/core.c
index 0db8962..714505f 100644
--- a/src/core.c
+++ b/src/core.c
@@ -8,7 +8,7 @@
#include "log.h"
#include "render.h"
#include "render_types.h"
-#include "threadpool.h"
+// #include "threadpool.h"
#define SCR_WIDTH 1000
#define SCR_HEIGHT 1000
@@ -21,10 +21,10 @@ core* core_bringup() {
.scr_height = SCR_HEIGHT,
.clear_colour = (vec3){ .08, .08, .1 } };
c->renderer.config = conf;
- c->renderer.backend_state = NULL;
+ c->renderer.backend_context = NULL;
- threadpool_create(&c->threadpool, 6, 256);
- threadpool_set_ctx(&c->threadpool, c); // Gives the threadpool access to the core
+ // threadpool_create(&c->threadpool, 6, 256);
+ // threadpool_set_ctx(&c->threadpool, c); // Gives the threadpool access to the core
// initialise all subsystems
if (!renderer_init(&c->renderer)) {
diff --git a/src/core.h b/src/core.h
index be88c53..a122448 100644
--- a/src/core.h
+++ b/src/core.h
@@ -6,13 +6,13 @@
#include "screenspace.h"
#include "terrain.h"
#include "text.h"
-#include "threadpool.h"
+// #include "threadpool.h"
typedef struct core {
const char* app_name;
// foundations
renderer renderer;
- threadpool threadpool;
+ // threadpool threadpool;
// systems
input_state input;
text_system_state text;
diff --git a/src/platform/path.c b/src/platform/path.c
index 9572941..bee4e9c 100644
--- a/src/platform/path.c
+++ b/src/platform/path.c
@@ -1,12 +1,12 @@
#include "path.h"
-#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include "mem.h"
#include "str.h"
#if defined(CEL_PLATFORM_LINUX) || defined(CEL_PLATFORM_MAC)
+#include <libgen.h>
path_opt path_parent(arena* a, const char* path) {
// Duplicate the string because dirname doesnt like const literals
char* path_copy = arena_alloc(a, strlen(path) + 1);
@@ -17,4 +17,6 @@ path_opt path_parent(arena* a, const char* path) {
#endif
#ifdef CEL_PLATFORM_WINDOWS
// TODO: path_opt path_parent(const char* path)
-#endif \ No newline at end of file
+#endif
+
+path_opt path_parent(arena* a, const char* path) {} \ No newline at end of file
diff --git a/src/renderer/archive/render.c b/src/renderer/archive/render.c
new file mode 100644
index 0000000..b1e2a46
--- /dev/null
+++ b/src/renderer/archive/render.c
@@ -0,0 +1,413 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "animation.h"
+#include "maths_types.h"
+#include "mem.h"
+#include "transform_hierarchy.h"
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+
+#define STB_TRUETYPE_IMPLEMENTATION
+#include <stb_truetype.h>
+
+#include "render.h"
+#include "render_types.h"
+
+#include <glad/glad.h>
+#include <glfw3.h>
+
+#include "defines.h"
+#include "log.h"
+#include "maths.h"
+#include "render_backend.h"
+
+// FIXME: get rid of these and store dynamic screen realestate
+// in renderer
+#define SCR_WIDTH 1000
+#define SCR_HEIGHT 1000
+
+material DEFAULT_MATERIAL = { 0 };
+
+bool renderer_init(renderer* ren) {
+ INFO("Renderer init");
+
+ // NOTE: all platforms use GLFW at the moment but thats subject to change
+ glfwInit();
+
+#if defined(CEL_REND_BACKEND_OPENGL)
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+#elif defined(CEL_REND_BACKEND_VULKAN)
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+#endif
+
+ // glfw window creation
+ GLFWwindow* window = glfwCreateWindow(ren->config.scr_width, ren->config.scr_height,
+ ren->config.window_name, NULL, NULL);
+ if (window == NULL) {
+ ERROR("Failed to create GLFW window\n");
+ glfwTerminate();
+ return false;
+ }
+ ren->window = window;
+
+ glfwMakeContextCurrent(ren->window);
+
+ DEBUG("init graphics api backend");
+ if (!gfx_backend_init(ren)) {
+ FATAL("Couldnt load graphics api backend");
+ return false;
+ }
+
+ ren->blinn_phong =
+ shader_create_separate("assets/shaders/blinn_phong.vert", "assets/shaders/blinn_phong.frag");
+
+ ren->skinned =
+ shader_create_separate("assets/shaders/skinned.vert", "assets/shaders/blinn_phong.frag");
+
+ default_material_init();
+
+ return true;
+}
+
+void renderer_shutdown(renderer* ren) {}
+
+void render_frame_begin(renderer* ren) {
+ vec3 color = ren->config.clear_colour;
+ clear_screen(color);
+}
+void render_frame_end(renderer* ren) {
+ // present frame
+ glfwSwapBuffers(ren->window);
+ glfwPollEvents();
+}
+
+void default_material_init() {
+ INFO("Load default material")
+ DEFAULT_MATERIAL.ambient_colour = (vec3){ 0.5, 0.5, 0.5 };
+ DEFAULT_MATERIAL.diffuse = (vec3){ 0.8, 0.8, 0.8 };
+ DEFAULT_MATERIAL.specular = (vec3){ 1.0, 1.0, 1.0 };
+ DEFAULT_MATERIAL.diffuse_texture = texture_data_load("assets/textures/white1x1.png", false);
+ DEFAULT_MATERIAL.specular_texture = texture_data_load("assets/textures/black1x1.png", false);
+ DEFAULT_MATERIAL.spec_exponent = 32.0;
+ strcpy(DEFAULT_MATERIAL.name, "Default");
+ texture_data_upload(&DEFAULT_MATERIAL.diffuse_texture);
+ texture_data_upload(&DEFAULT_MATERIAL.specular_texture);
+}
+
+void model_destroy(model* model) {
+ TRACE("Freeing all data for model %s", model->name);
+ arena_free_all(&model->animation_data_arena);
+ arena_free_storage(&model->animation_data_arena);
+ mesh_darray_free(model->meshes);
+ material_darray_free(model->materials);
+ if (model->is_uploaded) {
+ // Delete gpu buffer data
+ for (u32 i = 0; i < mesh_darray_len(model->meshes); i++) {
+ // FIXME: dont leak Opengl
+ glDeleteBuffers(1, &model->meshes->data[i].vbo);
+ glDeleteVertexArrays(1, &model->meshes->data[i].vao);
+ }
+ }
+}
+
+typedef struct draw_ctx {
+ model_darray* models;
+ renderer* ren;
+ camera* cam;
+ scene* scene;
+} draw_ctx;
+bool draw_scene_node(transform_node* node, void* ctx_data) {
+ if (!node || !node->parent) return true;
+ draw_ctx* ctx = ctx_data;
+ model* m = &ctx->models->data[node->model.raw];
+ draw_model(ctx->ren, ctx->cam, m, &node->world_matrix_tf, ctx->scene);
+ return true;
+}
+
+void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera,
+ transform_hierarchy* tfh, scene* scene) {
+ draw_ctx* ctx = arena_alloc(frame, sizeof(draw_ctx));
+ ctx->models = models;
+ ctx->ren = ren;
+ ctx->cam = camera;
+ ctx->scene = scene;
+ transform_hierarchy_dfs(transform_hierarchy_root_node(tfh), draw_scene_node, true, ctx);
+}
+
+void draw_model(renderer* ren, camera* camera, model* model, mat4* model_tf, scene* scene) {
+ // TRACE("Drawing model: %s", model->name);
+ mat4 view;
+ mat4 proj;
+ camera_view_projection(camera, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
+
+ set_shader(ren->blinn_phong);
+
+ // set camera uniform
+ uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &camera->position);
+ // set light uniforms
+ dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light);
+ for (int i = 0; i < scene->n_point_lights; i++) {
+ point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i);
+ }
+
+ for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
+ mesh* m = &model->meshes->data[i];
+ if (vertex_darray_len(m->vertices) == 0) {
+ continue;
+ }
+ // TRACE("Drawing mesh %d", i);
+ material* mat = &model->materials->data[m->material_index];
+ draw_mesh(ren, m, model_tf, mat, &view, &proj);
+ }
+}
+
+void draw_mesh(renderer* ren, mesh* mesh, mat4* model_tf, material* mat, mat4* view, mat4* proj) {
+ shader lighting_shader = ren->blinn_phong;
+
+ // bind buffer
+ bind_mesh_vertex_buffer(ren->backend_state, mesh);
+
+ // bind textures
+ bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
+ bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
+ uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
+
+ // upload model, view, and projection matrices
+ uniform_mat4f(lighting_shader.program_id, "model", model_tf);
+ uniform_mat4f(lighting_shader.program_id, "view", view);
+ uniform_mat4f(lighting_shader.program_id, "projection", proj);
+
+ // draw triangles
+ u32 num_vertices = vertex_darray_len(mesh->vertices);
+ draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
+}
+
+void draw_skinned_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* view,
+ mat4* proj) {
+ shader lighting_shader = ren->skinned;
+
+ // bind buffer
+ bind_mesh_vertex_buffer(ren->backend_state, mesh);
+
+ // bind textures
+ bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
+ bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
+
+ // Uniforms
+ uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
+ mat4 trans = mat4_translation(tf.position);
+ mat4 rot = mat4_rotation(tf.rotation);
+ mat4 scale = mat4_scale(tf.scale);
+ mat4 model_tf = mat4_mult(trans, mat4_mult(rot, scale));
+ uniform_mat4f(lighting_shader.program_id, "model", &model_tf);
+ uniform_mat4f(lighting_shader.program_id, "view", view);
+ uniform_mat4f(lighting_shader.program_id, "projection", proj);
+
+ // bone transforms
+ size_t n_bones = mesh->bones->len;
+
+ // for now assume correct ordering
+ mat4* bone_transforms = malloc(n_bones * sizeof(mat4));
+ mat4 parent = mat4_ident();
+ for (int bone_i = 0; bone_i < n_bones; bone_i++) {
+ joint j = mesh->bones->data[bone_i];
+ transform tf = mesh->bones->data[bone_i].transform_components;
+ tf.position.y = -tf.position.y;
+ mat4 local = transform_to_mat(&tf);
+ mat4 inverse = j.inverse_bind_matrix;
+ inverse.data[13] = -inverse.data[13];
+ mat4 intemediate = mat4_mult(local, inverse);
+
+ bone_transforms[bone_i] = intemediate;
+ parent = bone_transforms[bone_i];
+ }
+
+ // premultiply the inverses
+ // for (int bone_i = 0; bone_i < n_bones; bone_i++) {
+ // joint j = mesh->bones->data[bone_i];
+ // // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix);
+ // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix);
+ // }
+
+ glUniformMatrix4fv(glGetUniformLocation(lighting_shader.program_id, "boneMatrices"), n_bones,
+ GL_FALSE, &bone_transforms->data[0]);
+
+ free(bone_transforms);
+
+ // draw triangles
+ u32 num_vertices = vertex_darray_len(mesh->vertices);
+ draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
+}
+
+void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene) {
+ mat4 view;
+ mat4 proj;
+ camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
+
+ set_shader(ren->skinned);
+
+ // set camera uniform
+ uniform_vec3f(ren->skinned.program_id, "viewPos", &cam->position);
+ // set light uniforms
+ dir_light_upload_uniforms(ren->skinned, &scene->dir_light);
+ for (int i = 0; i < scene->n_point_lights; i++) {
+ point_light_upload_uniforms(ren->skinned, &scene->point_lights[i], '0' + i);
+ }
+
+ for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
+ mesh* m = &model->meshes->data[i];
+ if (vertex_darray_len(m->vertices) == 0) {
+ continue;
+ }
+ // material* mat = &model->materials->data[m->material_index];
+ material* mat = &DEFAULT_MATERIAL;
+ draw_skinned_mesh(ren, m, tf, mat, &view, &proj);
+ }
+}
+
+void model_upload_meshes(renderer* ren, model* model) {
+ INFO("Upload mesh vertex data to GPU for model %s", model->name);
+
+ size_t num_meshes = mesh_darray_len(model->meshes);
+ u32 VBOs[num_meshes];
+ u32 VAOs[num_meshes];
+ glGenBuffers(num_meshes, VBOs);
+ glGenVertexArrays(num_meshes, VAOs);
+
+ u64 total_verts = 0;
+
+ TRACE("num meshes %d", num_meshes);
+
+ // upload each mesh to the GPU
+ for (int mesh_i = 0; mesh_i < num_meshes; mesh_i++) {
+ mesh mesh = model->meshes->data[mesh_i];
+ model->meshes->data[mesh_i].vao = VAOs[mesh_i];
+ model->meshes->data[mesh_i].vbo = VBOs[mesh_i];
+ // 3. bind buffers
+ glBindBuffer(GL_ARRAY_BUFFER, VBOs[mesh_i]);
+
+ size_t num_vertices = vertex_darray_len(model->meshes->data[mesh_i].vertices);
+ // TRACE("Uploading vertex array data: %d verts", num_vertices);
+ total_verts += num_vertices;
+
+ size_t static_vertex_size = 2 * sizeof(vec3) + sizeof(vec2);
+ size_t skinned_vertex_size = 2 * sizeof(vec3) + sizeof(vec2) + 4 * sizeof(u32) + sizeof(vec4);
+ size_t vertex_size = mesh.is_skinned ? skinned_vertex_size : static_vertex_size;
+
+ // TRACE("sizeof(vertex) -> %ld, vertex_size -> %ld\n", sizeof(vertex), vertex_size);
+ if (mesh.is_skinned) {
+ assert(vertex_size == (12 + 12 + 8 + 16 + 16));
+ } else {
+ assert(vertex_size == sizeof(vertex));
+ assert(vertex_size == 8 * sizeof(float));
+ }
+
+ size_t buffer_size = vertex_size * num_vertices;
+ u8* bytes = malloc(buffer_size);
+
+ for (int i = 0; i < num_vertices; i++) {
+ u8* p = bytes + vertex_size * i;
+ memcpy(p, &mesh.vertices->data[i], static_vertex_size);
+ if (mesh.is_skinned) {
+ u8* bone_data_offset = p + static_vertex_size;
+ memcpy(bone_data_offset, &mesh.vertex_bone_data->data[i], sizeof(vertex_bone_data));
+ }
+ }
+
+ // 4. upload data
+ glBufferData(GL_ARRAY_BUFFER, buffer_size, bytes, GL_STATIC_DRAW);
+
+ // 5. cont. set mesh vertex layout
+ glBindVertexArray(model->meshes->data[mesh_i].vao);
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)0);
+ glEnableVertexAttribArray(0);
+ // normal vector attribute
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+ // tex coords
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertex_size, (void*)(6 * sizeof(float)));
+ glEnableVertexAttribArray(2);
+
+ // skinning (optional)
+ if (mesh.is_skinned) {
+ glEnableVertexAttribArray(3);
+ glVertexAttribIPointer(3, 4, GL_INT, vertex_size, (void*)(8 * sizeof(float)));
+
+ glEnableVertexAttribArray(4);
+ glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, vertex_size, (void*)(12 * sizeof(float)));
+ }
+ }
+
+ INFO("Uploaded %d submeshes with a total of %d vertices\n", num_meshes, total_verts);
+
+ // 6. reset buffer
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+texture texture_data_load(const char* path, bool invert_y) {
+ TRACE("Load texture %s", path);
+
+ // load the file data
+ // texture loading
+ int width, height, num_channels;
+ stbi_set_flip_vertically_on_load(invert_y);
+
+#pragma GCC diagnostic ignored "-Wpointer-sign"
+ char* data = stbi_load(path, &width, &height, &num_channels, 0); // STBI_rgb_alpha);
+ if (data) {
+ DEBUG("loaded texture: %s", path);
+ } else {
+ WARN("failed to load texture");
+ }
+
+ unsigned int channel_type;
+ if (num_channels == 4) {
+ channel_type = GL_RGBA;
+ } else {
+ channel_type = GL_RGB;
+ }
+
+ return (texture){ .texture_id = 0,
+ .width = width,
+ .height = height,
+ .channel_count = num_channels,
+ .channel_type = channel_type,
+ .name = "TODO: Texture names",
+ .image_data = data };
+}
+
+void dir_light_upload_uniforms(shader shader, directional_light* light) {
+ uniform_vec3f(shader.program_id, "dirLight.direction", &light->direction);
+ uniform_vec3f(shader.program_id, "dirLight.ambient", &light->ambient);
+ uniform_vec3f(shader.program_id, "dirLight.diffuse", &light->diffuse);
+ uniform_vec3f(shader.program_id, "dirLight.specular", &light->specular);
+}
+
+void point_light_upload_uniforms(shader shader, point_light* light, char index) {
+ char position_str[] = "pointLights[x].position";
+ position_str[12] = (char)index;
+ char ambient_str[] = "pointLights[x].ambient";
+ ambient_str[12] = (char)index;
+ char diffuse_str[] = "pointLights[x].diffuse";
+ diffuse_str[12] = (char)index;
+ char specular_str[] = "pointLights[x].specular";
+ specular_str[12] = (char)index;
+ char constant_str[] = "pointLights[x].constant";
+ constant_str[12] = (char)index;
+ char linear_str[] = "pointLights[x].linear";
+ linear_str[12] = (char)index;
+ char quadratic_str[] = "pointLights[x].quadratic";
+ quadratic_str[12] = (char)index;
+ uniform_vec3f(shader.program_id, position_str, &light->position);
+ uniform_vec3f(shader.program_id, ambient_str, &light->ambient);
+ uniform_vec3f(shader.program_id, diffuse_str, &light->diffuse);
+ uniform_vec3f(shader.program_id, specular_str, &light->specular);
+ uniform_f32(shader.program_id, constant_str, light->constant);
+ uniform_f32(shader.program_id, linear_str, light->linear);
+ uniform_f32(shader.program_id, quadratic_str, light->quadratic);
+} \ No newline at end of file
diff --git a/src/renderer/archive/render.h b/src/renderer/archive/render.h
new file mode 100644
index 0000000..31cf3b0
--- /dev/null
+++ b/src/renderer/archive/render.h
@@ -0,0 +1,46 @@
+/**
+ * @file render.h
+ * @author your name (you@domain.com)
+ * @brief Renderer frontend
+ * @version 0.1
+ * @date 2024-03-21
+ *
+ * @copyright Copyright (c) 2024
+ *
+ */
+#pragma once
+
+#include "camera.h"
+#include "loaders.h"
+#include "render_types.h"
+#include "transform_hierarchy.h"
+
+// --- Lifecycle
+/** @brief initialise the render system frontend */
+bool renderer_init(renderer* ren);
+/** @brief shutdown the render system frontend */
+void renderer_shutdown(renderer* ren);
+
+void renderer_on_resize(renderer* ren);
+
+struct render_packet;
+
+// --- Frame
+
+void render_frame_begin(renderer* ren);
+void render_frame_end(renderer* ren);
+void render_frame_draw(renderer* ren);
+
+// --- models meshes
+void model_upload_meshes(renderer* ren, model* model);
+void draw_model(renderer* ren, camera* camera, model* model, mat4* tf, scene* scene);
+void draw_mesh(renderer* ren, mesh* mesh, mat4* tf, material* mat, mat4* view, mat4* proj);
+void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera,
+ transform_hierarchy* tfh, scene* scene);
+
+void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene);
+
+void model_destroy(model* model);
+
+// ---
+texture texture_data_load(const char* path, bool invert_y); // #frontend
diff --git a/src/renderer/render_backend.h b/src/renderer/archive/render_backend.h
index da30bcc..da30bcc 100644
--- a/src/renderer/render_backend.h
+++ b/src/renderer/archive/render_backend.h
diff --git a/src/renderer/archive/render_types.h b/src/renderer/archive/render_types.h
new file mode 100644
index 0000000..13a6651
--- /dev/null
+++ b/src/renderer/archive/render_types.h
@@ -0,0 +1,210 @@
+// /**
+// * @file render_types.h
+// * @author Omniscient
+// * @brief Type definitions for the majority of data required by the renderer system
+// * @date 2024-02-24
+// *
+// */
+// #pragma once
+
+#include "animation.h"
+#include "darray.h"
+#include "maths.h"
+#include "maths_types.h"
+#include "str.h"
+
+struct GLFWwindow;
+
+#define MAX_MATERIAL_NAME_LEN 256
+#define MAX_TEXTURE_NAME_LEN 256
+
+// #ifndef RESOURCE_HANDLE_DEFS
+// // CORE_DEFINE_HANDLE(model_handle);
+// #define ABSENT_MODEL_HANDLE 999999999
+// // CORE_DEFINE_HANDLE(texture_handle);
+// #define RESOURCE_HANDLE_DEFS
+// #endif
+
+/* @brief Opaque wrapper around a shader program */
+typedef struct shader {
+ u32 program_id;
+} shader;
+
+/** @brief configuration passed to the renderer at init time */
+typedef struct renderer_config {
+ char window_name[256];
+ u32 scr_width, scr_height;
+ vec3 clear_colour; /** colour that the screen gets cleared to every frame */
+} renderer_config;
+
+// typedef struct frame_stats {
+// u64 last_time;
+// } frame_stats;
+
+typedef struct renderer {
+ struct GLFWwindow *window; /** Currently all platforms use GLFW*/
+ void *backend_state; /** Graphics API-specific state */
+ renderer_config config;
+ // shaders
+ shader blinn_phong;
+ shader skinned;
+} renderer;
+
+// // --- Lighting & Materials
+
+typedef struct texture {
+ u32 texture_id;
+ char name[MAX_TEXTURE_NAME_LEN];
+ void *image_data;
+ void *backend_data;
+ u32 width;
+ u32 height;
+ u8 channel_count;
+ u32 channel_type;
+} texture;
+
+typedef struct blinn_phong_material {
+ char name[MAX_MATERIAL_NAME_LEN];
+ texture diffuse_texture;
+ char diffuse_tex_path[256];
+ texture specular_texture;
+ char specular_tex_path[256];
+ vec3 ambient_colour;
+ vec3 diffuse;
+ vec3 specular;
+ f32 spec_exponent;
+ bool is_loaded;
+ bool is_uploaded;
+} blinn_phong_material;
+typedef blinn_phong_material material; // when we start using PBR, this will no longer be the
+// case
+
+// // the default blinn-phong material. MUST be initialised with the function below
+// extern material DEFAULT_MATERIAL;
+// void default_material_init();
+
+#ifndef TYPED_MATERIAL_ARRAY
+KITC_DECL_TYPED_ARRAY(material) // creates "material_darray"
+#define TYPED_MATERIAL_ARRAY
+#endif
+
+#ifndef TYPED_ANIMATION_CLIP_ARRAY
+KITC_DECL_TYPED_ARRAY(animation_clip) // creates "material_darray"
+#define TYPED_ANIMATION_CLIP_ARRAY
+#endif
+
+// // lights
+// typedef struct point_light {
+// vec3 position;
+// f32 constant, linear, quadratic;
+// vec3 ambient;
+// vec3 diffuse;
+// vec3 specular;
+// } point_light;
+
+// typedef struct directional_light {
+// vec3 direction;
+// vec3 ambient;
+// vec3 diffuse;
+// vec3 specular;
+// } directional_light;
+
+// void point_light_upload_uniforms(shader shader, point_light *light, char index);
+// void dir_light_upload_uniforms(shader shader, directional_light *light);
+
+// // --- Models & Meshes
+
+// /** @brief Vertex format for a static mesh */
+typedef struct vertex {
+ vec3 position;
+ vec3 normal;
+ vec2 uv;
+} vertex;
+
+typedef struct vertex_bone_data {
+ vec4u joints; /** @brief 4 indices of joints that influence vectors position */
+ vec4 weights; /** @brief weight (0,1) of each joint */
+} vertex_bone_data;
+
+#include "animation.h"
+#ifndef TYPED_VERTEX_ARRAY
+KITC_DECL_TYPED_ARRAY(vertex) // creates "vertex_darray"
+KITC_DECL_TYPED_ARRAY(vertex_bone_data) // creates "skinned_vertex_darray"
+KITC_DECL_TYPED_ARRAY(joint)
+#define TYPED_VERTEX_ARRAY
+#endif
+
+typedef struct mesh {
+ vertex_darray *vertices;
+ vertex_bone_data_darray *vertex_bone_data; // only used if model needs it
+ joint_darray *bones;
+ bool is_skinned;
+ u32 vertex_size; /** size in bytes of each vertex including necessary padding */
+ bool has_indices;
+ u32 *indices;
+ u32 indices_len;
+ size_t material_index;
+ u32 vbo, vao; /** OpenGL data. TODO: dont leak OpenGL details */
+} mesh;
+
+// #ifndef TYPED_MESH_ARRAY
+// KITC_DECL_TYPED_ARRAY(mesh) // creates "mesh_darray"
+// #define TYPED_MESH_ARRAY
+// #endif
+
+typedef struct model {
+ str8 name;
+ mesh_darray *meshes;
+ aabb_3d bbox;
+ material_darray *materials;
+ animation_clip_darray *animations;
+ arena animation_data_arena;
+ bool is_loaded;
+ bool is_uploaded;
+} model;
+
+// #ifndef TYPED_MODEL_ARRAY
+// KITC_DECL_TYPED_ARRAY(model) // creates "model_darray"
+// #define TYPED_MODEL_ARRAY
+// #endif
+
+// // --- Scene
+
+// // NOTE: This struct won't stay like this for a long time. It's somewhat temporary
+// // in order to get a basic scene working without putting burden on the caller of
+// // draw_model()
+// typedef struct scene {
+// directional_light dir_light;
+// point_light point_lights[4];
+// size_t n_point_lights;
+// } scene;
+
+// // --- Graphics API related
+
+// // typedef enum cel_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 {
+// // TEXTURE_TYPE_2D,
+// // TEXTURE_TYPE_3D,
+// // TEXTURE_TYPE_2D_ARRAY,
+// // TEXTURE_TYPE_CUBE_MAP,
+// // TEXTURE_TYPE_COUNT
+// // } gpu_texture_type;
+
+// // typedef enum gpu_texture_format {
+// // TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
+// // TEXTURE_FORMAT_DEPTH_DEFAULT,
+// // TEXTURE_FORMAT_COUNT
+// // } gpu_texture_format;
+
+// // typedef enum pipeline_kind {
+// // GRAPHICS,
+// // COMPUTE,
+// // } pipeline_kind; \ No newline at end of file
diff --git a/src/renderer/backends/backend_dx11.c b/src/renderer/backends/backend_dx11.c
index d991f03..7e48853 100644
--- a/src/renderer/backends/backend_dx11.c
+++ b/src/renderer/backends/backend_dx11.c
@@ -1,3 +1,5 @@
-#if CEL_REND_BACKEND_DX11
+#if defined(CEL_REND_BACKEND_DX11)
+#include <d3d11.h>
+#include <d3dcompiler.h>
#endif \ No newline at end of file
diff --git a/src/renderer/backends/backend_dx11.h b/src/renderer/backends/backend_dx11.h
new file mode 100644
index 0000000..163ca97
--- /dev/null
+++ b/src/renderer/backends/backend_dx11.h
@@ -0,0 +1,27 @@
+#pragma once
+#include "ral.h"
+
+#define GPU_SWAPCHAIN_IMG_COUNT 2
+
+typedef struct gpu_swapchain {
+} gpu_swapchain;
+typedef struct gpu_device {
+ // VkPhysicalDevice physical_device;
+ // VkDevice logical_device;
+ // VkPhysicalDeviceProperties properties;
+ // VkPhysicalDeviceFeatures features;
+ // VkPhysicalDeviceMemoryProperties memory;
+ // VkCommandPool pool;
+} gpu_device;
+typedef struct gpu_pipeline {
+} gpu_pipeline;
+
+typedef struct gpu_renderpass {
+ // VkRenderPass vk_handle;
+ // VkFramebuffer framebuffers[GPU_SWAPCHAIN_IMG_COUNT];
+ // u32
+} gpu_renderpass;
+
+typedef struct gpu_cmd_encoder {
+ // VkCommandBuffer cmd_buffer;
+} gpu_cmd_encoder; \ No newline at end of file
diff --git a/src/renderer/cleanroom/types.h b/src/renderer/cleanroom/types.h
index 7a6cfbd..0a28b1c 100644
--- a/src/renderer/cleanroom/types.h
+++ b/src/renderer/cleanroom/types.h
@@ -3,22 +3,11 @@
#include "defines.h"
#include "maths_types.h"
#include "str.h"
+#include "render_types.h"
-CORE_DEFINE_HANDLE(buffer_handle);
-CORE_DEFINE_HANDLE(texture_handle);
-CORE_DEFINE_HANDLE(sampler_handle);
-CORE_DEFINE_HANDLE(shader_handle);
-CORE_DEFINE_HANDLE(model_handle);
+// typedef struct transform_hierarchy {
+// } transform_hierarchy;
-typedef struct transform_hierarchy {
-} transform_hierarchy;
-
-/** @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;
/*
- render_types.h
@@ -27,102 +16,10 @@ typedef struct texture_desc {
- render.h ?
*/
-// 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;
-
/* render_types */
typedef struct model pbr_material;
typedef struct model bp_material; // blinn-phong
-#include "maths_types.h"
-
-typedef enum vertex_format {
- VERTEX_STATIC_3D,
- VERTEX_SPRITE,
- VERTEX_SKINNED,
- VERTEX_COUNT
-} vertex_format;
-
-typedef union vertex {
- struct {
- vec3 position;
- vec4 colour;
- vec2 tex_coords;
- vec3 normal;
- } 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 */
-} vertex;
-
-KITC_DECL_TYPED_ARRAY(vertex)
-KITC_DECL_TYPED_ARRAY(u32)
-
-typedef struct geometry_data {
- vertex_format format;
- vertex_darray vertices;
- bool has_indices;
- u32_darray indices;
- vec3 colour; /** Optional: set vertex colours */
-} geometry_data;
-
-void geo_set_vertex_colours(geometry_data* geo, vec4 colour);
-
-typedef struct mesh {
- buffer_handle vertex_buffer;
- buffer_handle index_buffer;
- u32 index_count;
- bool has_indices;
- geometry_data* vertices; // NULL means it has been freed
-} mesh;
-
-/* Hot reloading:
-C side - reload_model():
- - load model from disk using existing loader
- - remove from transform graph so it isnt tried to be drawn
- -
-
-*/
-
-// TODO: move to some sort of render layer (not inside the abstraction layer)
-typedef struct model {
- str8 debug_name;
- mesh* meshes;
- u32 mesh_count;
-} model;
// ? How to tie together materials and shaders
@@ -149,27 +46,6 @@ typedef struct model {
/* --- Renderer layer */
/* render.h */
-typedef struct renderer {
- void* backend_context;
-} renderer;
-
-bool renderer_init(renderer* ren);
-void renderer_shutdown(renderer* ren);
-
-// frontend -- these can be called from say a loop in an example, or via FFI
-texture_handle texture_create(const char* debug_name, texture_desc description, const u8* data);
-
-// Frontend Resources
-void texture_data_upload(texture_handle texture);
-buffer_handle buffer_create(const char* debug_name, u64 size);
-bool buffer_destroy(buffer_handle buffer);
-sampler_handle sampler_create();
-
-void shader_hot_reload(const char* filepath);
-
-// models and meshes are implemented **in terms of the above**
-mesh mesh_create(geometry_data* geometry);
-model_handle model_load(const char* debug_name, const char* filepath);
// Drawing
diff --git a/src/renderer/cleanroom/ral.h b/src/renderer/ral.h
index 15eb027..fd83e76 100644
--- a/src/renderer/cleanroom/ral.h
+++ b/src/renderer/ral.h
@@ -11,8 +11,9 @@
*/
#pragma once
-#include "cleanroom/types.h"
+#include "ral_types.h"
#include "defines.h"
+#include "str.h"
// Forward declare structs
typedef struct gpu_swapchain gpu_swapchain;
@@ -25,7 +26,7 @@ typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission
enum pipeline_kind {
GRAPHICS,
COMPUTE,
-} pipeline_kind;
+};
typedef struct shader_desc {
const char* debug_name;
diff --git a/src/renderer/ral_types.h b/src/renderer/ral_types.h
new file mode 100644
index 0000000..9b1ef62
--- /dev/null
+++ b/src/renderer/ral_types.h
@@ -0,0 +1,93 @@
+/**
+ * @file ral_types.h
+ * @author your name (you@domain.com)
+ * @brief
+ * @version 0.1
+ * @date 2024-04-27
+ *
+ * @copyright Copyright (c) 2024
+ *
+ */
+#pragma once
+
+#include "defines.h"
+#include "maths_types.h"
+#include "darray.h"
+
+#ifndef RENDERER_TYPED_HANDLES
+CORE_DEFINE_HANDLE(buffer_handle);
+CORE_DEFINE_HANDLE(texture_handle);
+CORE_DEFINE_HANDLE(sampler_handle);
+CORE_DEFINE_HANDLE(shader_handle);
+CORE_DEFINE_HANDLE(model_handle);
+#define ABSENT_MODEL_HANDLE 999999999
+#define RENDERER_TYPED_HANDLES
+#endif
+
+// gpu types
+typedef enum gpu_primitive_topology {
+ CEL_PRIMITIVE_TOPOLOGY_POINT,
+ CEL_PRIMITIVE_TOPOLOGY_LINE,
+ CEL_PRIMITIVE_TOPOLOGY_LINE_STRIP,
+ CEL_PRIMITIVE_TOPOLOGY_TRIANGLE,
+ CEL_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+ CEL_PRIMITIVE_TOPOLOGY_COUNT
+} cel_primitive_topology;
+
+typedef enum gpu_texture_type {
+ CEL_TEXTURE_TYPE_2D,
+ CEL_TEXTURE_TYPE_3D,
+ CEL_TEXTURE_TYPE_2D_ARRAY,
+ CEL_TEXTURE_TYPE_CUBE_MAP,
+ CEL_TEXTURE_TYPE_COUNT
+} gpu_texture_type;
+
+typedef enum gpu_texture_format {
+ CEL_TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
+ CEL_TEXTURE_FORMAT_DEPTH_DEFAULT,
+ CEL_TEXTURE_FORMAT_COUNT
+} gpu_texture_format;
+
+/** @brief Texture Description - used by texture creation functions */
+typedef struct texture_desc {
+ // gpu_texture_type tex_type;
+ // gpu_texture_format format;
+ // u32x2 extents;
+} texture_desc;
+
+typedef enum vertex_format {
+ VERTEX_STATIC_3D,
+ VERTEX_SPRITE,
+ VERTEX_SKINNED,
+ VERTEX_COUNT
+} vertex_format;
+
+typedef union vertex {
+ struct {
+ vec3 position;
+ vec4 colour;
+ vec2 tex_coords;
+ vec3 normal;
+ } 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 */
+} vertex;
+
+#ifndef TYPED_VERTEX_ARRAY
+KITC_DECL_TYPED_ARRAY(vertex)
+KITC_DECL_TYPED_ARRAY(u32)
+#define TYPED_VERTEX_ARRAY
+#endif \ No newline at end of file
diff --git a/src/renderer/render.c b/src/renderer/render.c
index b1e2a46..8cd7421 100644
--- a/src/renderer/render.c
+++ b/src/renderer/render.c
@@ -1,36 +1,9 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "animation.h"
-#include "maths_types.h"
-#include "mem.h"
-#include "transform_hierarchy.h"
-#define STB_IMAGE_IMPLEMENTATION
-#include <stb_image.h>
-
-#define STB_TRUETYPE_IMPLEMENTATION
-#include <stb_truetype.h>
-
-#include "render.h"
-#include "render_types.h"
-
-#include <glad/glad.h>
#include <glfw3.h>
-
-#include "defines.h"
-#include "log.h"
-#include "maths.h"
-#include "render_backend.h"
-
-// FIXME: get rid of these and store dynamic screen realestate
-// in renderer
-#define SCR_WIDTH 1000
-#define SCR_HEIGHT 1000
-
-material DEFAULT_MATERIAL = { 0 };
+#include "render.h"
+#include "camera.h"
bool renderer_init(renderer* ren) {
- INFO("Renderer init");
+ // INFO("Renderer init");
// NOTE: all platforms use GLFW at the moment but thats subject to change
glfwInit();
@@ -48,7 +21,7 @@ bool renderer_init(renderer* ren) {
GLFWwindow* window = glfwCreateWindow(ren->config.scr_width, ren->config.scr_height,
ren->config.window_name, NULL, NULL);
if (window == NULL) {
- ERROR("Failed to create GLFW window\n");
+ // ERROR("Failed to create GLFW window\n");
glfwTerminate();
return false;
}
@@ -56,358 +29,26 @@ bool renderer_init(renderer* ren) {
glfwMakeContextCurrent(ren->window);
- DEBUG("init graphics api backend");
- if (!gfx_backend_init(ren)) {
- FATAL("Couldnt load graphics api backend");
- return false;
- }
+ // DEBUG("init graphics api backend");
+ // if (!gfx_backend_init(ren)) {
+ // FATAL("Couldnt load graphics api backend");
+ // return false;
+ // }
- ren->blinn_phong =
- shader_create_separate("assets/shaders/blinn_phong.vert", "assets/shaders/blinn_phong.frag");
+ // ren->blinn_phong =
+ // shader_create_separate("assets/shaders/blinn_phong.vert", "assets/shaders/blinn_phong.frag");
- ren->skinned =
- shader_create_separate("assets/shaders/skinned.vert", "assets/shaders/blinn_phong.frag");
+ // ren->skinned =
+ // shader_create_separate("assets/shaders/skinned.vert", "assets/shaders/blinn_phong.frag");
- default_material_init();
+ // default_material_init();
return true;
}
-
void renderer_shutdown(renderer* ren) {}
-void render_frame_begin(renderer* ren) {
- vec3 color = ren->config.clear_colour;
- clear_screen(color);
-}
-void render_frame_end(renderer* ren) {
- // present frame
- glfwSwapBuffers(ren->window);
- glfwPollEvents();
-}
-
-void default_material_init() {
- INFO("Load default material")
- DEFAULT_MATERIAL.ambient_colour = (vec3){ 0.5, 0.5, 0.5 };
- DEFAULT_MATERIAL.diffuse = (vec3){ 0.8, 0.8, 0.8 };
- DEFAULT_MATERIAL.specular = (vec3){ 1.0, 1.0, 1.0 };
- DEFAULT_MATERIAL.diffuse_texture = texture_data_load("assets/textures/white1x1.png", false);
- DEFAULT_MATERIAL.specular_texture = texture_data_load("assets/textures/black1x1.png", false);
- DEFAULT_MATERIAL.spec_exponent = 32.0;
- strcpy(DEFAULT_MATERIAL.name, "Default");
- texture_data_upload(&DEFAULT_MATERIAL.diffuse_texture);
- texture_data_upload(&DEFAULT_MATERIAL.specular_texture);
-}
-
-void model_destroy(model* model) {
- TRACE("Freeing all data for model %s", model->name);
- arena_free_all(&model->animation_data_arena);
- arena_free_storage(&model->animation_data_arena);
- mesh_darray_free(model->meshes);
- material_darray_free(model->materials);
- if (model->is_uploaded) {
- // Delete gpu buffer data
- for (u32 i = 0; i < mesh_darray_len(model->meshes); i++) {
- // FIXME: dont leak Opengl
- glDeleteBuffers(1, &model->meshes->data[i].vbo);
- glDeleteVertexArrays(1, &model->meshes->data[i].vao);
- }
- }
-}
-
-typedef struct draw_ctx {
- model_darray* models;
- renderer* ren;
- camera* cam;
- scene* scene;
-} draw_ctx;
-bool draw_scene_node(transform_node* node, void* ctx_data) {
- if (!node || !node->parent) return true;
- draw_ctx* ctx = ctx_data;
- model* m = &ctx->models->data[node->model.raw];
- draw_model(ctx->ren, ctx->cam, m, &node->world_matrix_tf, ctx->scene);
- return true;
-}
-
-void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera,
- transform_hierarchy* tfh, scene* scene) {
- draw_ctx* ctx = arena_alloc(frame, sizeof(draw_ctx));
- ctx->models = models;
- ctx->ren = ren;
- ctx->cam = camera;
- ctx->scene = scene;
- transform_hierarchy_dfs(transform_hierarchy_root_node(tfh), draw_scene_node, true, ctx);
-}
-
-void draw_model(renderer* ren, camera* camera, model* model, mat4* model_tf, scene* scene) {
- // TRACE("Drawing model: %s", model->name);
- mat4 view;
- mat4 proj;
- camera_view_projection(camera, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
-
- set_shader(ren->blinn_phong);
-
- // set camera uniform
- uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &camera->position);
- // set light uniforms
- dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light);
- for (int i = 0; i < scene->n_point_lights; i++) {
- point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i);
- }
-
- for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
- mesh* m = &model->meshes->data[i];
- if (vertex_darray_len(m->vertices) == 0) {
- continue;
- }
- // TRACE("Drawing mesh %d", i);
- material* mat = &model->materials->data[m->material_index];
- draw_mesh(ren, m, model_tf, mat, &view, &proj);
- }
-}
-
-void draw_mesh(renderer* ren, mesh* mesh, mat4* model_tf, material* mat, mat4* view, mat4* proj) {
- shader lighting_shader = ren->blinn_phong;
-
- // bind buffer
- bind_mesh_vertex_buffer(ren->backend_state, mesh);
-
- // bind textures
- bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
- bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
- uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
-
- // upload model, view, and projection matrices
- uniform_mat4f(lighting_shader.program_id, "model", model_tf);
- uniform_mat4f(lighting_shader.program_id, "view", view);
- uniform_mat4f(lighting_shader.program_id, "projection", proj);
-
- // draw triangles
- u32 num_vertices = vertex_darray_len(mesh->vertices);
- draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
-}
-
-void draw_skinned_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* view,
- mat4* proj) {
- shader lighting_shader = ren->skinned;
-
- // bind buffer
- bind_mesh_vertex_buffer(ren->backend_state, mesh);
-
- // bind textures
- bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
- bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
-
- // Uniforms
- uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
- mat4 trans = mat4_translation(tf.position);
- mat4 rot = mat4_rotation(tf.rotation);
- mat4 scale = mat4_scale(tf.scale);
- mat4 model_tf = mat4_mult(trans, mat4_mult(rot, scale));
- uniform_mat4f(lighting_shader.program_id, "model", &model_tf);
- uniform_mat4f(lighting_shader.program_id, "view", view);
- uniform_mat4f(lighting_shader.program_id, "projection", proj);
-
- // bone transforms
- size_t n_bones = mesh->bones->len;
-
- // for now assume correct ordering
- mat4* bone_transforms = malloc(n_bones * sizeof(mat4));
- mat4 parent = mat4_ident();
- for (int bone_i = 0; bone_i < n_bones; bone_i++) {
- joint j = mesh->bones->data[bone_i];
- transform tf = mesh->bones->data[bone_i].transform_components;
- tf.position.y = -tf.position.y;
- mat4 local = transform_to_mat(&tf);
- mat4 inverse = j.inverse_bind_matrix;
- inverse.data[13] = -inverse.data[13];
- mat4 intemediate = mat4_mult(local, inverse);
-
- bone_transforms[bone_i] = intemediate;
- parent = bone_transforms[bone_i];
- }
-
- // premultiply the inverses
- // for (int bone_i = 0; bone_i < n_bones; bone_i++) {
- // joint j = mesh->bones->data[bone_i];
- // // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix);
- // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix);
- // }
-
- glUniformMatrix4fv(glGetUniformLocation(lighting_shader.program_id, "boneMatrices"), n_bones,
- GL_FALSE, &bone_transforms->data[0]);
-
- free(bone_transforms);
-
- // draw triangles
- u32 num_vertices = vertex_darray_len(mesh->vertices);
- draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
-}
-
-void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene) {
- mat4 view;
- mat4 proj;
- camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
-
- set_shader(ren->skinned);
-
- // set camera uniform
- uniform_vec3f(ren->skinned.program_id, "viewPos", &cam->position);
- // set light uniforms
- dir_light_upload_uniforms(ren->skinned, &scene->dir_light);
- for (int i = 0; i < scene->n_point_lights; i++) {
- point_light_upload_uniforms(ren->skinned, &scene->point_lights[i], '0' + i);
- }
-
- for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
- mesh* m = &model->meshes->data[i];
- if (vertex_darray_len(m->vertices) == 0) {
- continue;
- }
- // material* mat = &model->materials->data[m->material_index];
- material* mat = &DEFAULT_MATERIAL;
- draw_skinned_mesh(ren, m, tf, mat, &view, &proj);
- }
-}
-
-void model_upload_meshes(renderer* ren, model* model) {
- INFO("Upload mesh vertex data to GPU for model %s", model->name);
-
- size_t num_meshes = mesh_darray_len(model->meshes);
- u32 VBOs[num_meshes];
- u32 VAOs[num_meshes];
- glGenBuffers(num_meshes, VBOs);
- glGenVertexArrays(num_meshes, VAOs);
-
- u64 total_verts = 0;
-
- TRACE("num meshes %d", num_meshes);
-
- // upload each mesh to the GPU
- for (int mesh_i = 0; mesh_i < num_meshes; mesh_i++) {
- mesh mesh = model->meshes->data[mesh_i];
- model->meshes->data[mesh_i].vao = VAOs[mesh_i];
- model->meshes->data[mesh_i].vbo = VBOs[mesh_i];
- // 3. bind buffers
- glBindBuffer(GL_ARRAY_BUFFER, VBOs[mesh_i]);
-
- size_t num_vertices = vertex_darray_len(model->meshes->data[mesh_i].vertices);
- // TRACE("Uploading vertex array data: %d verts", num_vertices);
- total_verts += num_vertices;
-
- size_t static_vertex_size = 2 * sizeof(vec3) + sizeof(vec2);
- size_t skinned_vertex_size = 2 * sizeof(vec3) + sizeof(vec2) + 4 * sizeof(u32) + sizeof(vec4);
- size_t vertex_size = mesh.is_skinned ? skinned_vertex_size : static_vertex_size;
-
- // TRACE("sizeof(vertex) -> %ld, vertex_size -> %ld\n", sizeof(vertex), vertex_size);
- if (mesh.is_skinned) {
- assert(vertex_size == (12 + 12 + 8 + 16 + 16));
- } else {
- assert(vertex_size == sizeof(vertex));
- assert(vertex_size == 8 * sizeof(float));
- }
-
- size_t buffer_size = vertex_size * num_vertices;
- u8* bytes = malloc(buffer_size);
-
- for (int i = 0; i < num_vertices; i++) {
- u8* p = bytes + vertex_size * i;
- memcpy(p, &mesh.vertices->data[i], static_vertex_size);
- if (mesh.is_skinned) {
- u8* bone_data_offset = p + static_vertex_size;
- memcpy(bone_data_offset, &mesh.vertex_bone_data->data[i], sizeof(vertex_bone_data));
- }
- }
-
- // 4. upload data
- glBufferData(GL_ARRAY_BUFFER, buffer_size, bytes, GL_STATIC_DRAW);
-
- // 5. cont. set mesh vertex layout
- glBindVertexArray(model->meshes->data[mesh_i].vao);
- // position attribute
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)0);
- glEnableVertexAttribArray(0);
- // normal vector attribute
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
- // tex coords
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertex_size, (void*)(6 * sizeof(float)));
- glEnableVertexAttribArray(2);
-
- // skinning (optional)
- if (mesh.is_skinned) {
- glEnableVertexAttribArray(3);
- glVertexAttribIPointer(3, 4, GL_INT, vertex_size, (void*)(8 * sizeof(float)));
-
- glEnableVertexAttribArray(4);
- glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, vertex_size, (void*)(12 * sizeof(float)));
- }
- }
-
- INFO("Uploaded %d submeshes with a total of %d vertices\n", num_meshes, total_verts);
-
- // 6. reset buffer
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-texture texture_data_load(const char* path, bool invert_y) {
- TRACE("Load texture %s", path);
-
- // load the file data
- // texture loading
- int width, height, num_channels;
- stbi_set_flip_vertically_on_load(invert_y);
-
-#pragma GCC diagnostic ignored "-Wpointer-sign"
- char* data = stbi_load(path, &width, &height, &num_channels, 0); // STBI_rgb_alpha);
- if (data) {
- DEBUG("loaded texture: %s", path);
- } else {
- WARN("failed to load texture");
- }
-
- unsigned int channel_type;
- if (num_channels == 4) {
- channel_type = GL_RGBA;
- } else {
- channel_type = GL_RGB;
- }
-
- return (texture){ .texture_id = 0,
- .width = width,
- .height = height,
- .channel_count = num_channels,
- .channel_type = channel_type,
- .name = "TODO: Texture names",
- .image_data = data };
-}
-
-void dir_light_upload_uniforms(shader shader, directional_light* light) {
- uniform_vec3f(shader.program_id, "dirLight.direction", &light->direction);
- uniform_vec3f(shader.program_id, "dirLight.ambient", &light->ambient);
- uniform_vec3f(shader.program_id, "dirLight.diffuse", &light->diffuse);
- uniform_vec3f(shader.program_id, "dirLight.specular", &light->specular);
-}
+void render_frame_begin(renderer* ren) {}
+void render_frame_end(renderer* ren) {}
+void render_frame_draw(renderer* ren) {}
-void point_light_upload_uniforms(shader shader, point_light* light, char index) {
- char position_str[] = "pointLights[x].position";
- position_str[12] = (char)index;
- char ambient_str[] = "pointLights[x].ambient";
- ambient_str[12] = (char)index;
- char diffuse_str[] = "pointLights[x].diffuse";
- diffuse_str[12] = (char)index;
- char specular_str[] = "pointLights[x].specular";
- specular_str[12] = (char)index;
- char constant_str[] = "pointLights[x].constant";
- constant_str[12] = (char)index;
- char linear_str[] = "pointLights[x].linear";
- linear_str[12] = (char)index;
- char quadratic_str[] = "pointLights[x].quadratic";
- quadratic_str[12] = (char)index;
- uniform_vec3f(shader.program_id, position_str, &light->position);
- uniform_vec3f(shader.program_id, ambient_str, &light->ambient);
- uniform_vec3f(shader.program_id, diffuse_str, &light->diffuse);
- uniform_vec3f(shader.program_id, specular_str, &light->specular);
- uniform_f32(shader.program_id, constant_str, light->constant);
- uniform_f32(shader.program_id, linear_str, light->linear);
- uniform_f32(shader.program_id, quadratic_str, light->quadratic);
-} \ No newline at end of file
+void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model, texture* tex) {} \ No newline at end of file
diff --git a/src/renderer/render.h b/src/renderer/render.h
index 31cf3b0..0aeeac2 100644
--- a/src/renderer/render.h
+++ b/src/renderer/render.h
@@ -10,37 +10,34 @@
*/
#pragma once
-#include "camera.h"
-#include "loaders.h"
#include "render_types.h"
-#include "transform_hierarchy.h"
+#include "ral_types.h"
-// --- Lifecycle
-/** @brief initialise the render system frontend */
bool renderer_init(renderer* ren);
-/** @brief shutdown the render system frontend */
void renderer_shutdown(renderer* ren);
-void renderer_on_resize(renderer* ren);
-
-struct render_packet;
-
-// --- Frame
-
void render_frame_begin(renderer* ren);
void render_frame_end(renderer* ren);
void render_frame_draw(renderer* ren);
-// --- models meshes
-void model_upload_meshes(renderer* ren, model* model);
-void draw_model(renderer* ren, camera* camera, model* model, mat4* tf, scene* scene);
-void draw_mesh(renderer* ren, mesh* mesh, mat4* tf, material* mat, mat4* view, mat4* proj);
-void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera,
- transform_hierarchy* tfh, scene* scene);
+// ! TEMP
+typedef struct camera camera;
+void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model, texture* tex);
+
+// frontend -- these can be called from say a loop in an example, or via FFI
+texture_handle texture_create(const char* debug_name, texture_desc description, const u8* data);
+
+// Frontend Resources
+// TODO: void texture_data_upload(texture_handle texture);
+void texture_data_upload(texture* tex);
+texture texture_data_load(const char* path, bool invert_y);
+buffer_handle buffer_create(const char* debug_name, u64 size);
+bool buffer_destroy(buffer_handle buffer);
+sampler_handle sampler_create();
-void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene);
+void shader_hot_reload(const char* filepath);
-void model_destroy(model* model);
+// models and meshes are implemented **in terms of the above**
+mesh mesh_create(geometry_data* geometry);
-// ---
-texture texture_data_load(const char* path, bool invert_y); // #frontend
+model_handle model_load(const char* debug_name, const char* filepath); \ No newline at end of file
diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h
index 3bce88f..bc9692f 100644
--- a/src/renderer/render_types.h
+++ b/src/renderer/render_types.h
@@ -1,60 +1,71 @@
-// /**
-// * @file render_types.h
-// * @author Omniscient
-// * @brief Type definitions for the majority of data required by the renderer system
-// * @date 2024-02-24
-// *
-// */
-// #pragma once
+/**
+ * @file render_types.h
+ * @author your name (you@domain.com)
+ * @brief
+ * @version 0.1
+ * @date 2024-04-27
+ *
+ * @copyright Copyright (c) 2024
+ *
+ */
+#pragma once
+
+#include "ral_types.h"
+#include "ral.h"
+#if defined(CEL_PLATFORM_WINDOWS)
+#include "backend_dx11.h"
+#endif
-#include "animation.h"
-#include "darray.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "str.h"
-
-// struct GLFWwindow;
-
-// #define MAX_MATERIAL_NAME_LEN 256
-// #define MAX_TEXTURE_NAME_LEN 256
-
-// #ifndef RESOURCE_HANDLE_DEFS
-// // CORE_DEFINE_HANDLE(model_handle);
-// #define ABSENT_MODEL_HANDLE 999999999
-// // CORE_DEFINE_HANDLE(texture_handle);
-// #define RESOURCE_HANDLE_DEFS
-// #endif
-
-// /* @brief Opaque wrapper around a shader program */
-// typedef struct shader {
-// u32 program_id;
-// } shader;
-
-// /** @brief configuration passed to the renderer at init time */
-// typedef struct renderer_config {
-// char window_name[256];
-// u32 scr_width, scr_height;
-// vec3 clear_colour; /** colour that the screen gets cleared to every frame */
-// } renderer_config;
-
-// typedef struct frame_stats {
-// u64 last_time;
-// } frame_stats;
+struct GLFWwindow;
+
+/** @brief configuration passed to the renderer at init time */
+typedef struct renderer_config {
+ char window_name[256];
+ u32 scr_width, scr_height;
+ vec3 clear_colour; /** colour that the screen gets cleared to every frame */
+} renderer_config;
typedef struct renderer {
- struct GLFWwindow *window; /** Currently all platforms use GLFW*/
- void *backend_state; /** Graphics API-specific state */
+ struct GLFWwindow* window;
+ void* backend_context;
renderer_config config;
- // shaders
- shader blinn_phong;
- shader skinned;
+ gpu_device* device;
+ gpu_pipeline* static_opaque_pipeline;
} renderer;
-// // --- Lighting & Materials
+typedef struct geometry_data {
+ vertex_format format;
+ vertex_darray* vertices; // TODO: make it not a pointe
+ bool has_indices;
+ u32_darray indices;
+ vec3 colour; /** Optional: set vertex colours */
+} geometry_data;
+
+void geo_set_vertex_colours(geometry_data* geo, vec4 colour);
+
+typedef struct mesh {
+ buffer_handle vertex_buffer;
+ buffer_handle index_buffer;
+ u32 index_count;
+ bool has_indices;
+ geometry_data* vertices; // NULL means it has been freed
+} mesh;
+
+/* Hot reloading:
+C side - reload_model():
+ - load model from disk using existing loader
+ - remove from transform graph so it isnt tried to be drawn
+*/
+
+typedef struct model {
+ str8 name;
+ mesh* meshes;
+ u32 mesh_count;
+} model;
typedef struct texture {
u32 texture_id;
- char name[MAX_TEXTURE_NAME_LEN];
+ char name[256];
void *image_data;
void *backend_data;
u32 width;
@@ -63,148 +74,42 @@ typedef struct texture {
u32 channel_type;
} texture;
-// typedef struct blinn_phong_material {
-// char name[MAX_MATERIAL_NAME_LEN];
-// texture diffuse_texture;
-// char diffuse_tex_path[256];
-// texture specular_texture;
-// char specular_tex_path[256];
-// vec3 ambient_colour;
-// vec3 diffuse;
-// vec3 specular;
-// f32 spec_exponent;
-// bool is_loaded;
-// bool is_uploaded;
-// } blinn_phong_material;
-// typedef blinn_phong_material material; // when we start using PBR, this will no longer be the
-// case
-
-// // the default blinn-phong material. MUST be initialised with the function below
-// extern material DEFAULT_MATERIAL;
-// void default_material_init();
+typedef struct blinn_phong_material {
+ char name[256];
+ texture diffuse_texture;
+ char diffuse_tex_path[256];
+ texture specular_texture;
+ char specular_tex_path[256];
+ vec3 ambient_colour;
+ vec3 diffuse;
+ vec3 specular;
+ f32 spec_exponent;
+ bool is_loaded;
+ bool is_uploaded;
+} blinn_phong_material;
+typedef blinn_phong_material material;
-#ifndef TYPED_MATERIAL_ARRAY
-KITC_DECL_TYPED_ARRAY(material) // creates "material_darray"
-#define TYPED_MATERIAL_ARRAY
-#endif
+// the default blinn-phong material. MUST be initialised with the function below
+extern material DEFAULT_MATERIAL;
+void default_material_init();
-#ifndef TYPED_ANIMATION_CLIP_ARRAY
-KITC_DECL_TYPED_ARRAY(animation_clip) // creates "material_darray"
-#define TYPED_ANIMATION_CLIP_ARRAY
+#ifndef TYPED_MESH_ARRAY
+KITC_DECL_TYPED_ARRAY(mesh)
+#define TYPED_MESH_ARRAY
#endif
-// // lights
-// typedef struct point_light {
-// vec3 position;
-// f32 constant, linear, quadratic;
-// vec3 ambient;
-// vec3 diffuse;
-// vec3 specular;
-// } point_light;
-
-// typedef struct directional_light {
-// vec3 direction;
-// vec3 ambient;
-// vec3 diffuse;
-// vec3 specular;
-// } directional_light;
-
-// void point_light_upload_uniforms(shader shader, point_light *light, char index);
-// void dir_light_upload_uniforms(shader shader, directional_light *light);
-
-// // --- Models & Meshes
-
-// /** @brief Vertex format for a static mesh */
-// typedef struct vertex {
-// vec3 position;
-// vec3 normal;
-// vec2 uv;
-// } vertex;
-
-typedef struct vertex_bone_data {
- vec4u joints; /** @brief 4 indices of joints that influence vectors position */
- vec4 weights; /** @brief weight (0,1) of each joint */
-} vertex_bone_data;
-
-#include "animation.h"
-#ifndef TYPED_VERTEX_ARRAY
-KITC_DECL_TYPED_ARRAY(vertex) // creates "vertex_darray"
-KITC_DECL_TYPED_ARRAY(vertex_bone_data) // creates "skinned_vertex_darray"
-KITC_DECL_TYPED_ARRAY(joint)
-#define TYPED_VERTEX_ARRAY
+#ifndef TYPED_MODEL_ARRAY
+KITC_DECL_TYPED_ARRAY(model)
+#define TYPED_MODEL_ARRAY
#endif
-typedef struct mesh {
- vertex_darray *vertices;
- vertex_bone_data_darray *vertex_bone_data; // only used if model needs it
- joint_darray *bones;
- bool is_skinned;
- u32 vertex_size; /** size in bytes of each vertex including necessary padding */
- bool has_indices;
- u32 *indices;
- u32 indices_len;
- size_t material_index;
- u32 vbo, vao; /** OpenGL data. TODO: dont leak OpenGL details */
-} mesh;
-
-// #ifndef TYPED_MESH_ARRAY
-// KITC_DECL_TYPED_ARRAY(mesh) // creates "mesh_darray"
-// #define TYPED_MESH_ARRAY
-// #endif
-
-typedef struct model {
- str8 name;
- mesh_darray *meshes;
- aabb_3d bbox;
- material_darray *materials;
- animation_clip_darray *animations;
- arena animation_data_arena;
- bool is_loaded;
- bool is_uploaded;
-} model;
+#ifndef TYPED_MATERIAL_ARRAY
+KITC_DECL_TYPED_ARRAY(material)
+#define TYPED_MATERIAL_ARRAY
+#endif
-// #ifndef TYPED_MODEL_ARRAY
-// KITC_DECL_TYPED_ARRAY(model) // creates "model_darray"
-// #define TYPED_MODEL_ARRAY
-// #endif
-
-// // --- Scene
-
-// // NOTE: This struct won't stay like this for a long time. It's somewhat temporary
-// // in order to get a basic scene working without putting burden on the caller of
-// // draw_model()
-// typedef struct scene {
-// directional_light dir_light;
-// point_light point_lights[4];
-// size_t n_point_lights;
-// } scene;
-
-// // --- Graphics API related
-
-// // typedef enum cel_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 {
-// // TEXTURE_TYPE_2D,
-// // TEXTURE_TYPE_3D,
-// // TEXTURE_TYPE_2D_ARRAY,
-// // TEXTURE_TYPE_CUBE_MAP,
-// // TEXTURE_TYPE_COUNT
-// // } gpu_texture_type;
-
-// // typedef enum gpu_texture_format {
-// // TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
-// // TEXTURE_FORMAT_DEPTH_DEFAULT,
-// // TEXTURE_FORMAT_COUNT
-// // } gpu_texture_format;
-
-// // typedef enum pipeline_kind {
-// // GRAPHICS,
-// // COMPUTE,
-// // } pipeline_kind; \ No newline at end of file
+#ifndef TYPED_ANIMATION_CLIP_ARRAY
+#include "animation.h"
+KITC_DECL_TYPED_ARRAY(animation_clip)
+#define TYPED_ANIMATION_CLIP_ARRAY
+#endif \ No newline at end of file
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
index 81992d1..022bf95 100644
--- a/src/resources/gltf.c
+++ b/src/resources/gltf.c
@@ -12,7 +12,7 @@
#include "mem.h"
#include "path.h"
#include "render.h"
-#include "render_backend.h"
+// #include "render_backend.h"
#include "render_types.h"
#include "str.h"
@@ -26,7 +26,6 @@ typedef struct face face;
KITC_DECL_TYPED_ARRAY(vec3)
KITC_DECL_TYPED_ARRAY(vec2)
-KITC_DECL_TYPED_ARRAY(u32)
KITC_DECL_TYPED_ARRAY(vec4u)
KITC_DECL_TYPED_ARRAY(vec4)
KITC_DECL_TYPED_ARRAY(face)
@@ -49,7 +48,7 @@ model_handle model_load_gltf(struct core *core, const char *path, bool invert_te
model model = { 0 };
model.name = str8_cstr_view(path);
model.meshes = mesh_darray_new(1);
- model.materials = material_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);
@@ -79,403 +78,414 @@ void assert_path_type_matches_component_type(cgltf_animation_path_type target_pa
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);
- 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;
- bool is_skinned = false;
- if (num_skins == 1) {
- is_skinned = true;
- } else if (num_skins > 1) {
- WARN("GLTF files with more than 1 skin are not supported");
- return false;
- }
-
- if (is_skinned) {
- cgltf_skin *gltf_skin = data->skins;
- DEBUG("loading skin %s", gltf_skin->name);
- size_t num_joints = gltf_skin->joints_count;
- DEBUG("# Joints %d", num_joints);
-
- cgltf_accessor *gltf_inverse_bind_matrices = gltf_skin->inverse_bind_matrices;
-
- // for each one we'll spit out a joint
- for (size_t i = 0; i < num_joints; i++) {
- cgltf_node *joint_node = gltf_skin->joints[i];
-
- joint joint_i = { .name = "testjoint" };
- if (joint_node->children_count > 0 && !joint_node->has_translation &&
- !joint_node->has_rotation) {
- WARN("joint Node with index %d is the root node", i);
- joint_i.transform_components = TRANSFORM_DEFAULT;
- } else {
- TRACE("Storing joint transform");
- joint_i.transform_components = TRANSFORM_DEFAULT;
- if (joint_node->has_translation) {
- memcpy(&joint_i.transform_components.position, &joint_node->translation, 3 * sizeof(f32));
- }
- if (joint_node->has_rotation) {
- memcpy(&joint_i.transform_components.rotation, &joint_node->rotation, 4 * sizeof(f32));
- }
- // TODO: support scaling as vec instead of float
- }
- joint_i.local_transform = transform_to_mat(&joint_i.transform_components);
- cgltf_accessor_read_float(gltf_inverse_bind_matrices, i, &joint_i.inverse_bind_matrix.data[0],
- 16);
- joint_darray_push(tmp_joints, joint_i);
- }
- }
-
- // --- Materials
- TRACE("Num materials %d", data->materials_count);
- size_t num_materials = data->materials_count;
- for (size_t m = 0; m < num_materials; m++) {
- cgltf_material gltf_material = data->materials[m];
- material our_material = DEFAULT_MATERIAL;
-
- strcpy(our_material.name, gltf_material.name);
-
- cgltf_pbr_metallic_roughness pbr = gltf_material.pbr_metallic_roughness;
- if (gltf_material.has_pbr_metallic_roughness) {
- // we will use base color texture like blinn phong
- cgltf_texture_view diff_tex_view = pbr.base_color_texture;
-
- char diffuse_map_path[1024];
- snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf,
- diff_tex_view.texture->image->uri);
-
- strcpy(our_material.diffuse_tex_path, diffuse_map_path);
- texture diffuse_texture = texture_data_load(our_material.diffuse_tex_path, false);
- texture_data_upload(&diffuse_texture);
- our_material.diffuse_texture = diffuse_texture;
-
- cgltf_texture_view specular_tex_view = pbr.metallic_roughness_texture;
-
- char specular_map_path[1024];
- snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf,
- specular_tex_view.texture->image->uri);
-
- strcpy(our_material.specular_tex_path, specular_map_path);
- texture specular_texture = texture_data_load(our_material.specular_tex_path, false);
- texture_data_upload(&specular_texture);
- our_material.specular_texture = specular_texture;
- }
-
- material_darray_push(out_model->materials, our_material);
- }
-
- // --- Meshes
- TRACE("Num meshes %d", data->meshes_count);
- size_t num_meshes = data->meshes_count;
- for (size_t m = 0; m < num_meshes; m++) {
- cgltf_primitive primitive = data->meshes[m].primitives[0];
- DEBUG("Found %d attributes", primitive.attributes_count);
- // DEBUG("Number of this primitive %d", primitive.)
-
- for (int a = 0; a < data->meshes[m].primitives[0].attributes_count; a++) {
- cgltf_attribute attribute = data->meshes[m].primitives[0].attributes[a];
- if (attribute.type == cgltf_attribute_type_position) {
- TRACE("Load positions from accessor");
-
- cgltf_accessor *accessor = attribute.data;
- assert(accessor->component_type == cgltf_component_type_r_32f);
- // CASSERT_MSG(accessor->type == cgltf_type_vec3, "Vertex positions should be a vec3");
-
- 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);
- }
-
- } else if (attribute.type == cgltf_attribute_type_normal) {
- TRACE("Load normals from accessor");
-
- cgltf_accessor *accessor = attribute.data;
- 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);
- }
-
- } else if (attribute.type == cgltf_attribute_type_texcoord) {
- TRACE("Load texture coordinates from accessor");
- cgltf_accessor *accessor = attribute.data;
- assert(accessor->component_type == cgltf_component_type_r_32f);
- // CASSERT_MSG(accessor->type == cgltf_type_vec2, "Texture coordinates should be a vec2");
-
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- vec2 tex;
- bool success = cgltf_accessor_read_float(accessor, v, &tex.x, 2);
- if (!success) {
- ERROR("Error loading tex coord");
- }
- vec2_darray_push(tmp_uvs, tex);
- }
- } else if (attribute.type == cgltf_attribute_type_joints) {
- TRACE("Load joint indices from accessor");
- cgltf_accessor *accessor = attribute.data;
- assert(accessor->component_type == cgltf_component_type_r_16u);
- assert(accessor->type == cgltf_type_vec4);
- vec4u joint_indices;
- vec4 joints_as_floats;
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- cgltf_accessor_read_float(accessor, v, &joints_as_floats.x, 4);
- joint_indices.x = (u32)joints_as_floats.x;
- joint_indices.y = (u32)joints_as_floats.y;
- joint_indices.z = (u32)joints_as_floats.z;
- joint_indices.w = (u32)joints_as_floats.w;
- printf("Joints affecting vertex %d : %d %d %d %d\n", v, joint_indices.x, joint_indices.y,
- joint_indices.z, joint_indices.w);
- vec4u_darray_push(tmp_joint_indices, joint_indices);
- }
-
- } else if (attribute.type == cgltf_attribute_type_weights) {
- TRACE("Load joint weights from accessor");
- cgltf_accessor *accessor = attribute.data;
- assert(accessor->component_type == cgltf_component_type_r_32f);
- assert(accessor->type == cgltf_type_vec4);
-
- for (cgltf_size v = 0; v < accessor->count; ++v) {
- vec4 weights;
- cgltf_accessor_read_float(accessor, v, &weights.x, 4);
- printf("Weights affecting vertex %d : %f %f %f %f\n", v, weights.x, weights.y, weights.z,
- weights.w);
- vec4_darray_push(tmp_weights, weights);
- }
- } else {
- WARN("Unhandled cgltf_attribute_type: %s. skipping..", attribute.name);
- }
- }
-
- mesh mesh = { 0 };
- mesh.vertices = vertex_darray_new(10);
- mesh.vertex_bone_data = vertex_bone_data_darray_new(1);
-
- if (primitive.material != NULL) {
- for (int 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) {
- TRACE("Found material");
- mesh.material_index = i;
- break;
- }
- }
- }
-
- if (is_skinned) {
- mesh.is_skinned = true;
- // mesh.vertex_bone_data = vertex_bone_data_darray_new(tmp_joint_indices->len);
- mesh.bones = joint_darray_new(tmp_joints->len);
- for (int i = 0; i < tmp_joint_indices->len; i++) {
- vertex_bone_data data;
- data.joints = tmp_joint_indices->data[i];
- data.weights = tmp_weights->data[i];
- vertex_bone_data_darray_push(tmp_vertex_bone_data,
- data); // Push the temp data that aligns with raw vertices
- }
- for (int i = 0; i < tmp_joints->len; i++) {
- joint data = tmp_joints->data[i];
- joint_darray_push(mesh.bones, data);
- }
- }
-
- cgltf_accessor *indices = primitive.indices;
- if (primitive.indices > 0) {
- WARN("indices!");
- mesh.has_indices = true;
-
- mesh.indices = malloc(indices->count * sizeof(u32));
- mesh.indices_len = indices->count;
-
- // store indices
- for (cgltf_size i = 0; i < indices->count; ++i) {
- cgltf_uint ei;
- cgltf_accessor_read_uint(indices, i, &ei, 1);
- mesh.indices[i] = ei;
- }
-
- // fetch and store vertices for each index
- for (cgltf_size i = 0; i < indices->count; ++i) {
- vertex vert;
- cgltf_uint index = mesh.indices[i];
- vert.position = tmp_positions->data[index];
- vert.normal = tmp_normals->data[index];
- vert.uv = tmp_uvs->data[index];
- vertex_darray_push(mesh.vertices, vert);
-
- if (is_skinned) {
- vertex_bone_data vbd = tmp_vertex_bone_data->data[index]; // create a copy
- vertex_bone_data_darray_push(mesh.vertex_bone_data, vbd);
- }
- // for each vertex do the bone data
- }
- } else {
- mesh.has_indices = false;
- return false; // TODO
- }
-
- mesh_darray_push(out_model->meshes, mesh);
-
- // clear data for each mesh
- vec3_darray_clear(tmp_positions);
- vec3_darray_clear(tmp_normals);
- vec2_darray_free(tmp_uvs);
- vec4u_darray_clear(tmp_joint_indices);
- vec4_darray_clear(tmp_weights);
- joint_darray_clear(tmp_joints);
- }
-
- for (int i = 0; i < out_model->meshes->len; i++) {
- u32 mat_idx = out_model->meshes->data[i].material_index;
- printf("Mesh %d Mat index %d Mat name %s\n", i, mat_idx,
- out_model->materials->data[mat_idx].name);
- }
-
- // Animations
- TRACE("Num animations %d", data->animations_count);
- size_t num_animations = data->animations_count;
- if (num_animations > 0) {
-// Create an arena for all animation related data
-#define ANIMATION_STORAGE_ARENA_SIZE (1024 * 1024 * 1024)
- char *animation_backing_storage = malloc(ANIMATION_STORAGE_ARENA_SIZE);
- // We'll store data on this arena so we can easily free it all at once later
- out_model->animation_data_arena =
- arena_create(animation_backing_storage, ANIMATION_STORAGE_ARENA_SIZE);
- arena *arena = &out_model->animation_data_arena;
-
- if (!out_model->animations) {
- out_model->animations = animation_clip_darray_new(num_animations);
- }
-
- for (int anim_idx = 0; anim_idx < data->animations_count; anim_idx++) {
- cgltf_animation animation = data->animations[anim_idx];
- animation_clip clip = { 0 };
-
- for (size_t c = 0; c < animation.channels_count; c++) {
- cgltf_animation_channel channel = animation.channels[c];
-
- animation_sampler *sampler = arena_alloc(arena, sizeof(animation_sampler));
-
- animation_sampler **target_property;
- keyframe_kind data_type;
-
- switch (channel.target_path) {
- case cgltf_animation_path_type_rotation:
- target_property = &clip.rotation;
- data_type = KEYFRAME_ROTATION;
- break;
- case cgltf_animation_path_type_translation:
- target_property = &clip.translation;
- data_type = KEYFRAME_TRANSLATION;
- break;
- case cgltf_animation_path_type_scale:
- target_property = &clip.scale;
- data_type = KEYFRAME_SCALE;
- break;
- case cgltf_animation_path_type_weights:
- target_property = &clip.weights;
- data_type = KEYFRAME_WEIGHTS;
- WARN("Morph target weights arent supported yet");
- return false;
- default:
- WARN("unsupported animation type");
- return false;
- }
- *target_property = sampler;
-
- sampler->current_index = 0;
- printf("1 %d index\n", sampler->current_index);
- sampler->animation.interpolation = INTERPOLATION_LINEAR;
-
- // keyframe times
- size_t n_frames = channel.sampler->input->count;
- assert(channel.sampler->input->component_type == cgltf_component_type_r_32f);
- // FIXME: CASSERT_MSG function "Expected animation sampler input component to be type f32
- // (keyframe times)");
- f32 *times = arena_alloc(arena, n_frames * sizeof(f32));
- sampler->animation.n_timestamps = n_frames;
- sampler->animation.timestamps = times;
- cgltf_accessor_unpack_floats(channel.sampler->input, times, n_frames);
-
- assert_path_type_matches_component_type(channel.target_path, channel.sampler->output);
-
- // keyframe values
- size_t n_values = channel.sampler->output->count;
- assert(n_frames == n_values);
-
- keyframes keyframes = { 0 };
- keyframes.kind = KEYFRAME_ROTATION;
- keyframes.count = n_values;
- keyframes.values = arena_alloc(arena, n_values * sizeof(keyframe));
- for (cgltf_size v = 0; v < channel.sampler->output->count; ++v) {
- switch (data_type) {
- case KEYFRAME_ROTATION: {
- quat rot;
- cgltf_accessor_read_float(channel.sampler->output, v, &rot.x, 4);
- // printf("Quat %f %f %f %f\n", rot.x, rot.y, rot.z, rot.w);
- keyframes.values[v].rotation = rot;
- break;
- }
- case KEYFRAME_TRANSLATION: {
- vec3 trans;
- cgltf_accessor_read_float(channel.sampler->output, v, &trans.x, 3);
- keyframes.values[v].translation = trans;
- break;
- }
- case KEYFRAME_SCALE: {
- vec3 scale;
- cgltf_accessor_read_float(channel.sampler->output, v, &scale.x, 3);
- keyframes.values[v].scale = scale;
- break;
- }
- case KEYFRAME_WEIGHTS: {
- // TODO
- break;
- }
- }
- }
- sampler->animation.values = keyframes;
-
- sampler->min = channel.sampler->input->min[0];
- sampler->max = channel.sampler->input->max[0];
-
- // clip.rotation = sampler;
- // printf("%d timestamps\n", sampler->animation.n_timestamps);
- // printf("%d index\n", sampler->current_index);
- }
-
- WARN("stuff %ld", clip.rotation->animation.n_timestamps);
- animation_clip_darray_push(out_model->animations, clip);
- }
- }
-
- return true;
+ return false;
+ // 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;
+ // bool is_skinned = false;
+ // if (num_skins == 1) {
+ // is_skinned = true;
+ // } else if (num_skins > 1) {
+ // WARN("GLTF files with more than 1 skin are not supported");
+ // return false;
+ // }
+
+ // if (is_skinned) {
+ // cgltf_skin *gltf_skin = data->skins;
+ // DEBUG("loading skin %s", gltf_skin->name);
+ // size_t num_joints = gltf_skin->joints_count;
+ // DEBUG("# Joints %d", num_joints);
+
+ // cgltf_accessor *gltf_inverse_bind_matrices = gltf_skin->inverse_bind_matrices;
+
+ // // for each one we'll spit out a joint
+ // for (size_t i = 0; i < num_joints; i++) {
+ // cgltf_node *joint_node = gltf_skin->joints[i];
+
+ // joint joint_i = { .name = "testjoint" };
+ // if (joint_node->children_count > 0 && !joint_node->has_translation &&
+ // !joint_node->has_rotation) {
+ // WARN("joint Node with index %d is the root node", i);
+ // joint_i.transform_components = TRANSFORM_DEFAULT;
+ // } else {
+ // TRACE("Storing joint transform");
+ // joint_i.transform_components = TRANSFORM_DEFAULT;
+ // if (joint_node->has_translation) {
+ // memcpy(&joint_i.transform_components.position, &joint_node->translation, 3 *
+ // sizeof(f32));
+ // }
+ // if (joint_node->has_rotation) {
+ // memcpy(&joint_i.transform_components.rotation, &joint_node->rotation, 4 *
+ // sizeof(f32));
+ // }
+ // // TODO: support scaling as vec instead of float
+ // }
+ // joint_i.local_transform = transform_to_mat(&joint_i.transform_components);
+ // cgltf_accessor_read_float(gltf_inverse_bind_matrices, i,
+ // &joint_i.inverse_bind_matrix.data[0],
+ // 16);
+ // // joint_darray_push(tmp_joints, joint_i);
+ // }
+ // }
+
+ // // --- Materials
+ // TRACE("Num materials %d", data->materials_count);
+ // size_t num_materials = data->materials_count;
+ // for (size_t m = 0; m < num_materials; m++) {
+ // cgltf_material gltf_material = data->materials[m];
+ // material our_material = DEFAULT_MATERIAL;
+
+ // strcpy(our_material.name, gltf_material.name);
+
+ // cgltf_pbr_metallic_roughness pbr = gltf_material.pbr_metallic_roughness;
+ // if (gltf_material.has_pbr_metallic_roughness) {
+ // // we will use base color texture like blinn phong
+ // cgltf_texture_view diff_tex_view = pbr.base_color_texture;
+
+ // char diffuse_map_path[1024];
+ // snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf,
+ // diff_tex_view.texture->image->uri);
+
+ // strcpy(our_material.diffuse_tex_path, diffuse_map_path);
+ // texture diffuse_texture = texture_data_load(our_material.diffuse_tex_path, false);
+ // texture_data_upload(&diffuse_texture);
+ // our_material.diffuse_texture = diffuse_texture;
+
+ // cgltf_texture_view specular_tex_view = pbr.metallic_roughness_texture;
+
+ // char specular_map_path[1024];
+ // snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf,
+ // specular_tex_view.texture->image->uri);
+
+ // strcpy(our_material.specular_tex_path, specular_map_path);
+ // texture specular_texture = texture_data_load(our_material.specular_tex_path, false);
+ // texture_data_upload(&specular_texture);
+ // our_material.specular_texture = specular_texture;
+ // }
+
+ // // material_darray_push(out_model->materials, our_material);
+ // }
+
+ // // --- Meshes
+ // TRACE("Num meshes %d", data->meshes_count);
+ // size_t num_meshes = data->meshes_count;
+ // for (size_t m = 0; m < num_meshes; m++) {
+ // cgltf_primitive primitive = data->meshes[m].primitives[0];
+ // DEBUG("Found %d attributes", primitive.attributes_count);
+ // // DEBUG("Number of this primitive %d", primitive.)
+
+ // for (int a = 0; a < data->meshes[m].primitives[0].attributes_count; a++) {
+ // cgltf_attribute attribute = data->meshes[m].primitives[0].attributes[a];
+ // if (attribute.type == cgltf_attribute_type_position) {
+ // TRACE("Load positions from accessor");
+
+ // cgltf_accessor *accessor = attribute.data;
+ // assert(accessor->component_type == cgltf_component_type_r_32f);
+ // // CASSERT_MSG(accessor->type == cgltf_type_vec3, "Vertex positions should be a vec3");
+
+ // 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);
+ // }
+
+ // } else if (attribute.type == cgltf_attribute_type_normal) {
+ // TRACE("Load normals from accessor");
+
+ // cgltf_accessor *accessor = attribute.data;
+ // 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);
+ // }
+
+ // } else if (attribute.type == cgltf_attribute_type_texcoord) {
+ // TRACE("Load texture coordinates from accessor");
+ // cgltf_accessor *accessor = attribute.data;
+ // assert(accessor->component_type == cgltf_component_type_r_32f);
+ // // CASSERT_MSG(accessor->type == cgltf_type_vec2, "Texture coordinates should be a
+ // vec2");
+
+ // for (cgltf_size v = 0; v < accessor->count; ++v) {
+ // vec2 tex;
+ // bool success = cgltf_accessor_read_float(accessor, v, &tex.x, 2);
+ // if (!success) {
+ // ERROR("Error loading tex coord");
+ // }
+ // vec2_darray_push(tmp_uvs, tex);
+ // }
+ // } else if (attribute.type == cgltf_attribute_type_joints) {
+ // TRACE("Load joint indices from accessor");
+ // cgltf_accessor *accessor = attribute.data;
+ // assert(accessor->component_type == cgltf_component_type_r_16u);
+ // assert(accessor->type == cgltf_type_vec4);
+ // vec4u joint_indices;
+ // vec4 joints_as_floats;
+ // for (cgltf_size v = 0; v < accessor->count; ++v) {
+ // cgltf_accessor_read_float(accessor, v, &joints_as_floats.x, 4);
+ // joint_indices.x = (u32)joints_as_floats.x;
+ // joint_indices.y = (u32)joints_as_floats.y;
+ // joint_indices.z = (u32)joints_as_floats.z;
+ // joint_indices.w = (u32)joints_as_floats.w;
+ // printf("Joints affecting vertex %d : %d %d %d %d\n", v, joint_indices.x,
+ // joint_indices.y,
+ // joint_indices.z, joint_indices.w);
+ // vec4u_darray_push(tmp_joint_indices, joint_indices);
+ // }
+
+ // } else if (attribute.type == cgltf_attribute_type_weights) {
+ // TRACE("Load joint weights from accessor");
+ // cgltf_accessor *accessor = attribute.data;
+ // assert(accessor->component_type == cgltf_component_type_r_32f);
+ // assert(accessor->type == cgltf_type_vec4);
+
+ // for (cgltf_size v = 0; v < accessor->count; ++v) {
+ // vec4 weights;
+ // cgltf_accessor_read_float(accessor, v, &weights.x, 4);
+ // printf("Weights affecting vertex %d : %f %f %f %f\n", v, weights.x, weights.y,
+ // weights.z,
+ // weights.w);
+ // vec4_darray_push(tmp_weights, weights);
+ // }
+ // } else {
+ // WARN("Unhandled cgltf_attribute_type: %s. skipping..", attribute.name);
+ // }
+ // }
+
+ // mesh mesh = { 0 };
+ // mesh.vertices = vertex_darray_new(10);
+ // // mesh.vertex_bone_data = vertex_bone_data_darray_new(1);
+
+ // if (primitive.material != NULL) {
+ // // for (int 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) {
+ // // TRACE("Found material");
+ // // mesh.material_index = i;
+ // // break;
+ // // }
+ // // }
+ // }
+
+ // // FIXME
+ // // if (is_skinned) {
+ // // mesh.is_skinned = true;
+ // // // mesh.vertex_bone_data = vertex_bone_data_darray_new(tmp_joint_indices->len);
+ // // mesh.bones = joint_darray_new(tmp_joints->len);
+ // // for (int i = 0; i < tmp_joint_indices->len; i++) {
+ // // vertex_bone_data data;
+ // // data.joints = tmp_joint_indices->data[i];
+ // // data.weights = tmp_weights->data[i];
+ // // vertex_bone_data_darray_push(tmp_vertex_bone_data,
+ // // data); // Push the temp data that aligns with raw
+ // vertices
+ // // }
+ // // for (int i = 0; i < tmp_joints->len; i++) {
+ // // joint data = tmp_joints->data[i];
+ // // joint_darray_push(mesh.bones, data);
+ // // }
+ // // }
+
+ // cgltf_accessor *indices = primitive.indices;
+ // if (primitive.indices > 0) {
+ // WARN("indices!");
+ // mesh.has_indices = true;
+
+ // mesh.indices = malloc(indices->count * sizeof(u32));
+ // mesh.indices_len = indices->count;
+
+ // // store indices
+ // for (cgltf_size i = 0; i < indices->count; ++i) {
+ // cgltf_uint ei;
+ // cgltf_accessor_read_uint(indices, i, &ei, 1);
+ // mesh.indices[i] = ei;
+ // }
+
+ // // fetch and store vertices for each index
+ // for (cgltf_size i = 0; i < indices->count; ++i) {
+ // vertex vert;
+ // cgltf_uint index = mesh.indices[i];
+ // vert.position = tmp_positions->data[index];
+ // vert.normal = tmp_normals->data[index];
+ // vert.uv = tmp_uvs->data[index];
+ // vertex_darray_push(mesh.vertices, vert);
+
+ // if (is_skinned) {
+ // vertex_bone_data vbd = tmp_vertex_bone_data->data[index]; // create a copy
+ // vertex_bone_data_darray_push(mesh.vertex_bone_data, vbd);
+ // }
+ // // for each vertex do the bone data
+ // }
+ // } else {
+ // mesh.has_indices = false;
+ // return false; // TODO
+ // }
+
+ // mesh_darray_push(out_model->meshes, mesh);
+
+ // // clear data for each mesh
+ // vec3_darray_clear(tmp_positions);
+ // vec3_darray_clear(tmp_normals);
+ // vec2_darray_free(tmp_uvs);
+ // vec4u_darray_clear(tmp_joint_indices);
+ // vec4_darray_clear(tmp_weights);
+ // joint_darray_clear(tmp_joints);
+ // }
+
+ // for (int i = 0; i < out_model->meshes->len; i++) {
+ // u32 mat_idx = out_model->meshes->data[i].material_index;
+ // printf("Mesh %d Mat index %d Mat name %s\n", i, mat_idx,
+ // out_model->materials->data[mat_idx].name);
+ // }
+
+ // // Animations
+ // TRACE("Num animations %d", data->animations_count);
+ // size_t num_animations = data->animations_count;
+ // if (num_animations > 0) {
+ // // Create an arena for all animation related data
+ // #define ANIMATION_STORAGE_ARENA_SIZE (1024 * 1024 * 1024)
+ // char *animation_backing_storage = malloc(ANIMATION_STORAGE_ARENA_SIZE);
+ // // We'll store data on this arena so we can easily free it all at once later
+ // out_model->animation_data_arena =
+ // arena_create(animation_backing_storage, ANIMATION_STORAGE_ARENA_SIZE);
+ // arena *arena = &out_model->animation_data_arena;
+
+ // if (!out_model->animations) {
+ // out_model->animations = animation_clip_darray_new(num_animations);
+ // }
+
+ // for (int anim_idx = 0; anim_idx < data->animations_count; anim_idx++) {
+ // cgltf_animation animation = data->animations[anim_idx];
+ // animation_clip clip = { 0 };
+
+ // for (size_t c = 0; c < animation.channels_count; c++) {
+ // cgltf_animation_channel channel = animation.channels[c];
+
+ // animation_sampler *sampler = arena_alloc(arena, sizeof(animation_sampler));
+
+ // animation_sampler **target_property;
+ // keyframe_kind data_type;
+
+ // switch (channel.target_path) {
+ // case cgltf_animation_path_type_rotation:
+ // target_property = &clip.rotation;
+ // data_type = KEYFRAME_ROTATION;
+ // break;
+ // case cgltf_animation_path_type_translation:
+ // target_property = &clip.translation;
+ // data_type = KEYFRAME_TRANSLATION;
+ // break;
+ // case cgltf_animation_path_type_scale:
+ // target_property = &clip.scale;
+ // data_type = KEYFRAME_SCALE;
+ // break;
+ // case cgltf_animation_path_type_weights:
+ // target_property = &clip.weights;
+ // data_type = KEYFRAME_WEIGHTS;
+ // WARN("Morph target weights arent supported yet");
+ // return false;
+ // default:
+ // WARN("unsupported animation type");
+ // return false;
+ // }
+ // *target_property = sampler;
+
+ // sampler->current_index = 0;
+ // printf("1 %d index\n", sampler->current_index);
+ // sampler->animation.interpolation = INTERPOLATION_LINEAR;
+
+ // // keyframe times
+ // size_t n_frames = channel.sampler->input->count;
+ // assert(channel.sampler->input->component_type == cgltf_component_type_r_32f);
+ // // FIXME: CASSERT_MSG function "Expected animation sampler input component to be type
+ // f32
+ // // (keyframe times)");
+ // f32 *times = arena_alloc(arena, n_frames * sizeof(f32));
+ // sampler->animation.n_timestamps = n_frames;
+ // sampler->animation.timestamps = times;
+ // cgltf_accessor_unpack_floats(channel.sampler->input, times, n_frames);
+
+ // assert_path_type_matches_component_type(channel.target_path, channel.sampler->output);
+
+ // // keyframe values
+ // size_t n_values = channel.sampler->output->count;
+ // assert(n_frames == n_values);
+
+ // keyframes keyframes = { 0 };
+ // keyframes.kind = KEYFRAME_ROTATION;
+ // keyframes.count = n_values;
+ // keyframes.values = arena_alloc(arena, n_values * sizeof(keyframe));
+ // for (cgltf_size v = 0; v < channel.sampler->output->count; ++v) {
+ // switch (data_type) {
+ // case KEYFRAME_ROTATION: {
+ // quat rot;
+ // cgltf_accessor_read_float(channel.sampler->output, v, &rot.x, 4);
+ // // printf("Quat %f %f %f %f\n", rot.x, rot.y, rot.z, rot.w);
+ // keyframes.values[v].rotation = rot;
+ // break;
+ // }
+ // case KEYFRAME_TRANSLATION: {
+ // vec3 trans;
+ // cgltf_accessor_read_float(channel.sampler->output, v, &trans.x, 3);
+ // keyframes.values[v].translation = trans;
+ // break;
+ // }
+ // case KEYFRAME_SCALE: {
+ // vec3 scale;
+ // cgltf_accessor_read_float(channel.sampler->output, v, &scale.x, 3);
+ // keyframes.values[v].scale = scale;
+ // break;
+ // }
+ // case KEYFRAME_WEIGHTS: {
+ // // TODO
+ // break;
+ // }
+ // }
+ // }
+ // sampler->animation.values = keyframes;
+
+ // sampler->min = channel.sampler->input->min[0];
+ // sampler->max = channel.sampler->input->max[0];
+
+ // // clip.rotation = sampler;
+ // // printf("%d timestamps\n", sampler->animation.n_timestamps);
+ // // printf("%d index\n", sampler->current_index);
+ // }
+
+ // WARN("stuff %ld", clip.rotation->animation.n_timestamps);
+ // animation_clip_darray_push(out_model->animations, clip);
+ // }
+ // }
+
+ // return true;
}
/*
diff --git a/src/resources/obj.c b/src/resources/obj.c
index ea73ffa..888e16e 100644
--- a/src/resources/obj.c
+++ b/src/resources/obj.c
@@ -18,7 +18,7 @@
#include "mem.h"
#include "path.h"
#include "render.h"
-#include "render_backend.h"
+// #include "render_backend.h"
#include "render_types.h"
#include "str.h"
@@ -55,7 +55,7 @@ model_handle model_load_obj(core *core, const char *path, bool invert_textures_y
model model = { 0 };
model.name = str8_cstr_view(path);
model.meshes = mesh_darray_new(1);
- model.materials = material_darray_new(1);
+ // model.materials = material_darray_new(1);
bool success = model_load_obj_str(file_string, relative_path.path, &model, invert_textures_y);
@@ -76,151 +76,157 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_
bool invert_textures_y) {
TRACE("Load OBJ from string");
- // Setup temps
- vec3_darray *tmp_positions = vec3_darray_new(1000);
- vec3_darray *tmp_normals = vec3_darray_new(1000);
- vec2_darray *tmp_uvs = vec2_darray_new(1000);
- face_darray *tmp_faces = face_darray_new(1000);
- // TODO: In the future I'd like these temporary arrays to be allocated from an arena provided
- // by the function one level up, model_load_obj. That way we can just `return false;` anywhere in
- // this code to indicate an error, and be sure that all that memory will be cleaned up without
- // having to call vec3_darray_free in every single error case before returning.
-
- // Other state
- bool object_set = false;
- bool material_loaded = false;
- char current_material_name[64];
-
- char *pch;
- char *rest = file_string;
- pch = strtok_r((char *)file_string, "\n", &rest);
-
- int line_num = 0;
- char last_char_type = 'a';
-
- while (pch != NULL) {
- line_num++;
- char line_header[128];
- int offset = 0;
-
- // skip whitespace
- char *p = pch;
-
- skip_space(pch);
-
- if (*p == '\0') {
- /* the string is empty */
- } else {
- // read the first word of the line
- int res = sscanf(pch, "%s %n", line_header, &offset);
- /* printf("header: %s, offset : %d res: %d\n",line_header, offset, res); */
- if (res != 1) {
- break;
- }
-
- if (strcmp(line_header, "o") == 0 || strcmp(line_header, "g") == 0) {
- // if we're currently parsing one
- if (!object_set) {
- object_set = true;
- } else {
- create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
- out_model->materials, material_loaded, current_material_name);
- object_set = false;
- }
- } else if (strcmp(line_header, "v") == 0) {
- // special logic: if we went from faces back to vertices trigger a mesh output.
- // PS: I hate OBJ
- if (last_char_type == 'f') {
- create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
- out_model->materials, material_loaded, current_material_name);
- object_set = false;
- }
-
- last_char_type = 'v';
- vec3 vertex;
- sscanf(pch + offset, "%f %f %f", &vertex.x, &vertex.y, &vertex.z);
-
- vec3_darray_push(tmp_positions, vertex);
- } else if (strcmp(line_header, "vt") == 0) {
- last_char_type = 't';
- vec2 uv;
- char copy[1024];
- memcpy(copy, pch + offset, strlen(pch + offset) + 1);
- char *p = pch + offset;
- while (isspace((unsigned char)*p)) ++p;
-
- // I can't remember what is going on here
- memset(copy, 0, 1024);
- memcpy(copy, pch + offset, strlen(pch + offset) + 1);
- int res = sscanf(copy, "%f %f", &uv.x, &uv.y);
- memset(copy, 0, 1024);
- memcpy(copy, pch + offset, strlen(pch + offset) + 1);
- if (res != 1) {
- // da frick? some .obj files have 3 uvs instead of 2
- f32 dummy;
- int res2 = sscanf(copy, "%f %f %f", &uv.x, &uv.y, &dummy);
- }
-
- if (invert_textures_y) {
- uv.y = -uv.y; // flip Y axis to be consistent with how other PNGs are being handled
- // `texture_load` will flip it again
- }
- vec2_darray_push(tmp_uvs, uv);
- } else if (strcmp(line_header, "vn") == 0) {
- last_char_type = 'n';
- vec3 normal;
- sscanf(pch + offset, "%f %f %f", &normal.x, &normal.y, &normal.z);
- vec3_darray_push(tmp_normals, normal);
- } else if (strcmp(line_header, "f") == 0) {
- last_char_type = 'f';
- struct face f;
- sscanf(pch + offset, "%d/%d/%d %d/%d/%d %d/%d/%d", &f.vertex_indices[0], &f.uv_indices[0],
- &f.normal_indices[0], &f.vertex_indices[1], &f.uv_indices[1], &f.normal_indices[1],
- &f.vertex_indices[2], &f.uv_indices[2], &f.normal_indices[2]);
- // printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", f.vertex_indices[0], f.uv_indices[0],
- // f.normal_indices[0],
- // f.vertex_indices[1], f.uv_indices[1], f.normal_indices[1],
- // f.vertex_indices[2], f.uv_indices[2], f.normal_indices[2]);
- face_darray_push(tmp_faces, f);
- } else if (strcmp(line_header, "mtllib") == 0) {
- char filename[1024];
- sscanf(pch + offset, "%s", filename);
- char mtllib_path[1024];
- snprintf(mtllib_path, sizeof(mtllib_path), "%s/%s", relative_path.buf, filename);
- if (!load_material_lib(mtllib_path, relative_path, out_model->materials)) {
- ERROR("couldnt load material lib");
- return false;
- }
- } else if (strcmp(line_header, "usemtl") == 0) {
- material_loaded = true;
- sscanf(pch + offset, "%s", current_material_name);
- }
- }
-
- pch = strtok_r(NULL, "\n", &rest);
- }
-
- // last mesh or if one wasnt created with 'o' directive
- if (face_darray_len(tmp_faces) > 0) {
- TRACE("Last leftover mesh");
- create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
- out_model->materials, material_loaded, current_material_name);
- }
-
- // Free data
- free((char *)file_string);
- vec3_darray_free(tmp_positions);
- vec3_darray_free(tmp_normals);
- vec2_darray_free(tmp_uvs);
- face_darray_free(tmp_faces);
- TRACE("Freed temporary OBJ loading data");
-
- if (mesh_darray_len(out_model->meshes) > 256) {
- printf("num meshes: %ld\n", mesh_darray_len(out_model->meshes));
- }
-
- // TODO: bounding box calculation for each mesh
- // TODO: bounding box calculation for model
+ // // Setup temps
+ // vec3_darray *tmp_positions = vec3_darray_new(1000);
+ // vec3_darray *tmp_normals = vec3_darray_new(1000);
+ // vec2_darray *tmp_uvs = vec2_darray_new(1000);
+ // face_darray *tmp_faces = face_darray_new(1000);
+ // // TODO: In the future I'd like these temporary arrays to be allocated from an arena provided
+ // // by the function one level up, model_load_obj. That way we can just `return false;` anywhere
+ // in
+ // // this code to indicate an error, and be sure that all that memory will be cleaned up without
+ // // having to call vec3_darray_free in every single error case before returning.
+
+ // // Other state
+ // bool object_set = false;
+ // bool material_loaded = false;
+ // char current_material_name[64];
+
+ // char *pch;
+ // char *rest = file_string;
+ // pch = strtok_r((char *)file_string, "\n", &rest);
+
+ // int line_num = 0;
+ // char last_char_type = 'a';
+
+ // while (pch != NULL) {
+ // line_num++;
+ // char line_header[128];
+ // int offset = 0;
+
+ // // skip whitespace
+ // char *p = pch;
+
+ // skip_space(pch);
+
+ // if (*p == '\0') {
+ // /* the string is empty */
+ // } else {
+ // // read the first word of the line
+ // int res = sscanf(pch, "%s %n", line_header, &offset);
+ // /* printf("header: %s, offset : %d res: %d\n",line_header, offset, res); */
+ // if (res != 1) {
+ // break;
+ // }
+
+ // if (strcmp(line_header, "o") == 0 || strcmp(line_header, "g") == 0) {
+ // // if we're currently parsing one
+ // if (!object_set) {
+ // object_set = true;
+ // } else {
+ // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
+ // NULL, // out_model->materials,
+ // material_loaded, current_material_name);
+ // object_set = false;
+ // }
+ // } else if (strcmp(line_header, "v") == 0) {
+ // // special logic: if we went from faces back to vertices trigger a mesh output.
+ // // PS: I hate OBJ
+ // if (last_char_type == 'f') {
+ // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
+ // NULL, // FIXME: out_model->materials,
+ // material_loaded, current_material_name);
+ // object_set = false;
+ // }
+
+ // last_char_type = 'v';
+ // vec3 vertex;
+ // sscanf(pch + offset, "%f %f %f", &vertex.x, &vertex.y, &vertex.z);
+
+ // vec3_darray_push(tmp_positions, vertex);
+ // } else if (strcmp(line_header, "vt") == 0) {
+ // last_char_type = 't';
+ // vec2 uv;
+ // char copy[1024];
+ // memcpy(copy, pch + offset, strlen(pch + offset) + 1);
+ // char *p = pch + offset;
+ // while (isspace((unsigned char)*p)) ++p;
+
+ // // I can't remember what is going on here
+ // memset(copy, 0, 1024);
+ // memcpy(copy, pch + offset, strlen(pch + offset) + 1);
+ // int res = sscanf(copy, "%f %f", &uv.x, &uv.y);
+ // memset(copy, 0, 1024);
+ // memcpy(copy, pch + offset, strlen(pch + offset) + 1);
+ // if (res != 1) {
+ // // da frick? some .obj files have 3 uvs instead of 2
+ // f32 dummy;
+ // int res2 = sscanf(copy, "%f %f %f", &uv.x, &uv.y, &dummy);
+ // }
+
+ // if (invert_textures_y) {
+ // uv.y = -uv.y; // flip Y axis to be consistent with how other PNGs are being handled
+ // // `texture_load` will flip it again
+ // }
+ // vec2_darray_push(tmp_uvs, uv);
+ // } else if (strcmp(line_header, "vn") == 0) {
+ // last_char_type = 'n';
+ // vec3 normal;
+ // sscanf(pch + offset, "%f %f %f", &normal.x, &normal.y, &normal.z);
+ // vec3_darray_push(tmp_normals, normal);
+ // } else if (strcmp(line_header, "f") == 0) {
+ // last_char_type = 'f';
+ // struct face f;
+ // sscanf(pch + offset, "%d/%d/%d %d/%d/%d %d/%d/%d", &f.vertex_indices[0],
+ // &f.uv_indices[0],
+ // &f.normal_indices[0], &f.vertex_indices[1], &f.uv_indices[1],
+ // &f.normal_indices[1], &f.vertex_indices[2], &f.uv_indices[2],
+ // &f.normal_indices[2]);
+ // // printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", f.vertex_indices[0], f.uv_indices[0],
+ // // f.normal_indices[0],
+ // // f.vertex_indices[1], f.uv_indices[1], f.normal_indices[1],
+ // // f.vertex_indices[2], f.uv_indices[2], f.normal_indices[2]);
+ // face_darray_push(tmp_faces, f);
+ // } else if (strcmp(line_header, "mtllib") == 0) {
+ // char filename[1024];
+ // sscanf(pch + offset, "%s", filename);
+ // char mtllib_path[1024];
+ // snprintf(mtllib_path, sizeof(mtllib_path), "%s/%s", relative_path.buf, filename);
+ // if (!load_material_lib(mtllib_path, relative_path, out_model->materials)) {
+ // ERROR("couldnt load material lib");
+ // return false;
+ // }
+ // } else if (strcmp(line_header, "usemtl") == 0) {
+ // material_loaded = true;
+ // sscanf(pch + offset, "%s", current_material_name);
+ // }
+ // }
+
+ // pch = strtok_r(NULL, "\n", &rest);
+ // }
+
+ // // last mesh or if one wasnt created with 'o' directive
+ // if (face_darray_len(tmp_faces) > 0) {
+ // TRACE("Last leftover mesh");
+ // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces,
+ // NULL, // TODO: out_model->materials,
+ // material_loaded, current_material_name);
+ // }
+
+ // // Free data
+ // free((char *)file_string);
+ // vec3_darray_free(tmp_positions);
+ // vec3_darray_free(tmp_normals);
+ // vec2_darray_free(tmp_uvs);
+ // face_darray_free(tmp_faces);
+ // TRACE("Freed temporary OBJ loading data");
+
+ // if (mesh_darray_len(out_model->meshes) > 256) {
+ // printf("num meshes: %ld\n", mesh_darray_len(out_model->meshes));
+ // }
+
+ // // TODO: bounding box calculation for each mesh
+ // // TODO: bounding box calculation for model
return true;
}
@@ -232,158 +238,159 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_
void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray *tmp_normals,
vec2_darray *tmp_uvs, face_darray *tmp_faces, material_darray *materials,
bool material_loaded, char current_material_name[256]) {
- size_t num_verts = face_darray_len(tmp_faces) * 3;
- vertex_darray *out_vertices = vertex_darray_new(num_verts);
-
- face_darray_iter face_iter = face_darray_iter_new(tmp_faces);
- struct face *f;
-
- while ((f = face_darray_iter_next(&face_iter))) {
- for (int j = 0; j < 3; j++) {
- vertex vert = { 0 };
- vert.position = tmp_positions->data[f->vertex_indices[j] - 1];
- if (vec3_darray_len(tmp_normals) == 0) {
- vert.normal = vec3_create(0.0, 0.0, 0.0);
- } else {
- vert.normal = tmp_normals->data[f->normal_indices[j] - 1];
- }
- vert.uv = tmp_uvs->data[f->uv_indices[j] - 1];
- vertex_darray_push(out_vertices, vert);
- }
- }
-
- DEBUG("Loaded submesh\n vertices: %zu\n uvs: %zu\n normals: %zu\n faces: %zu",
- vec3_darray_len(tmp_positions), vec2_darray_len(tmp_uvs), vec3_darray_len(tmp_normals),
- face_darray_len(tmp_faces));
-
- // Clear current object faces
- face_darray_clear(tmp_faces);
-
- mesh m = { .vertices = out_vertices };
- if (material_loaded) {
- // linear scan to find material
- bool found = false;
- DEBUG("Num of materials : %ld", material_darray_len(materials));
- material_darray_iter mat_iter = material_darray_iter_new(materials);
- blinn_phong_material *cur_material;
- while ((cur_material = material_darray_iter_next(&mat_iter))) {
- if (strcmp(cur_material->name, current_material_name) == 0) {
- DEBUG("Found match");
- m.material_index = mat_iter.current_idx - 1;
- found = true;
- break;
- }
- }
-
- if (!found) {
- // TODO: default material
- m.material_index = 0;
- DEBUG("Set default material");
- }
- }
- mesh_darray_push(meshes, m);
+ // size_t num_verts = face_darray_len(tmp_faces) * 3;
+ // vertex_darray *out_vertices = vertex_darray_new(num_verts);
+
+ // face_darray_iter face_iter = face_darray_iter_new(tmp_faces);
+ // struct face *f;
+
+ // while ((f = face_darray_iter_next(&face_iter))) {
+ // for (int j = 0; j < 3; j++) {
+ // vertex vert = { 0 };
+ // vert.position = tmp_positions->data[f->vertex_indices[j] - 1];
+ // if (vec3_darray_len(tmp_normals) == 0) {
+ // vert.normal = vec3_create(0.0, 0.0, 0.0);
+ // } else {
+ // vert.normal = tmp_normals->data[f->normal_indices[j] - 1];
+ // }
+ // vert.uv = tmp_uvs->data[f->uv_indices[j] - 1];
+ // vertex_darray_push(out_vertices, vert);
+ // }
+ // }
+
+ // DEBUG("Loaded submesh\n vertices: %zu\n uvs: %zu\n normals: %zu\n faces: %zu",
+ // vec3_darray_len(tmp_positions), vec2_darray_len(tmp_uvs), vec3_darray_len(tmp_normals),
+ // face_darray_len(tmp_faces));
+
+ // // Clear current object faces
+ // face_darray_clear(tmp_faces);
+
+ // mesh m = { .vertices = out_vertices };
+ // if (material_loaded) {
+ // // linear scan to find material
+ // bool found = false;
+ // DEBUG("Num of materials : %ld", material_darray_len(materials));
+ // material_darray_iter mat_iter = material_darray_iter_new(materials);
+ // blinn_phong_material *cur_material;
+ // while ((cur_material = material_darray_iter_next(&mat_iter))) {
+ // if (strcmp(cur_material->name, current_material_name) == 0) {
+ // DEBUG("Found match");
+ // m.material_index = mat_iter.current_idx - 1;
+ // found = true;
+ // break;
+ // }
+ // }
+
+ // if (!found) {
+ // // TODO: default material
+ // m.material_index = 0;
+ // DEBUG("Set default material");
+ // }
+ // }
+ // mesh_darray_push(meshes, m);
}
bool load_material_lib(const char *path, str8 relative_path, material_darray *materials) {
TRACE("BEGIN load material lib at %s", path);
- const char *file_string = string_from_file(path);
- if (file_string == NULL) {
- ERROR("couldnt load %s", path);
- return false;
- }
-
- char *pch;
- char *saveptr;
- pch = strtok_r((char *)file_string, "\n", &saveptr);
-
- material current_material = DEFAULT_MATERIAL;
-
- bool material_set = false;
-
- while (pch != NULL) {
- char line_header[128];
- int offset = 0;
- // read the first word of the line
- int res = sscanf(pch, "%s %n", line_header, &offset);
- if (res != 1) {
- break;
- }
-
- // When we see "newmtl", start a new material, or flush the previous one
- if (strcmp(line_header, "newmtl") == 0) {
- if (material_set) {
- // a material was being parsed, so flush that one and start a new one
- material_darray_push(materials, current_material);
- DEBUG("pushed material with name %s", current_material.name);
- WARN("Reset current material");
- current_material = DEFAULT_MATERIAL;
- } else {
- material_set = true;
- }
- // scan the new material name
- char material_name[64];
- sscanf(pch + offset, "%s", current_material.name);
- DEBUG("material name %s\n", current_material.name);
- // current_material.name = material_name;
- } else if (strcmp(line_header, "Ka") == 0) {
- // ambient
- sscanf(pch + offset, "%f %f %f", &current_material.ambient_colour.x,
- &current_material.ambient_colour.y, &current_material.ambient_colour.z);
- } else if (strcmp(line_header, "Kd") == 0) {
- // diffuse
- sscanf(pch + offset, "%f %f %f", &current_material.diffuse.x, &current_material.diffuse.y,
- &current_material.diffuse.z);
- } else if (strcmp(line_header, "Ks") == 0) {
- // specular
- sscanf(pch + offset, "%f %f %f", &current_material.specular.x, &current_material.specular.y,
- &current_material.specular.z);
- } else if (strcmp(line_header, "Ns") == 0) {
- // specular exponent
- sscanf(pch + offset, "%f", &current_material.spec_exponent);
- } else if (strcmp(line_header, "map_Kd") == 0) {
- char diffuse_map_filename[1024];
- sscanf(pch + offset, "%s", diffuse_map_filename);
- char diffuse_map_path[1024];
- snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf,
- diffuse_map_filename);
- printf("load from %s\n", diffuse_map_path);
-
- // --------------
- texture diffuse_texture = texture_data_load(diffuse_map_path, true);
- current_material.diffuse_texture = diffuse_texture;
- strcpy(current_material.diffuse_tex_path, diffuse_map_path);
- texture_data_upload(&current_material.diffuse_texture);
- // --------------
- } else if (strcmp(line_header, "map_Ks") == 0) {
- // char specular_map_path[1024] = "assets/";
- // sscanf(pch + offset, "%s", specular_map_path + 7);
- char specular_map_filename[1024];
- sscanf(pch + offset, "%s", specular_map_filename);
- char specular_map_path[1024];
- snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf,
- specular_map_filename);
- printf("load from %s\n", specular_map_path);
- // --------------
- texture specular_texture = texture_data_load(specular_map_path, true);
- current_material.specular_texture = specular_texture;
- strcpy(current_material.specular_tex_path, specular_map_path);
- texture_data_upload(&current_material.specular_texture);
- // --------------
- } else if (strcmp(line_header, "map_Bump") == 0) {
- // TODO
- }
-
- pch = strtok_r(NULL, "\n", &saveptr);
- }
-
- TRACE("end load material lib");
-
- // last mesh or if one wasnt created with 'o' directive
- // TRACE("Last leftover material");
- material_darray_push(materials, current_material);
-
- INFO("Loaded %ld materials", material_darray_len(materials));
+ // const char *file_string = string_from_file(path);
+ // if (file_string == NULL) {
+ // ERROR("couldnt load %s", path);
+ // return false;
+ // }
+
+ // char *pch;
+ // char *saveptr;
+ // pch = strtok_r((char *)file_string, "\n", &saveptr);
+
+ // material current_material = DEFAULT_MATERIAL;
+
+ // bool material_set = false;
+
+ // while (pch != NULL) {
+ // char line_header[128];
+ // int offset = 0;
+ // // read the first word of the line
+ // int res = sscanf(pch, "%s %n", line_header, &offset);
+ // if (res != 1) {
+ // break;
+ // }
+
+ // // When we see "newmtl", start a new material, or flush the previous one
+ // if (strcmp(line_header, "newmtl") == 0) {
+ // if (material_set) {
+ // // a material was being parsed, so flush that one and start a new one
+ // material_darray_push(materials, current_material);
+ // DEBUG("pushed material with name %s", current_material.name);
+ // WARN("Reset current material");
+ // current_material = DEFAULT_MATERIAL;
+ // } else {
+ // material_set = true;
+ // }
+ // // scan the new material name
+ // char material_name[64];
+ // sscanf(pch + offset, "%s", current_material.name);
+ // DEBUG("material name %s\n", current_material.name);
+ // // current_material.name = material_name;
+ // } else if (strcmp(line_header, "Ka") == 0) {
+ // // ambient
+ // sscanf(pch + offset, "%f %f %f", &current_material.ambient_colour.x,
+ // &current_material.ambient_colour.y, &current_material.ambient_colour.z);
+ // } else if (strcmp(line_header, "Kd") == 0) {
+ // // diffuse
+ // sscanf(pch + offset, "%f %f %f", &current_material.diffuse.x, &current_material.diffuse.y,
+ // &current_material.diffuse.z);
+ // } else if (strcmp(line_header, "Ks") == 0) {
+ // // specular
+ // sscanf(pch + offset, "%f %f %f", &current_material.specular.x,
+ // &current_material.specular.y,
+ // &current_material.specular.z);
+ // } else if (strcmp(line_header, "Ns") == 0) {
+ // // specular exponent
+ // sscanf(pch + offset, "%f", &current_material.spec_exponent);
+ // } else if (strcmp(line_header, "map_Kd") == 0) {
+ // char diffuse_map_filename[1024];
+ // sscanf(pch + offset, "%s", diffuse_map_filename);
+ // char diffuse_map_path[1024];
+ // snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf,
+ // diffuse_map_filename);
+ // printf("load from %s\n", diffuse_map_path);
+
+ // // --------------
+ // texture diffuse_texture = texture_data_load(diffuse_map_path, true);
+ // current_material.diffuse_texture = diffuse_texture;
+ // strcpy(current_material.diffuse_tex_path, diffuse_map_path);
+ // texture_data_upload(&current_material.diffuse_texture);
+ // // --------------
+ // } else if (strcmp(line_header, "map_Ks") == 0) {
+ // // char specular_map_path[1024] = "assets/";
+ // // sscanf(pch + offset, "%s", specular_map_path + 7);
+ // char specular_map_filename[1024];
+ // sscanf(pch + offset, "%s", specular_map_filename);
+ // char specular_map_path[1024];
+ // snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf,
+ // specular_map_filename);
+ // printf("load from %s\n", specular_map_path);
+ // // --------------
+ // texture specular_texture = texture_data_load(specular_map_path, true);
+ // current_material.specular_texture = specular_texture;
+ // strcpy(current_material.specular_tex_path, specular_map_path);
+ // texture_data_upload(&current_material.specular_texture);
+ // // --------------
+ // } else if (strcmp(line_header, "map_Bump") == 0) {
+ // // TODO
+ // }
+
+ // pch = strtok_r(NULL, "\n", &saveptr);
+ // }
+
+ // TRACE("end load material lib");
+
+ // // last mesh or if one wasnt created with 'o' directive
+ // // TRACE("Last leftover material");
+ // material_darray_push(materials, current_material);
+
+ // INFO("Loaded %ld materials", material_darray_len(materials));
TRACE("END load material lib");
return true;
}
diff --git a/xmake.lua b/xmake.lua
index a5e6239..0fc042c 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -1,6 +1,6 @@
set_project("celeritas")
set_version("0.1.0")
-set_config("cc", "gcc")
+set_config("cc", "clang")
add_rules("mode.debug", "mode.release") -- we have two modes: debug & release
@@ -25,7 +25,7 @@ if is_plat("linux") then
elseif is_plat("windows") then
add_defines("CEL_PLATFORM_WINDOWS")
add_syslinks("user32", "gdi32", "kernel32", "shell32")
- add_links("pthreadVC2-w64")
+ -- add_links("pthreadVC2-w64")
elseif is_plat("macosx") then
add_defines("CEL_PLATFORM_MAC")
add_frameworks("Cocoa", "IOKit", "CoreVideo", "OpenGL")
@@ -54,11 +54,10 @@ add_requires("local_glfw")
local core_sources = {
"deps/glad/src/glad.c",
"src/*.c",
- "src/logos/*.c",
+ -- "src/logos/*.c",
"src/platform/*.c",
"src/renderer/*.c",
"src/renderer/backends/*.c",
- "src/renderer/cleanroom/*.c",
"src/resources/*.c",
"src/std/*.c",
"src/std/containers/*.c",
@@ -96,12 +95,12 @@ target("core_config")
add_includedirs("deps/stb_image_write", {public = true})
add_includedirs("deps/stb_truetype", {public = true})
add_includedirs("src/", {public = true})
- add_includedirs("src/logos/", {public = true})
+ -- add_includedirs("src/logos/", {public = true})
add_includedirs("src/maths/", {public = true})
add_includedirs("src/platform/", {public = true})
add_includedirs("src/renderer/", {public = true})
add_includedirs("src/renderer/backends/", {public = true})
- add_includedirs("src/renderer/cleanroom/", {public = true})
+ -- add_includedirs("src/renderer/cleanroom/", {public = true})
add_includedirs("src/resources/", {public = true})
add_includedirs("src/std/", {public = true})
add_includedirs("src/std/containers", {public = true})
@@ -133,75 +132,75 @@ target("core_shared")
if is_plat("windows") then
add_links("msvcrt", "legacy_stdio_definitions") -- for release builds
add_links("msvcrtd", "legacy_stdio_definitions") -- for debug builds
- add_links("pthreadVC2-w64")
+ -- add_links("pthreadVC2-w64")
end
target("main_loop")
set_kind("binary")
set_group("examples")
- add_deps("core_shared")
- add_files("examples/main_loop/ex_main_loop.c")
- set_rundir("$(projectdir)")
-
-target("std")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/standard_lib/ex_std.c")
- set_rundir("$(projectdir)")
-
-target("obj")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/obj_loading/ex_obj_loading.c")
- set_rundir("$(projectdir)")
-
-target("input")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/input/ex_input.c")
- set_rundir("$(projectdir)")
-
-target("gltf")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/gltf_loading/ex_gltf_loading.c")
- set_rundir("$(projectdir)")
-
-target("transforms")
- set_kind("binary")
- set_group("examples")
- add_deps("core_shared")
- add_files("examples/transforms/ex_transforms.c")
- set_rundir("$(projectdir)")
-
-target("animation")
- set_kind("binary")
- set_group("examples")
- add_deps("core_shared")
- add_files("examples/property_animation/ex_property_animation.c")
- set_rundir("$(projectdir)")
-
-target("skinned")
- set_kind("binary")
- set_group("examples")
- add_deps("core_shared")
- add_files("examples/skinned_animation/ex_skinned_animation.c")
- set_rundir("$(projectdir)")
-
-target("input")
- set_kind("binary")
- set_group("examples")
add_deps("core_static")
- add_files("examples/input/ex_input.c")
+ add_files("examples/main_loop/ex_main_loop.c")
set_rundir("$(projectdir)")
-target("demo")
- set_kind("binary")
- set_group("examples")
- add_deps("core_static")
- add_files("examples/demo/demo.c")
- set_rundir("$(projectdir)")
+-- target("std")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/standard_lib/ex_std.c")
+-- set_rundir("$(projectdir)")
+
+-- target("obj")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/obj_loading/ex_obj_loading.c")
+-- set_rundir("$(projectdir)")
+
+-- target("input")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/input/ex_input.c")
+-- set_rundir("$(projectdir)")
+
+-- target("gltf")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/gltf_loading/ex_gltf_loading.c")
+-- set_rundir("$(projectdir)")
+
+-- target("transforms")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_shared")
+-- add_files("examples/transforms/ex_transforms.c")
+-- set_rundir("$(projectdir)")
+
+-- target("animation")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_shared")
+-- add_files("examples/property_animation/ex_property_animation.c")
+-- set_rundir("$(projectdir)")
+
+-- target("skinned")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_shared")
+-- add_files("examples/skinned_animation/ex_skinned_animation.c")
+-- set_rundir("$(projectdir)")
+
+-- target("input")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/input/ex_input.c")
+-- set_rundir("$(projectdir)")
+
+-- target("demo")
+-- set_kind("binary")
+-- set_group("examples")
+-- add_deps("core_static")
+-- add_files("examples/demo/demo.c")
+-- set_rundir("$(projectdir)")