From 99f2476d7bb8479d543f080c209324c77c775737 Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:35:23 +1000 Subject: bring back gltf --- assets/shaders/cube.frag | 8 +- assets/shaders/cube.vert | 4 +- assets/shaders/triangle.frag | 2 +- assets/shaders/triangle.vert | 2 +- examples/gltf_loading/ex_gltf_loading.c | 30 +- src/core.c | 8 + src/core.h | 4 +- src/defines.h | 4 +- src/maths/primitives.c | 2 +- src/renderer/backends/metal/backend_metal.m | 2 +- src/renderer/backends/opengl/backend_opengl.c | 7 +- src/renderer/backends/opengl/backend_opengl.h | 4 + src/renderer/backends/opengl/opengl_helpers.h | 1 + src/renderer/ral_types.h | 1 - src/renderer/render.c | 48 ++-- src/renderer/render.h | 19 ++ src/renderer/render_types.h | 42 +-- src/resources/gltf.c | 376 ++++++++++++++------------ src/resources/loaders.h | 4 +- src/resources/obj.c | 5 +- src/systems/terrain.h | 2 +- src/transform_hierarchy.c | 5 +- xmake.lua | 12 +- 23 files changed, 334 insertions(+), 258 deletions(-) diff --git a/assets/shaders/cube.frag b/assets/shaders/cube.frag index 02cb9b3..21d7b55 100644 --- a/assets/shaders/cube.frag +++ b/assets/shaders/cube.frag @@ -1,14 +1,14 @@ -#version 430 +#version 410 layout(location = 0) in vec3 fragColor; layout(location = 1) in vec2 fragTexCoord; -layout(binding = 1) uniform sampler2D texSampler; + uniform sampler2D texSampler; // uniform sampler2D texSampler; layout(location = 0) out vec4 outColor; void main() { - outColor = texture(texSampler, fragTexCoord); // vec4(fragTexCoord, 0.0); - // outColor = vec4(fragColor, 1.0); + // outColor = texture(texSampler, fragTexCoord); // vec4(fragTexCoord, 0.0); + outColor = vec4(fragColor, 1.0); } diff --git a/assets/shaders/cube.vert b/assets/shaders/cube.vert index 2f81e9c..2ccab09 100644 --- a/assets/shaders/cube.vert +++ b/assets/shaders/cube.vert @@ -1,6 +1,6 @@ -#version 430 +#version 410 -layout( binding = 0) uniform Matrices { +uniform Matrices { mat4 model; mat4 view; mat4 proj; diff --git a/assets/shaders/triangle.frag b/assets/shaders/triangle.frag index ad6de8e..3ae1fc4 100644 --- a/assets/shaders/triangle.frag +++ b/assets/shaders/triangle.frag @@ -1,4 +1,4 @@ -#version 430 +#version 410 layout(location = 0) in vec3 fragColor; layout(location = 0) out vec4 outColor; diff --git a/assets/shaders/triangle.vert b/assets/shaders/triangle.vert index f98696c..45b4907 100644 --- a/assets/shaders/triangle.vert +++ b/assets/shaders/triangle.vert @@ -1,4 +1,4 @@ -#version 430 +#version 410 layout(location = 0) in vec2 inPos; layout(location = 1) in vec3 inColor; diff --git a/examples/gltf_loading/ex_gltf_loading.c b/examples/gltf_loading/ex_gltf_loading.c index fa74ada..e7f84ff 100644 --- a/examples/gltf_loading/ex_gltf_loading.c +++ b/examples/gltf_loading/ex_gltf_loading.c @@ -10,6 +10,10 @@ #include "render.h" #include "render_types.h" +extern core g_core; + +#define MODEL_GET(h) (model_pool_get(&g_core.models, h)) + const vec3 pointlight_positions[4] = { { 0.7, 0.2, 2.0 }, { 2.3, -3.3, -4.0 }, @@ -23,12 +27,12 @@ int main() { double lastFrame = currentFrame; double deltaTime; - core* core = core_bringup(); + core_bringup(); model_handle helmet_handle = - model_load_gltf(core, "assets/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", false); - model* helmet = &core->models->data[helmet_handle.raw]; - model_upload_meshes(&core->renderer, helmet); + model_load_gltf("assets/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", false); + INFO("GLTF loaded successfully!"); + model* helmet = MODEL_GET(helmet_handle); vec3 camera_pos = vec3(5., 0., 0.); vec3 camera_front = vec3_normalise(vec3_negate(camera_pos)); @@ -51,16 +55,17 @@ int main() { point_lights[i].quadratic = 0.032; } - scene our_scene = { .dir_light = dir_light, .n_point_lights = 4 }; - memcpy(&our_scene.point_lights, &point_lights, sizeof(point_light[4])); + // scene our_scene = { .dir_light = dir_light, .n_point_lights = 4 }; + // memcpy(&our_scene.point_lights, &point_lights, sizeof(point_light[4])); + + while (!should_exit(&g_core)) { + input_update(&g_core.input); - while (!should_exit(core)) { currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; - input_update(&core->input); - render_frame_begin(&core->renderer); + render_frame_begin(&g_core.renderer); // Draw the model static f32 angle = 0.0; @@ -69,10 +74,13 @@ int main() { angle += (rot_speed * deltaTime); transform model_tf = transform_create(vec3(0.0, 0.1, -0.1), rot, 1.8); mat4 model = transform_to_mat(&model_tf); - draw_model(&core->renderer, &cam, helmet, &model, &our_scene); - render_frame_end(&core->renderer); + draw_mesh(&helmet->meshes->data[0], &model); + + render_frame_end(&g_core.renderer); } + renderer_shutdown(&g_core.renderer); + return 0; } diff --git a/src/core.c b/src/core.c index 84c9cae..1d8fe91 100644 --- a/src/core.c +++ b/src/core.c @@ -6,6 +6,7 @@ #include "input.h" #include "keys.h" #include "log.h" +#include "mem.h" #include "render.h" #include "render_types.h" #include "scene.h" @@ -52,6 +53,13 @@ void core_bringup() { } */ + size_t model_data_max = 1024 * 1024 * 1024; + arena model_arena = arena_create(malloc(model_data_max), model_data_max); + + model_pool model_pool = model_pool_create(&model_arena, 256, sizeof(model)); + g_core.models = model_pool; + INFO("Created model pool allocator"); + INFO("Creating default scene"); scene_init(&g_core.default_scene); } diff --git a/src/core.h b/src/core.h index 1031868..89702fd 100644 --- a/src/core.h +++ b/src/core.h @@ -1,6 +1,7 @@ #pragma once #include "input.h" +#include "render_types.h" #include "scene.h" #include "screenspace.h" #include "terrain.h" @@ -19,7 +20,8 @@ typedef struct core { screenspace_state screenspace; // data storage scene default_scene; - model_darray* models; + model_pool models; + // model_darray* models; } core; core* get_global_core(); diff --git a/src/defines.h b/src/defines.h index 9050f25..a35dbf4 100644 --- a/src/defines.h +++ b/src/defines.h @@ -77,6 +77,6 @@ Renderer backend defines: #endif #if defined(CEL_PLATFORM_MAC) -#define CEL_REND_BACKEND_METAL 1 -// #define CEL_REND_BACKEND_OPENGL 1 +// #define CEL_REND_BACKEND_METAL 1 +#define CEL_REND_BACKEND_OPENGL 1 #endif \ No newline at end of file diff --git a/src/maths/primitives.c b/src/maths/primitives.c index b9ec868..c0af140 100644 --- a/src/maths/primitives.c +++ b/src/maths/primitives.c @@ -111,7 +111,7 @@ geometry_data geo_create_cuboid(f32x3 extents) { .format = VERTEX_STATIC_3D, .vertices = vertices, .has_indices = true, - .indices = *indices, // FIXME: make darray methods that return stack allocated struct + .indices = indices, // FIXME: make darray methods that return stack allocated struct .colour = vec3(0, 0, 0), }; diff --git a/src/renderer/backends/metal/backend_metal.m b/src/renderer/backends/metal/backend_metal.m index 0e9399e..4787755 100644 --- a/src/renderer/backends/metal/backend_metal.m +++ b/src/renderer/backends/metal/backend_metal.m @@ -1,5 +1,5 @@ #include -#define CEL_REND_BACKEND_METAL +// #define CEL_REND_BACKEND_METAL #if defined(CEL_REND_BACKEND_METAL) #include #include "ral_types.h" diff --git a/src/renderer/backends/opengl/backend_opengl.c b/src/renderer/backends/opengl/backend_opengl.c index ba9435e..de6b71a 100644 --- a/src/renderer/backends/opengl/backend_opengl.c +++ b/src/renderer/backends/opengl/backend_opengl.c @@ -44,7 +44,7 @@ bool gpu_backend_init(const char* window_name, struct GLFWwindow* window) { resource_pools_init(&context.pool_arena, context.resource_pools); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); @@ -132,7 +132,7 @@ gpu_cmd_encoder gpu_cmd_encoder_create() { void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder) {} void gpu_cmd_encoder_begin(gpu_cmd_encoder encoder) {} void gpu_cmd_encoder_begin_render(gpu_cmd_encoder* encoder, gpu_renderpass* renderpass) { - rgba clear_colour = STONE_900; + rgba clear_colour = STONE_800; glClearColor(clear_colour.r, clear_colour.g, clear_colour.b, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -181,7 +181,8 @@ void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* d glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_buf->size, data->data); } else if (binding.type == SHADER_BINDING_TEXTURE) { gpu_texture* tex = TEXTURE_GET(binding.data.texture.handle); - glActiveTexture(GL_TEXTURE0 + i); + glActiveTexture(GL_TEXTURE0); + // glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, tex->id); } } diff --git a/src/renderer/backends/opengl/backend_opengl.h b/src/renderer/backends/opengl/backend_opengl.h index 348eb41..f3b4eb7 100644 --- a/src/renderer/backends/opengl/backend_opengl.h +++ b/src/renderer/backends/opengl/backend_opengl.h @@ -45,6 +45,10 @@ typedef struct gpu_texture { void *pad } gpu_texture; +typedef struct opengl_support { + +} opengl_support; + u32 shader_create_separate(const char *vert_shader, const char *frag_shader); void uniform_vec3f(u32 program_id, const char *uniform_name, vec3 *value); diff --git a/src/renderer/backends/opengl/opengl_helpers.h b/src/renderer/backends/opengl/opengl_helpers.h index a3c4014..41018cb 100644 --- a/src/renderer/backends/opengl/opengl_helpers.h +++ b/src/renderer/backends/opengl/opengl_helpers.h @@ -43,6 +43,7 @@ static opengl_vertex_attr format_from_vertex_attr(vertex_attrib_type attr) { } static u32 opengl_bindcreate_vao(gpu_buffer* buf, vertex_description desc) { + DEBUG("Vertex format name %s", desc.debug_label); // 1. Bind the buffer glBindBuffer(GL_ARRAY_BUFFER, buf->id.vbo); // 2. Create new VAO diff --git a/src/renderer/ral_types.h b/src/renderer/ral_types.h index f1f7809..f1f261d 100644 --- a/src/renderer/ral_types.h +++ b/src/renderer/ral_types.h @@ -21,7 +21,6 @@ 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); CORE_DEFINE_HANDLE(pipeline_layout_handle); CORE_DEFINE_HANDLE(pipeline_handle); CORE_DEFINE_HANDLE(renderpass_handle); diff --git a/src/renderer/render.c b/src/renderer/render.c index 7833ac9..f9e8ccf 100644 --- a/src/renderer/render.c +++ b/src/renderer/render.c @@ -66,7 +66,7 @@ bool renderer_init(renderer* ren) { // default_material_init(); // Create default rendering pipeline - /* default_pipelines_init(ren); */ + default_pipelines_init(ren); return true; } @@ -86,36 +86,40 @@ void default_pipelines_init(renderer* ren) { ren->default_renderpass = *renderpass; printf("Load shaders\n"); - str8 vert_path = str8lit("build/linux/x86_64/debug/triangle.vert.spv"); - str8 frag_path = str8lit("build/linux/x86_64/debug/triangle.frag.spv"); - /* str8 vert_path = - * str8lit("/home/void/code/celeritas-engine/celeritas-core/build/linux/x86_64/debug/triangle.vert.spv"); - */ - /* str8 frag_path = - * str8lit("/home/void/code/celeritas-engine/celeritas-core/build/linux/x86_64/debug/triangle.frag.spv"); - */ + str8 vert_path, frag_path; +#ifdef CEL_REND_BACKEND_OPENGL + vert_path = str8lit("assets/shaders/cube.vert"); + frag_path = str8lit("assets/shaders/cube.frag"); +#else + vert_path = str8lit("build/linux/x86_64/debug/cube.vert.spv"); + frag_path = str8lit("build/linux/x86_64/debug/cube.frag.spv"); +#endif str8_opt vertex_shader = str8_from_file(&scratch, vert_path); str8_opt fragment_shader = str8_from_file(&scratch, frag_path); if (!vertex_shader.has_value || !fragment_shader.has_value) { ERROR_EXIT("Failed to load shaders from disk") } + if (!vertex_shader.has_value || !fragment_shader.has_value) { + ERROR_EXIT("Failed to load shaders from disk") + } - vertex_description vertex_input; + vertex_description vertex_input = {0}; vertex_input.debug_label = "Standard Static 3D Vertex Format"; vertex_desc_add(&vertex_input, "inPosition", ATTR_F32x3); vertex_desc_add(&vertex_input, "inNormal", ATTR_F32x3); vertex_desc_add(&vertex_input, "inTexCoords", ATTR_F32x2); + vertex_input.use_full_vertex_size = true; struct graphics_pipeline_desc pipeline_description = { .debug_name = "Basic Pipeline", .vertex_desc = vertex_input, // .data_layouts // .data_layouts_count - .vs = { .debug_name = "Triangle Vertex Shader", + .vs = { .debug_name = "Basic Vertex Shader", .filepath = vert_path, .code = vertex_shader.contents, .is_spirv = true }, - .fs = { .debug_name = "Triangle Fragment Shader", + .fs = { .debug_name = "Basic Fragment Shader", .filepath = frag_path, .code = fragment_shader.contents, .is_spirv = true }, @@ -153,16 +157,20 @@ void render_frame_end(renderer* ren) { } void render_frame_draw(renderer* ren) {} +bool mesh_has_indices(mesh* m) { + return m->geometry->has_indices; +} + void draw_mesh(mesh* mesh, mat4* model) { // , mat4* view, mat4* proj) { gpu_cmd_encoder* enc = gpu_get_default_cmd_encoder(); encode_set_vertex_buffer(enc, mesh->vertex_buffer); - if (mesh->has_indices) { + if (mesh_has_indices(mesh)) { encode_set_index_buffer(enc, mesh->index_buffer); } // Assume this has already been done /* encode_bind_shader_data(enc, 0, &mvp_uniforms_data); */ - encode_draw_indexed(enc, mesh->index_count); + encode_draw_indexed(enc, mesh->geometry->indices->len); } void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model, texture* tex) {} @@ -182,15 +190,15 @@ mesh mesh_create(geometry_data* geometry, bool free_on_upload) { geometry->vertices->data); // Create and upload index buffer - size_t index_bytes = geometry->indices.len * sizeof(u32); - INFO("Creating index buffer with size %d (len: %d)", index_bytes, geometry->indices.len); + size_t index_bytes = geometry->indices->len * sizeof(u32); + INFO("Creating index buffer with size %d (len: %d)", index_bytes, geometry->indices->len); m.index_buffer = - gpu_buffer_create(index_bytes, CEL_BUFFER_INDEX, CEL_BUFFER_FLAG_GPU, geometry->indices.data); + gpu_buffer_create(index_bytes, CEL_BUFFER_INDEX, CEL_BUFFER_FLAG_GPU, geometry->indices->data); m.is_uploaded = true; - m.has_indices = geometry->has_indices; - m.index_count = geometry->indices.len; - m.vertices = geometry; + // m.has_indices = geometry->has_indices; + // m.index_count = geometry->indices.len; + m.geometry = geometry; if (free_on_upload) { geo_free_data(geometry); } diff --git a/src/renderer/render.h b/src/renderer/render.h index c193ff9..b745e7a 100644 --- a/src/renderer/render.h +++ b/src/renderer/render.h @@ -13,6 +13,25 @@ #include "ral_types.h" #include "render_types.h" +/** @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; + void* backend_context; + renderer_config config; + gpu_device device; + gpu_swapchain swapchain; + gpu_renderpass default_renderpass; + gpu_pipeline static_opaque_pipeline; + bool frame_aborted; + struct resource_pools* resource_pools; +} renderer; + bool renderer_init(renderer* ren); void renderer_shutdown(renderer* ren); diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h index 349f65a..2d9cf58 100644 --- a/src/renderer/render_types.h +++ b/src/renderer/render_types.h @@ -26,30 +26,11 @@ 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; - void* backend_context; - renderer_config config; - gpu_device device; - gpu_swapchain swapchain; - gpu_renderpass default_renderpass; - gpu_pipeline static_opaque_pipeline; - bool frame_aborted; - struct resource_pools* resource_pools; -} renderer; - typedef struct geometry_data { vertex_format format; vertex_darray* vertices; // TODO: make it not a pointer bool has_indices; - u32_darray indices; + u32_darray* indices; vec3 colour; /** Optional: set vertex colours */ } geometry_data; @@ -57,25 +38,31 @@ typedef struct geometry_data { 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 + geometry_data* geometry; // NULL means it has been freed bool is_uploaded; bool is_latent; } mesh; +#ifndef TYPED_MESH_ARRAY +KITC_DECL_TYPED_ARRAY(mesh) +#define TYPED_MESH_ARRAY +#endif + /* Hot reloading: C side - reload_model(): - load model from disk using existing loader - remove from transform graph so it isnt tried to be drawn */ +CORE_DEFINE_HANDLE(model_handle); + typedef struct model { str8 name; - mesh* meshes; - u32 mesh_count; + mesh_darray* meshes; } model; +TYPED_POOL(model, model) + typedef struct texture { } texture; @@ -103,11 +90,6 @@ typedef blinn_phong_material material; extern material DEFAULT_MATERIAL; void default_material_init(); -#ifndef TYPED_MESH_ARRAY -KITC_DECL_TYPED_ARRAY(mesh) -#define TYPED_MESH_ARRAY -#endif - #ifndef TYPED_MODEL_ARRAY KITC_DECL_TYPED_ARRAY(model) #define TYPED_MODEL_ARRAY diff --git a/src/resources/gltf.c b/src/resources/gltf.c index 61b99d7..67b4a86 100644 --- a/src/resources/gltf.c +++ b/src/resources/gltf.c @@ -2,6 +2,7 @@ #include #include #include "animation.h" +#include "colours.h" #include "core.h" #include "defines.h" #include "file.h" @@ -11,6 +12,7 @@ #include "maths_types.h" #include "mem.h" #include "path.h" +#include "ral_types.h" #include "render.h" // #include "render_backend.h" #include "render_types.h" @@ -19,6 +21,8 @@ #define CGLTF_IMPLEMENTATION #include +extern core g_core; + struct face { cgltf_uint indices[3]; }; @@ -34,7 +38,7 @@ KITC_DECL_TYPED_ARRAY(face) bool model_load_gltf_str(const char *file_string, const char *filepath, str8 relative_path, model *out_model, bool invert_textures_y); -model_handle model_load_gltf(struct core *core, const char *path, bool invert_texture_y) { +model_handle model_load_gltf(const char *path, bool invert_texture_y) { size_t arena_size = 1024; arena scratch = arena_create(malloc(arena_size), arena_size); @@ -45,26 +49,22 @@ model_handle model_load_gltf(struct core *core, const char *path, bool invert_te } const char *file_string = string_from_file(path); - model model = { 0 }; - model.name = str8_cstr_view(path); - // FIXME: Use mesh* malloc'd - /* model.meshes = mesh_darray_new(1); */ - // model.materials = material_darray_new(1); + model_handle handle; + model* model = model_pool_alloc(&g_core.models, &handle); + model->name = str8_cstr_view(path); + model->meshes = mesh_darray_new(1); bool success = - model_load_gltf_str(file_string, path, relative_path.path, &model, invert_texture_y); + model_load_gltf_str(file_string, path, relative_path.path, model, invert_texture_y); if (!success) { - FATAL("Couldnt load OBJ file at path %s", path); + FATAL("Couldnt load GLTF file at path %s", path); ERROR_EXIT("Load fails are considered crash-worthy right now. This will change later.\n"); } - u32 index = model_darray_len(core->models); - model_darray_push(core->models, model); - arena_free_all(&scratch); arena_free_storage(&scratch); - return (model_handle){ .raw = index }; + return handle; } void assert_path_type_matches_component_type(cgltf_animation_path_type target_path, @@ -77,32 +77,38 @@ void assert_path_type_matches_component_type(cgltf_animation_path_type target_pa // TODO: Brainstorm how I can make this simpler and break it up into more testable pieces +/* +typedef struct model { + str8 name; + mesh* meshes; + u32 mesh_count; +} model; +*/ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 relative_path, model *out_model, bool invert_textures_y) { - 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; - // } + 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"); + cgltf_load_buffers(&options, data, filepath); + DEBUG("loaded buffers"); // // --- Skin // size_t num_skins = data->skins_count; @@ -190,111 +196,110 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel // // 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); - // } + // --- Meshes + size_t num_meshes = data->meshes_count; + TRACE("Num meshes %d", num_meshes); + 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.) - // } else if (attribute.type == cgltf_attribute_type_normal) { - // TRACE("Load normals from accessor"); + for (cgltf_size 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, "Normal vectors should be a vec3"); + 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"); - // 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); - // } + TRACE("Loading %d vec3 components", accessor->count); - // } 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); - // } + 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_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); - // } - // } + } else if (attribute.type == cgltf_attribute_type_normal) { + TRACE("Load normals from accessor"); - // 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; - // // } - // // } - // } + 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) { + // FIXME: 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) { + // FIXME: 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.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) { @@ -315,42 +320,79 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel // // } // // } - // cgltf_accessor *indices = primitive.indices; - // if (primitive.indices > 0) { - // WARN("indices!"); - // mesh.has_indices = true; + /* + 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 + bool is_uploaded; + bool is_latent; + } mesh; + */ + bool has_indices = false; + vertex_darray* geo_vertices = vertex_darray_new(3); + u32_darray* geo_indices = u32_darray_new(0); + + // Store vertices + printf("Positions %d Normals %d UVs %d\n", tmp_positions->len, tmp_normals->len, tmp_uvs->len); + assert(tmp_positions->len == tmp_normals->len); + assert(tmp_normals->len == tmp_uvs->len); + for (u32 v_i = 0; v_i < tmp_positions->len; v_i++) { + vertex v = { + .static_3d = { + .position = tmp_positions->data[v_i], + .normal = tmp_normals->data[v_i], + .tex_coords = tmp_uvs->data[v_i], + } + }; + vertex_darray_push(geo_vertices, v); + } - // mesh.indices = malloc(indices->count * sizeof(u32)); - // mesh.indices_len = indices->count; + // Store indices + cgltf_accessor* indices = primitive.indices; + if (primitive.indices > 0) { + WARN("indices! %d", indices->count); + has_indices = true; - // // store indices - // for (cgltf_size i = 0; i < indices->count; ++i) { - // cgltf_uint ei; - // cgltf_accessor_read_uint(indices, i, &ei, 1); - // mesh.indices[i] = ei; - // } + // store indices + for (cgltf_size i = 0; i < indices->count; ++i) { + cgltf_uint ei; + cgltf_accessor_read_uint(indices, i, &ei, 1); + u32_darray_push(geo_indices, ei); + } - // // fetch and store vertices for each index - // for (cgltf_size i = 0; i < indices->count; ++i) { - // 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 - // } + // 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 { + has_indices = false; + return false; // TODO: handle this + } - // mesh_darray_push(out_model->meshes, mesh); + geometry_data* geometry = malloc(sizeof(geometry_data)); + geometry->format = VERTEX_STATIC_3D; + geometry->colour = vec3(1,1,1); + geometry->vertices = geo_vertices; + geometry->indices = geo_indices; + geometry->has_indices = has_indices; + mesh m = mesh_create(geometry, true); + + mesh_darray_push(out_model->meshes, m); + } // // clear data for each mesh // vec3_darray_clear(tmp_positions); @@ -486,7 +528,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel // } // } - // return true; + return true; } /* diff --git a/src/resources/loaders.h b/src/resources/loaders.h index 858e4d1..fe03ed9 100644 --- a/src/resources/loaders.h +++ b/src/resources/loaders.h @@ -5,5 +5,5 @@ struct core; -model_handle model_load_obj(struct core *core, const char *path, bool invert_texture_y); -model_handle model_load_gltf(struct core *core, const char *path, bool invert_texture_y); +model_handle model_load_obj(const char *path, bool invert_texture_y); +model_handle model_load_gltf(const char *path, bool invert_texture_y); diff --git a/src/resources/obj.c b/src/resources/obj.c index 19d8657..f95398a 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -64,8 +64,9 @@ model_handle model_load_obj(core *core, const char *path, bool invert_textures_y ERROR_EXIT("Load fails are considered crash-worthy right now. This will change later.\n"); } - u32 index = model_darray_len(core->models); - model_darray_push(core->models, model); +// FIXME + // u32 index = model_darray_len(core->models); + // model_darray_push(core->models, model); arena_free_all(&scratch); arena_free_storage(&scratch); diff --git a/src/systems/terrain.h b/src/systems/terrain.h index bfd90b5..62aa568 100644 --- a/src/systems/terrain.h +++ b/src/systems/terrain.h @@ -18,7 +18,7 @@ Future: #include "defines.h" #include "maths_types.h" #include "mem.h" -#include "render_types.h" +#include "render.h" #include "str.h" typedef struct heightmap { diff --git a/src/transform_hierarchy.c b/src/transform_hierarchy.c index 2f2ff01..2c427b2 100644 --- a/src/transform_hierarchy.c +++ b/src/transform_hierarchy.c @@ -165,11 +165,12 @@ bool print_node(transform_node* node, void* ctx_data) { } // Grab the model - model m = ctx->core->models->data[node->model.raw]; + // FIXME + // model m = ctx->core->models->data[node->model.raw]; for (int i = 0; i < ctx->indentation_lvl; i++) { printf(" "); } - printf("Node %s\n", m.name.buf); + // printf("Node %s\n", m.name.buf); ctx->indentation_lvl++; return true; diff --git a/xmake.lua b/xmake.lua index 6af1402..598b7a3 100644 --- a/xmake.lua +++ b/xmake.lua @@ -209,12 +209,12 @@ target("cube") -- 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("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") -- cgit v1.2.3-70-g09d2