diff options
author | omnisci3nce <omniscient.oce@gmail.com> | 2024-07-14 21:47:25 +1000 |
---|---|---|
committer | omnisci3nce <omniscient.oce@gmail.com> | 2024-07-14 21:47:25 +1000 |
commit | 529a603128d5e9dc4701322f44961f165e2183e1 (patch) | |
tree | 3e5d65ac503b971412ae35bfc5fb67a438a3c364 /src | |
parent | 5b001d39d42314085164724d3a417fb8ebd54f98 (diff) |
generate api docs python
Diffstat (limited to 'src')
-rw-r--r-- | src/core/core.c | 2 | ||||
-rw-r--r-- | src/core/core.h | 4 | ||||
-rw-r--r-- | src/maths/primitives.c | 18 | ||||
-rw-r--r-- | src/new_render/immdraw.h | 14 | ||||
-rw-r--r-- | src/new_render/render.c | 107 | ||||
-rw-r--r-- | src/new_render/render.h | 7 | ||||
-rw-r--r-- | src/new_render/render_types.h | 2 | ||||
-rw-r--r-- | src/ral/backends/opengl/backend_opengl.c | 284 | ||||
-rw-r--r-- | src/ral/backends/opengl/backend_opengl.h | 6 | ||||
-rw-r--r-- | src/ral/ral_common.c | 46 | ||||
-rw-r--r-- | src/ral/ral_common.h | 20 | ||||
-rw-r--r-- | src/ral/ral_impl.h | 56 | ||||
-rw-r--r-- | src/ral/ral_types.h | 5 | ||||
-rw-r--r-- | src/render/backends/opengl/backend_opengl.c | 16 | ||||
-rw-r--r-- | src/render/bind_group_layouts.h | 30 | ||||
-rw-r--r-- | src/render/immediate.h | 19 | ||||
-rw-r--r-- | src/render/ral.h | 40 | ||||
-rw-r--r-- | src/render/static_pipeline.h | 30 | ||||
-rw-r--r-- | src/resources/gltf.c | 96 | ||||
-rw-r--r-- | src/resources/loaders.h | 4 | ||||
-rw-r--r-- | src/resources/obj.c | 6 | ||||
-rw-r--r-- | src/std/buf.h | 6 |
22 files changed, 596 insertions, 222 deletions
diff --git a/src/core/core.c b/src/core/core.c index 602d35c..385479d 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -34,6 +34,7 @@ void Core_Bringup() { .scr_height = SCR_HEIGHT, .clear_colour = (Vec3){ .08, .08, .1 } }; + g_core.renderer = malloc(Renderer_GetMemReqs()); // initialise all subsystems if (!Renderer_Init(conf, g_core.renderer)) { // FATAL("Failed to start renderer"); @@ -61,6 +62,7 @@ void Core_Bringup() { void Core_Shutdown() { Input_Shutdown(&g_core.input); Renderer_Shutdown(g_core.renderer); + free(g_core.renderer); } bool ShouldExit() { diff --git a/src/core/core.h b/src/core/core.h index 7916143..78dcd14 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -9,6 +9,8 @@ typedef struct Core Core; +struct Renderer; + Core* get_global_core(); /** @brief Throws error if the core cannot be instantiated */ @@ -16,6 +18,8 @@ void Core_Bringup(); void Core_Shutdown(); bool ShouldExit(); +struct Renderer* Core_GetRenderer(Core* core); + void Frame_Begin(); void Frame_Draw(); void Frame_End(); diff --git a/src/maths/primitives.c b/src/maths/primitives.c index def2712..e74afcb 100644 --- a/src/maths/primitives.c +++ b/src/maths/primitives.c @@ -9,7 +9,7 @@ #define VERT_3D(arr, pos, norm, uv) \ { \ Vertex v = { .static_3d = { .position = pos, .normal = norm, .tex_coords = uv } }; \ - vertex_darray_push(arr, v); \ + Vertex_darray_push(arr, v); \ } void push_triangle(u32_darray* arr, u32 i0, u32 i1, u32 i2) { @@ -18,12 +18,6 @@ void push_triangle(u32_darray* arr, u32 i0, u32 i1, u32 i2) { u32_darray_push(arr, i2); } -// TODO: move to another file -void geo_free_data(Geometry* geo) { - vertex_darray_free(geo->vertices); - geo->vertices = NULL; -} - Vec3 plane_vertex_positions[] = { (Vec3){ -0.5, 0, -0.5 }, (Vec3){ 0.5, 0, -0.5 }, @@ -32,7 +26,7 @@ Vec3 plane_vertex_positions[] = { }; Geometry geo_create_plane(f32x2 extents) { - Vertex_darray* vertices = vertex_darray_new(4); + Vertex_darray* vertices = Vertex_darray_new(4); u32_darray* indices = u32_darray_new(vertices->len); Vec3 vert_pos[4]; @@ -69,7 +63,7 @@ static const Vec3 FRONT_TOP_LEFT = (Vec3){ 0, 1, 1 }; static const Vec3 FRONT_TOP_RIGHT = (Vec3){ 1, 1, 1 }; Geometry geo_create_cuboid(f32x3 extents) { - Vertex_darray* vertices = vertex_darray_new(36); + Vertex_darray* vertices = Vertex_darray_new(36); // back faces VERT_3D(vertices, BACK_TOP_RIGHT, VEC3_NEG_Z, vec2(1, 0)); @@ -148,7 +142,7 @@ Geometry geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_west_li assert(east_west_lines >= 3); // sphere will be degenerate and look gacked without at least 3 assert(north_south_lines >= 3); - Vertex_darray* vertices = vertex_darray_new(2 + (east_west_lines - 1) * north_south_lines); + Vertex_darray* vertices = Vertex_darray_new(2 + (east_west_lines - 1) * north_south_lines); // Create a UV sphere with spherical coordinates // a point P on the unit sphere can be represented P(r, theta, phi) @@ -180,7 +174,7 @@ Geometry geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_west_li vec3_normalise(position), // normal vector on sphere is same as position .tex_coords = vec2(0, 0) // TODO } }; - vertex_darray_push(vertices, v); + Vertex_darray_push(vertices, v); } } @@ -188,7 +182,7 @@ Geometry geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_west_li Vertex bot = { .static_3d = { .position = vec3(0, -radius, 0), .normal = vec3_normalise(vec3(0, -radius, 0)), .tex_coords = vec2(0, 0) } }; - vertex_darray_push(vertices, bot); + Vertex_darray_push(vertices, bot); u32_darray* indices = u32_darray_new(1); diff --git a/src/new_render/immdraw.h b/src/new_render/immdraw.h index c2c3a24..46c5add 100644 --- a/src/new_render/immdraw.h +++ b/src/new_render/immdraw.h @@ -6,9 +6,17 @@ #include "defines.h" #include "maths_types.h" +typedef struct Immdraw_Storage { + +} Immdraw_Storage; + // --- Public API +PUB void Immdraw_Init(Immdraw_Storage* storage); +PUB void Immdraw_Shutdown(Immdraw_Storage* storage); -void Immdraw_Cuboid(Transform tf); -void Immdraw_Sphere(Transform tf, f32 size); -void Immdraw_TransformGizmo(Transform tf, f32 size); +// These functions cause a pipeline switch and so aren't optimised for performance +PUB void Immdraw_Plane(Transform tf, Vec4 colour, bool wireframe); +PUB void Immdraw_Cuboid(Transform tf, Vec4 colour, bool wireframe); +PUB void Immdraw_Sphere(Transform tf, f32 size, Vec4 colour, bool wireframe); +PUB void Immdraw_TransformGizmo(Transform tf, f32 size); diff --git a/src/new_render/render.c b/src/new_render/render.c index f5547d5..cfd0b11 100644 --- a/src/new_render/render.c +++ b/src/new_render/render.c @@ -2,13 +2,23 @@ * @brief */ +#include <glfw3.h> #include "render.h" +#include "core.h" +#include "camera.h" +#include "colours.h" +#include "log.h" +#include "maths.h" #include "maths_types.h" #include "pbr.h" #include "ral_common.h" +#include "ral_impl.h" #include "render_scene.h" +#include "render_types.h" #include "shadows.h" +extern Core g_core; + struct Renderer { struct GLFWwindow* window; RendererConfig config; @@ -21,14 +31,105 @@ struct Renderer { Shadow_Storage* shadows; // Terrain_Storage terrain; // Text_Storage text; - struct ResourcePools* resource_pools; + ResourcePools* resource_pools; }; -bool Renderer_Init(RendererConfig config, Renderer* renderer) { +bool Renderer_Init(RendererConfig config, Renderer* ren) { + INFO("Renderer init"); + + // init resource pools + DEBUG("Initialise GPU resource pools"); + arena pool_arena = arena_create(malloc(1024 * 1024), 1024 * 1024); + ren->resource_pools = arena_alloc(&pool_arena, sizeof(struct ResourcePools)); + ResourcePools_Init(&pool_arena, ren->resource_pools); + + // GLFW window creation + + // 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 + + GLFWwindow* window = glfwCreateWindow(config.scr_width, config.scr_height, + config.window_name, NULL, NULL); + if (window == NULL) { + ERROR("Failed to create GLFW window\n"); + glfwTerminate(); + return false; + } + ren->window = window; + + glfwMakeContextCurrent(ren->window); + // set the RAL backend up + if (!GPU_Backend_Init(config.window_name, window, ren->resource_pools)) { + return false; + } + + GPU_Device_Create(&ren->device); + GPU_Swapchain_Create(&ren->swapchain); + + + // set up default scene + Camera default_cam = + Camera_Create(vec3(0.0, 2.0, 4.0), vec3_normalise(vec3(0.0, -2.0, -4.0)), VEC3_Y, 45.0); + SetCamera(default_cam); + PointLight default_light = { /* TODO */ }; + SetPointLight(default_light); // create our renderpasses - Shadow_Init(renderer->shadows); + Shadow_Init(ren->shadows); return true; } + +void Renderer_Shutdown(Renderer* renderer) { } +size_t Renderer_GetMemReqs() { return sizeof(Renderer); } + +void Render_FrameBegin(Renderer *renderer) { + renderer->frame_aborted = false; + if (GPU_Backend) + +} +void Render_FrameEnd(Renderer* renderer) { + +} +void Render_RenderEntities(RenderEnt* entities, size_t entity_count) { + Renderer* ren = Core_GetRenderer(&g_core); + + GPU_CmdEncoder* enc = GPU_GetDefaultEncoder(); + // bind shadow + GPU_EncodeBindPipeline(enc, ren->shadows) + +} + +Mesh Mesh_Create(Geometry* geometry, bool free_on_upload) { + Mesh m = { 0 }; + + // Create and upload vertex buffer + size_t vert_bytes = geometry->vertices->len * sizeof(Vertex); + INFO("Creating vertex buffer with size %d (%d x %d)", vert_bytes, geometry->vertices->len, + sizeof(Vertex)); + m.vertex_buffer = GPU_BufferCreate(vert_bytes, BUFFER_VERTEX, BUFFER_FLAG_GPU, + geometry->vertices->data); + + // Create and upload index buffer + size_t index_bytes = geometry->indices->len * sizeof(u32); + INFO("Creating index buffer with size %d (len: %d)", index_bytes, geometry->indices->len); + m.index_buffer = GPU_BufferCreate(index_bytes, BUFFER_INDEX, BUFFER_FLAG_GPU, + geometry->indices->data); + + m.is_uploaded = true; + m.geometry = geometry; + if (free_on_upload) { + Geometry_Destroy(geometry); + } + return m; +} diff --git a/src/new_render/render.h b/src/new_render/render.h index b0b5495..6e9f380 100644 --- a/src/new_render/render.h +++ b/src/new_render/render.h @@ -24,6 +24,10 @@ typedef struct RenderCtx { PUB bool Renderer_Init(RendererConfig config, Renderer* renderer); PUB void Renderer_Shutdown(Renderer* renderer); +PUB size_t Renderer_GetMemReqs(); + +// internal init functions +void DefaultPipelinesInit(Renderer* renderer); // NOTE: All of these functions grab the Renderer instance off the global Core PUB void Render_FrameBegin(Renderer* renderer); @@ -37,12 +41,13 @@ PUB void Render_RenderEntities(RenderEnt* entities, size_t entity_count); // --- Resources PUB TextureHandle TextureUpload(); -PUB ModelHandle ModelLoad(const char* name, const char* filepath); +PUB ModelHandle ModelLoad(const char* debug_name, const char* filepath); // --- Rendering Data PUB Mesh Mesh_Create(Geometry* geometry, bool free_on_upload); PUB void Mesh_Delete(Mesh* mesh); +void Geometry_Destroy(Geometry* geometry); // --- Drawing diff --git a/src/new_render/render_types.h b/src/new_render/render_types.h index b27bf2f..1cf6c7e 100644 --- a/src/new_render/render_types.h +++ b/src/new_render/render_types.h @@ -27,7 +27,7 @@ typedef struct u32_opt { } u32_opt; typedef struct Mesh { - BufferHandle vextex_buffer; + BufferHandle vertex_buffer; BufferHandle index_buffer; Geometry* geometry; // NULL means it has been freed CPU-side bool is_uploaded; // has the data been uploaded to the GPU diff --git a/src/ral/backends/opengl/backend_opengl.c b/src/ral/backends/opengl/backend_opengl.c new file mode 100644 index 0000000..2c7c411 --- /dev/null +++ b/src/ral/backends/opengl/backend_opengl.c @@ -0,0 +1,284 @@ +#include <assert.h> +#include "backend_opengl.h" +#include "log.h" +#include "mem.h" +#include "ral_common.h" +#include "ral_impl.h" +#include "ral_types.h" + +#include <glad/glad.h> +#include <glfw3.h> + +typedef struct OpenglCtx { + GLFWwindow* window; + arena pool_arena; + GPU_CmdBuffer main_cmd_buffer; + GPU_BackendPools gpu_pools; + ResourcePools* resource_pools; +} OpenglCtx; + +static OpenglCtx context; + +bool GPU_Backend_Init(const char* window_name, struct GLFWwindow *window, struct ResourcePools* res_pools) { + INFO("loading OpenGL backend"); + + memset(&context, 0, sizeof(context)); + context.window = window; + + size_t pool_buffer_size = 1024 * 1024; + context.pool_arena = arena_create(malloc(pool_buffer_size), pool_buffer_size); + + BackendPools_Init(&context.pool_arena, &context.gpu_pools); + context.resource_pools = res_pools; + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + + // glad: load all opengl function pointers + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + ERROR("Failed to initialise GLAD \n"); + return false; + } + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + return true; +} + +// All of these are no-ops in OpenGL +void GPU_Backend_Shutdown() {} +bool GPU_Device_Create(GPU_Device* out_device) { return true; } +void GPU_Device_Destroy(GPU_Device* device) {} +bool GPU_Swapchain_Create(GPU_Swapchain* out_swapchain) { return true; } +void GPU_Swapchain_Destroy(GPU_Swapchain* swapchain) {} +void GPU_CmdEncoder_Destroy(GPU_CmdEncoder* encoder) {} +void GPU_CmdEncoder_BeginRender(GPU_CmdEncoder* encoder, GPU_Renderpass* renderpass) {} +void GPU_CmdEncoder_EndRender(GPU_CmdEncoder* encoder) {} +GPU_CmdEncoder* GPU_GetDefaultEncoder() { + return context. +} +void GPU_QueueSubmit(GPU_CmdBuffer* cmd_buffer) {} + +GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description) { + // allocate new pass + GPU_Renderpass* renderpass = Renderpass_pool_alloc(&context.gpu_pools.renderpasses, NULL); + renderpass->description = description; + + if (!description.default_framebuffer) { + // If we're not using the default framebuffer we need to generate a new one + GLuint gl_fbo_id; + glGenFramebuffers(1, &gl_fbo_id); + renderpass->fbo = gl_fbo_id; + } else { + renderpass->fbo = OPENGL_DEFAULT_FRAMEBUFFER; + assert(!description.has_color_target); + assert(!description.has_depth_stencil); + } + glBindFramebuffer(GL_FRAMEBUFFER, renderpass->fbo); + + if (description.has_color_target && !description.default_framebuffer) { + GPU_Texture* colour_attachment = TEXTURE_GET(description.color_target); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + colour_attachment->id, 0); + } + if (description.has_depth_stencil && !description.default_framebuffer) { + GPU_Texture* depth_attachment = TEXTURE_GET(description.depth_stencil); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_attachment->id, + 0); + } + + if (description.has_depth_stencil && !description.has_color_target) { + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); // reset to default framebuffer + + return renderpass; +} + +void GPU_Renderpass_Destroy(GPU_Renderpass* pass) { glDeleteFramebuffers(1, &pass->fbo); } + +GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description, GPU_Renderpass* renderpass) { + GPU_Pipeline* pipeline = Pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL); + + // Create shader program + u32 shader_id = shader_create_separate(description.vs.filepath.buf, description.fs.filepath.buf); + pipeline->shader_id = shader_id; + + // Vertex format + pipeline->vertex_desc = description.vertex_desc; + + // Allocate uniform buffers if needed + u32 ubo_count = 0; + // printf("data layouts %d\n", description.data_layouts_count); + for (u32 layout_i = 0; layout_i < description.data_layouts_count; layout_i++) { + ShaderDataLayout sdl = description.data_layouts[layout_i].get_layout(NULL); + TRACE("Got shader data layout %d's bindings! . found %d", layout_i, sdl.binding_count); + + for (u32 binding_j = 0; binding_j < sdl.binding_count; binding_j++) { + u32 binding_id = binding_j; + assert(binding_id < MAX_PIPELINE_UNIFORM_BUFFERS); + ShaderBinding binding = sdl.bindings[binding_j]; + // Do I want Buffer vs Bytes? + if (binding.kind == BINDING_BUFFER) { + static u32 s_binding_point = 0; + BufferHandle ubo_handle = + GPU_BufferCreate(binding.data.bytes.size, BUFFER_UNIFORM, BUFFER_FLAG_GPU, NULL); // no data right now + pipeline->uniform_bindings[ubo_count++] = ubo_handle; + GPU_Buffer* ubo_buf = BUFFER_GET(ubo_handle); + + i32 blockIndex = glGetUniformBlockIndex(pipeline->shader_id, binding.label); + printf("Block index for %s: %d", binding.label, blockIndex); + if (blockIndex < 0) { + WARN("Couldn't retrieve block index for uniform block '%s'", binding.label); + } else { + // DEBUG("Retrived block index %d for %s", blockIndex, binding.label); + } + u32 blocksize; + glGetActiveUniformBlockiv(pipeline->shader_id, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, + &blocksize); + printf("\t with size %d bytes\n", blocksize); + + glBindBufferBase(GL_UNIFORM_BUFFER, s_binding_point, ubo_buf->id.ubo); + if (blockIndex != GL_INVALID_INDEX) { + glUniformBlockBinding(pipeline->shader_id, blockIndex, s_binding_point); + } + ubo_buf->ubo_binding_point = s_binding_point++; + ubo_buf->name = binding.label; + assert(s_binding_point < GL_MAX_UNIFORM_BUFFER_BINDINGS); + } + } + } + pipeline->uniform_count = ubo_count; + + pipeline->renderpass = description.renderpass; + pipeline->wireframe = description.wireframe; + + return pipeline; +} + +void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline) {} + +GPU_CmdEncoder GPU_CmdEncoder_Create() { + GPU_CmdEncoder encoder = { 0 }; + return encoder; +} + + +BufferHandle GPU_BufferCreate(u64 size, GPU_BufferType buf_type, GPU_BufferFlags flags, const void *data) { + // "allocating" the cpu-side buffer struct + BufferHandle handle; + GPU_Buffer* buffer = Buffer_pool_alloc(&context.resource_pools, &handle); + buffer->size = size; + buffer->vao = 0; + + // Opengl buffer + GLuint gl_buffer_id; + glGenBuffers(1, &gl_buffer_id); + + GLenum gl_buf_type; + GLenum gl_buf_usage = GL_STATIC_DRAW; + + switch (buf_type) { + case BUFFER_UNIFORM: + DEBUG("Creating Uniform buffer"); + gl_buf_type = GL_UNIFORM_BUFFER; + /* gl_buf_usage = GL_DYNAMIC_DRAW; */ + buffer->id.ubo = gl_buffer_id; + break; + case BUFFER_DEFAULT: + case BUFFER_VERTEX: + DEBUG("Creating Vertex buffer"); + gl_buf_type = GL_ARRAY_BUFFER; + buffer->id.vbo = gl_buffer_id; + break; + case BUFFER_INDEX: + DEBUG("Creating Index buffer"); + gl_buf_type = GL_ELEMENT_ARRAY_BUFFER; + buffer->id.ibo = gl_buffer_id; + break; + default: + WARN("Unimplemented gpu_buffer_type provided %s", buffer_type_names[buf_type]); + break; + } + // bind buffer + glBindBuffer(gl_buf_type, gl_buffer_id); + + if (data) { + TRACE("Upload data (%d bytes) as part of buffer creation", size); + glBufferData(gl_buf_type, buffer->size, data, gl_buf_usage); + } else { + TRACE("Allocating but not uploading (%d bytes)", size); + glBufferData(gl_buf_type, buffer->size, NULL, gl_buf_usage); + } + + glBindBuffer(gl_buf_type, 0); + + return handle; +} + +TextureHandle GPU_TextureCreate(TextureDesc desc, bool create_view, const void *data) { + // "allocating" the cpu-side struct + TextureHandle handle; + GPU_Texture* texture = Texture_pool_alloc(&context.resource_pools->textures, &handle); + DEBUG("Allocated texture with handle %d", handle.raw); + + GLuint gl_texture_id; + glGenTextures(1, &gl_texture_id); + texture->id = gl_texture_id; + + glBindTexture(GL_TEXTURE_2D, gl_texture_id); + + GLint internal_format = + desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_DEPTH_COMPONENT : GL_RGB; + GLenum format = desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_DEPTH_COMPONENT : GL_RGBA; + GLenum data_type = desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT ? GL_FLOAT : GL_UNSIGNED_BYTE; + + if (desc.format == TEXTURE_FORMAT_DEPTH_DEFAULT) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + } else { + // set the texture wrapping parameters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // set texture filtering parameters + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + if (data) { + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.extents.x, desc.extents.y, 0, format, + data_type, data); + glGenerateMipmap(GL_TEXTURE_2D); + } else { + WARN("No image data provided"); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, desc.extents.x, desc.extents.y, 0, format, + data_type, NULL); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + return handle; +} + +void GPU_TextureDestroy(TextureHandle handle) { + glDeleteTextures(1, &handle.raw); +} + +// TODO: void GPU_TextureUpload(TextureHandle handle, size_t n_bytes, const void* data) + +bool GPU_Backend_BeginFrame() { + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void GPU_Backend_EndFrame() { + glfwSwapBuffers(context.window); +} diff --git a/src/ral/backends/opengl/backend_opengl.h b/src/ral/backends/opengl/backend_opengl.h index 22162f3..4fbb4bb 100644 --- a/src/ral/backends/opengl/backend_opengl.h +++ b/src/ral/backends/opengl/backend_opengl.h @@ -39,11 +39,11 @@ typedef struct GPU_Renderpass { typedef struct GPU_CmdEncoder { GPU_Pipeline *pipeline; -} GPU_CmdEncoder; // Recording +} GPU_CmdEncoder; // Recording -typedef struct gpu_cmd_buffer { +typedef struct GPU_CmdBuffer { void *pad; -} gpu_cmd_buffer; // Ready for submission +} GPU_CmdBuffer; // Ready for submission typedef struct GPU_Buffer { union { diff --git a/src/ral/ral_common.c b/src/ral/ral_common.c index 89d475b..8ff282e 100644 --- a/src/ral/ral_common.c +++ b/src/ral/ral_common.c @@ -1,7 +1,7 @@ #include "ral_common.h" #include "ral_impl.h" -void backend_pools_init(arena* a, GPU_BackendPools* backend_pools) { +void BackendPools_Init(arena* a, GPU_BackendPools* backend_pools) { PipelineLayout_pool pipeline_layout_pool = PipelineLayout_pool_create(a, MAX_PIPELINES, sizeof(GPU_PipelineLayout)); backend_pools->pipeline_layouts = pipeline_layout_pool; @@ -11,9 +11,51 @@ void backend_pools_init(arena* a, GPU_BackendPools* backend_pools) { backend_pools->renderpasses = rpass_pool; } -void resource_pools_init(arena* a, struct ResourcePools* res_pools) { +void ResourcePools_Init(arena* a, struct ResourcePools* res_pools) { Buffer_pool buf_pool = Buffer_pool_create(a, MAX_BUFFERS, sizeof(GPU_Buffer)); res_pools->buffers = buf_pool; Texture_pool tex_pool = Texture_pool_create(a, MAX_TEXTURES, sizeof(GPU_Texture)); res_pools->textures = tex_pool; } + +VertexDescription static_3d_vertex_description() { + VertexDescription builder = { .debug_label = "Standard static 3d vertex format" }; + VertexDesc_AddAttr(&builder, "inPosition", ATTR_F32x3); + VertexDesc_AddAttr(&builder, "inNormal", ATTR_F32x3); + VertexDesc_AddAttr(&builder, "inTexCoords", ATTR_F32x2); + builder.use_full_vertex_size = true; + return builder; +} + +void VertexDesc_AddAttr(VertexDescription* builder, const char* name, VertexAttribType type) { + u32 i = builder->attributes_count; + + size_t size = VertexAttribSize(type); + builder->attributes[i] = type; + builder->stride += size; + builder->attr_names[i] = name; + + builder->attributes_count++; +} + +size_t VertexAttribSize(VertexAttribType attr) { + switch (attr) { + case ATTR_F32: + case ATTR_U32: + case ATTR_I32: + return 4; + case ATTR_F32x2: + case ATTR_U32x2: + case ATTR_I32x2: + return 8; + case ATTR_F32x3: + case ATTR_U32x3: + case ATTR_I32x3: + return 12; + case ATTR_F32x4: + case ATTR_U32x4: + case ATTR_I32x4: + return 16; + break; + } +} diff --git a/src/ral/ral_common.h b/src/ral/ral_common.h index 1088404..0f7c1b7 100644 --- a/src/ral/ral_common.h +++ b/src/ral/ral_common.h @@ -1,3 +1,6 @@ +/** + * @brief Common functions that don't actually depend on the specific backend +*/ #pragma once #include "defines.h" #include "buf.h" @@ -5,7 +8,6 @@ #include "ral_types.h" #include "ral_impl.h" - TYPED_POOL(GPU_Buffer, Buffer); TYPED_POOL(GPU_Texture, Texture); TYPED_POOL(GPU_PipelineLayout, PipelineLayout); @@ -17,23 +19,23 @@ TYPED_POOL(GPU_Renderpass, Renderpass); #define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h)) // --- Pools -typedef struct GPU_BackendPools{ +typedef struct GPU_BackendPools { Pipeline_pool pipelines; PipelineLayout_pool pipeline_layouts; Renderpass_pool renderpasses; } GPU_BackendPools; -void backend_pools_init(arena* a, GPU_BackendPools* backend_pools); +void BackendPools_Init(arena* a, GPU_BackendPools* backend_pools); struct ResourcePools { Buffer_pool buffers; Texture_pool textures; }; -void resource_pools_init(arena* a, struct ResourcePools* res_pools); - +typedef struct ResourcePools ResourcePools; +void ResourcePools_Init(arena* a, struct ResourcePools* res_pools); // --- Vertex formats -bytebuffer vertices_as_bytebuffer(arena* a, VertexFormat format, Vertex_darray* vertices); - -void vertex_desc_add(VertexDescription* builder, const char* name, VertexAttribType type); VertexDescription static_3d_vertex_description(); -size_t vertex_attrib_size(VertexAttribType attr); + +void VertexDesc_AddAttr(VertexDescription* builder, const char* name, VertexAttribType type); + +size_t VertexAttribSize(VertexAttribType attr); diff --git a/src/ral/ral_impl.h b/src/ral/ral_impl.h index 4d1c17a..a896eff 100644 --- a/src/ral/ral_impl.h +++ b/src/ral/ral_impl.h @@ -2,7 +2,9 @@ * @brief */ #pragma once +#include "buf.h" #include "defines.h" +#include "ral_common.h" #include "ral_types.h" struct GLFWwindow; @@ -18,7 +20,9 @@ typedef struct GPU_CmdBuffer GPU_CmdBuffer; // Ready for submission typedef struct GPU_Buffer GPU_Buffer; typedef struct GPU_Texture GPU_Texture; -bool GPU_Backend_Init(const char* window_name, struct GLFWwindow* window); +struct ResourcePools; + +bool GPU_Backend_Init(const char* window_name, struct GLFWwindow* window, struct ResourcePools* res_pools); void GPU_Backend_Shutdown(); bool GPU_Device_Create(GPU_Device* out_device); @@ -27,12 +31,54 @@ void GPU_Device_Destroy(GPU_Device* device); bool GPU_Swapchain_Create(GPU_Swapchain* out_swapchain); void GPU_Swapchain_Destroy(GPU_Swapchain* swapchain); -GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description); -void GPU_Renderpass_Destroy(GPU_Renderpass* pass); +PUB GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description); +PUB void GPU_Renderpass_Destroy(GPU_Renderpass* pass); + +PUB GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description, GPU_Renderpass* renderpass); +PUB void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline); + +// --- Command buffer +PUB GPU_CmdEncoder GPU_CmdEncoder_Create(); +PUB void GPU_CmdEncoder_Destroy(GPU_CmdEncoder* encoder); +PUB void GPU_CmdEncoder_BeginRender(GPU_CmdEncoder* encoder, GPU_Renderpass* renderpass); +PUB void GPU_CmdEncoder_EndRender(GPU_CmdEncoder* encoder); +PUB GPU_CmdEncoder* GPU_GetDefaultEncoder(); +PUB void GPU_QueueSubmit(GPU_CmdBuffer* cmd_buffer); + +// --- Buffers +PUB BufferHandle GPU_BufferCreate(u64 size, GPU_BufferType buf_type, GPU_BufferFlags flags, const void* data); +PUB void GPU_BufferDestroy(BufferHandle handle); +PUB void GPU_BufferUpload(BufferHandle buffer, size_t n_bytes, const void* data); + +// --- Textures +PUB TextureHandle GPU_TextureCreate(TextureDesc desc, bool create_view, const void* data); +PUB void GPU_TextureDestroy(TextureHandle handle); +PUB void GPU_TextureUpload(TextureHandle handle, size_t n_bytes, const void* data); + +// --- Data copy commands +// TODO: Rename these to reflect current coding style +void encode_buffer_copy(GPU_CmdEncoder* encoder, BufferHandle src, u64 src_offset, + BufferHandle dst, u64 dst_offset, u64 copy_size); +void buffer_upload_bytes(BufferHandle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size); + +void copy_buffer_to_buffer_oneshot(BufferHandle src, u64 src_offset, BufferHandle dst, + u64 dst_offset, u64 copy_size); +void copy_buffer_to_image_oneshot(BufferHandle src, TextureHandle dst); + +// --- Render commands +PUB void GPU_EncodeBindPipeline(GPU_CmdEncoder* encoder, GPU_Pipeline* pipeline); +PUB void GPU_EncodeBindShaderData(GPU_CmdEncoder* encoder, u32 group, ShaderData* data); +void GPU_EncodeSetDefaults(GPU_CmdEncoder* encoder); +PUB void GPU_EncodeSetVertexBuffer(GPU_CmdEncoder* encoder, BufferHandle buf); +PUB void GPU_EncodeSetIndexBuffer(GPU_CmdEncoder* encoder, BufferHandle buf); +PUB void GPU_EncodeDraw(GPU_CmdEncoder* encoder, u64 count); +PUB void GPU_EncodeDrawIndexed(GPU_CmdEncoder* encoder, u64 index_count); -GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description, GPU_Renderpass* renderpass); -void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline); +// --- Frame cycle +PUB bool GPU_Backend_BeginFrame(); +PUB void GPU_Backend_EndFrame(); +// Concrete implementation #if defined(CEL_REND_BACKEND_OPENGL) #include "backend_opengl.h" #endif diff --git a/src/ral/ral_types.h b/src/ral/ral_types.h index 0ba7f87..188951a 100644 --- a/src/ral/ral_types.h +++ b/src/ral/ral_types.h @@ -176,7 +176,7 @@ typedef struct ShaderDataLayout { size_t binding_count; } ShaderDataLayout; -typedef ShaderDataLayout (*FN_GetBindingLayout)(void); +typedef ShaderDataLayout (*FN_GetBindingLayout)(void* data); typedef struct ShaderData { FN_GetBindingLayout get_layout; @@ -197,7 +197,6 @@ typedef enum PrimitiveTopology { typedef enum CullMode { CULL_BACK_FACE, CULL_FRONT_FACE, CULL_COUNT } CullMode; typedef struct GraphicsPipelineDesc { - // GPU_Renderpass* renderpass -> takes a renderpass in the create function const char* debug_name; VertexDescription vertex_desc; ShaderDesc vs; /** @brief Vertex shader stage */ @@ -205,7 +204,7 @@ typedef struct GraphicsPipelineDesc { // Roughly equivalent to a descriptor set layout each. each layout can have multiple bindings // examples: - // - uniform buffer reprensenting view projection matrix + // - uniform buffer representing view projection matrix // - texture for shadow map ShaderData data_layouts[MAX_SHADER_DATA_LAYOUTS]; u32 data_layouts_count; diff --git a/src/render/backends/opengl/backend_opengl.c b/src/render/backends/opengl/backend_opengl.c index 70e10d7..43105e2 100644 --- a/src/render/backends/opengl/backend_opengl.c +++ b/src/render/backends/opengl/backend_opengl.c @@ -1,7 +1,6 @@ #include <stddef.h> #include <stdio.h> #include <string.h> -#include "builtin_materials.h" #include "colours.h" #include "maths.h" #include "opengl_helpers.h" @@ -63,11 +62,6 @@ bool gpu_backend_init(const char* window_name, struct GLFWwindow* window) { return true; } -void gpu_backend_shutdown() {} - -bool gpu_device_create(gpu_device* out_device) { /* No-op in OpenGL */ } -void gpu_device_destroy() { /* No-op in OpenGL */ } - // --- Render Pipeline gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description) { gpu_pipeline* pipeline = pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL); @@ -168,10 +162,6 @@ gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description) { } void gpu_renderpass_destroy(gpu_renderpass* pass) { glDeleteFramebuffers(1, &pass->fbo); } -// --- Swapchain -bool gpu_swapchain_create(gpu_swapchain* out_swapchain) {} -void gpu_swapchain_destroy(gpu_swapchain* swapchain) {} - // --- Command buffer gpu_cmd_encoder gpu_cmd_encoder_create() { gpu_cmd_encoder encoder = { 0 }; @@ -180,12 +170,9 @@ 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) { - // glViewport(0, 0, 1000, 1000); glBindFramebuffer(GL_FRAMEBUFFER, renderpass->fbo); 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); */ - // FIXME: account for both if (renderpass->description.has_depth_stencil) { glClear(GL_DEPTH_BUFFER_BIT); } else { @@ -353,9 +340,6 @@ buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_f return handle; } -void gpu_buffer_destroy(buffer_handle buffer) {} -void gpu_buffer_upload(const void* data) {} - texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) { // "allocating" the cpu-side struct texture_handle handle; diff --git a/src/render/bind_group_layouts.h b/src/render/bind_group_layouts.h deleted file mode 100644 index 246d1ef..0000000 --- a/src/render/bind_group_layouts.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file bind_group_layouts.h - * @author your name (you@domain.com) - * @brief Common bindgroups (descriptor set layouts) - * @version 0.1 - * @date 2024-04-28 - * - * @copyright Copyright (c) 2024 - * - */ -#pragma once -#include "defines.h" -#include "maths_types.h" - -// Three major sets - -// 1. Scene / Global -typedef struct bg_globals { - mat4 view; - mat4 projection; - f32 total_time; - f32 delta_time; -} bg_globals; - -// 2. Material (once per object) - -// 3. Per draw call -typedef struct bg_model { - mat4 model; -} bg_model; diff --git a/src/render/immediate.h b/src/render/immediate.h deleted file mode 100644 index f4b1729..0000000 --- a/src/render/immediate.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "geometry.h" -#include "maths_types.h" - -typedef struct immdraw_system immdraw_system; - -bool immdraw_system_init(immdraw_system* state); -void immdraw_system_shutdown(immdraw_system* state); -void immdraw_system_render(immdraw_system* state); - -// 3. SIMA (simplified immediate mode api) / render.h -// - dont need to worry about uploading mesh data -// - very useful for debugging -void immdraw_plane(vec3 pos, quat rotation, f32 u_scale, f32 v_scale, vec4 colour); -void immdraw_cuboid(vec3 pos, quat rotation, f32x3 extents, vec4 colour); -void immdraw_sphere(vec3 pos, f32 radius, vec4 colour); - -void immdraw_camera_frustum(); diff --git a/src/render/ral.h b/src/render/ral.h index 792bb4e..fc3c96c 100644 --- a/src/render/ral.h +++ b/src/render/ral.h @@ -109,24 +109,24 @@ typedef struct gpu_renderpass_desc { } gpu_renderpass_desc; // --- Lifecycle functions -bool gpu_backend_init(const char* window_name, struct GLFWwindow* window); -void gpu_backend_shutdown(); +// bool gpu_backend_init(const char* window_name, struct GLFWwindow* window); +// void gpu_backend_shutdown(); void resource_pools_init(arena* a, struct resource_pools* res_pools); -bool gpu_device_create(gpu_device* out_device); -void gpu_device_destroy(); +// bool gpu_device_create(gpu_device* out_device); +// void gpu_device_destroy(); -// --- Render Pipeline -gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description); -void gpu_pipeline_destroy(gpu_pipeline* pipeline); +// // --- Render Pipeline +// gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description); +// void gpu_pipeline_destroy(gpu_pipeline* pipeline); -// --- Renderpass -gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description); -void gpu_renderpass_destroy(gpu_renderpass* pass); +// // --- Renderpass +// gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description); +// void gpu_renderpass_destroy(gpu_renderpass* pass); -// --- Swapchain -bool gpu_swapchain_create(gpu_swapchain* out_swapchain); -void gpu_swapchain_destroy(gpu_swapchain* swapchain); +// // --- Swapchain +// bool gpu_swapchain_create(gpu_swapchain* out_swapchain); +// void gpu_swapchain_destroy(gpu_swapchain* swapchain); // --- Command buffer gpu_cmd_encoder gpu_cmd_encoder_create(); @@ -167,20 +167,6 @@ void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count); void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf); // --- Buffers -buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags, - const void* data); -void gpu_buffer_destroy(buffer_handle buffer); -void gpu_buffer_upload(const void* data); - -// Textures -/** @brief Create a new GPU texture resource. - * @param create_view creates a texture view (with same dimensions) at the same time - * @param data if not NULL then the data stored at the pointer will be uploaded to the GPU texture - * @note automatically creates a sampler for you */ -texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data); -void gpu_texture_destroy(texture_handle); -void gpu_texture_upload(texture_handle texture, const void* data); - // --- Vertex formats bytebuffer vertices_as_bytebuffer(arena* a, vertex_format format, vertex_darray* vertices); diff --git a/src/render/static_pipeline.h b/src/render/static_pipeline.h deleted file mode 100644 index bf5bc42..0000000 --- a/src/render/static_pipeline.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "defines.h" -#include "maths_types.h" -#include "ral.h" -#include "ral_types.h" -#include "render_types.h" - -typedef struct mvp_uniforms { - mat4 model; - mat4 view; - mat4 projection; -} mvp_uniforms; -typedef struct my_shader_bind_group { - mvp_uniforms mvp; -} my_shader_bind_group; - -static shader_data_layout mvp_uniforms_layout(void* data) { - my_shader_bind_group* d = (my_shader_bind_group*)data; - bool has_data = data != NULL; - - shader_binding b1 = { .label = "Matrices", - .type = SHADER_BINDING_BYTES, - .stores_data = has_data, - .data = { .bytes = { .size = sizeof(mvp_uniforms) } } }; - - if (has_data) { - b1.data.bytes.data = &d->mvp; - } - return (shader_data_layout){ .name = "global_ubo", .bindings = { b1 }, .bindings_count = 1 }; -} diff --git a/src/resources/gltf.c b/src/resources/gltf.c index e381954..69ae9e1 100644 --- a/src/resources/gltf.c +++ b/src/resources/gltf.c @@ -50,7 +50,7 @@ ModelHandle model_load_gltf(const char *path, bool invert_texture_y) { const char *file_string = string_from_file(path); ModelHandle handle; - // modfl *model = model_pool_alloc(&g_core.models, &handle); + // Model *model = model_pool_alloc(&g_core.models, &handle); // model->name = str8_cstr_view(path); // model->meshes = mesh_darray_new(1); // model->materials = material_darray_new(1); @@ -184,7 +184,8 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel normal_tex_view.texture->image->uri); // material our_material = - // pbr_material_load(albedo_map_path, normal_map_path, true, metal_rough_map_path, NULL, NULL); + // pbr_material_load(albedo_map_path, normal_map_path, true, metal_rough_map_path, NULL, + // NULL); // our_material.name = malloc(strlen(gltf_material.name) + 1); // strcpy(our_material.name, gltf_material.name); @@ -326,62 +327,61 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel 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++) { + // printf("Positions %d Normals %d UVs %d\n", tmp_positions->len, tmp_normals->len, + // tmp_uvs->len); assert(tmp_positions->len == tmp_normals->len); assert(tmp_normals->len == + // tmp_uvs->len); for (u32 v_i = 0; v_i < tmp_positions->len; v_i++) { // vertex v = { .static_3d = { // .position = tmp_positions->data[v_i], // .normal = tmp_normals->data[v_i], // .tex_coords = tmp_uvs->data[v_i], // } }; // vertex_darray_push(geo_vertices, v); - } + } - // Store indices - // cgltf_accessor *indices = primitive.indices; - // if (primitive.indices > 0) { - // WARN("indices! %d", indices->count); - // has_indices = true; - - // // store indices - // for (cgltf_size i = 0; i < indices->count; ++i) { - // cgltf_uint ei; - // cgltf_accessor_read_uint(indices, i, &ei, 1); - // u32_darray_push(geo_indices, ei); - // } - - // 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 - // } + // Store indices + // cgltf_accessor *indices = primitive.indices; + // if (primitive.indices > 0) { + // WARN("indices! %d", indices->count); + // has_indices = true; + + // // store indices + // for (cgltf_size i = 0; i < indices->count; ++i) { + // cgltf_uint ei; + // cgltf_accessor_read_uint(indices, i, &ei, 1); + // u32_darray_push(geo_indices, ei); + // } + + // 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 + // } - // geometry_data *geometry = malloc(sizeof(geometry_data)); - // geometry->format = VERTEX_STATIC_3D; - // geometry->colour = (rgba){ 1, 1, 1, 1 }; - // geometry->vertices = geo_vertices; - // geometry->indices = geo_indices; - // geometry->has_indices = has_indices; + // geometry_data *geometry = malloc(sizeof(geometry_data)); + // geometry->format = VERTEX_STATIC_3D; + // geometry->colour = (rgba){ 1, 1, 1, 1 }; + // geometry->vertices = geo_vertices; + // geometry->indices = geo_indices; + // geometry->has_indices = has_indices; - // mesh m = mesh_create(geometry, true); - // m.material_index = (u32_opt){ .has_value = mat_idx == 9999, .value = mat_idx }; + // mesh m = mesh_create(geometry, true); + // m.material_index = (u32_opt){ .has_value = mat_idx == 9999, .value = mat_idx }; - // mesh_darray_push(out_model->meshes, m); + // mesh_darray_push(out_model->meshes, m); // } // // clear data for each mesh diff --git a/src/resources/loaders.h b/src/resources/loaders.h index d8437b9..3ec41fa 100644 --- a/src/resources/loaders.h +++ b/src/resources/loaders.h @@ -5,8 +5,8 @@ #include "str.h" // --- Public API -ModelHandle Model_Load_obj(const char *path, bool invert_texture_y); -ModelHandle Model_Load_gltf(const char *path, bool invert_texture_y); +PUB ModelHandle Model_Load_obj(const char *path, bool invert_texture_y); +PUB ModelHandle Model_Load_gltf(const char *path, bool invert_texture_y); // --- Internal bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 relative_path, diff --git a/src/resources/obj.c b/src/resources/obj.c index 87d3ed6..e5b2fc9 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -260,7 +260,8 @@ bool model_load_obj_str(const char *file_string, Str8 relative_path, Model *out_ // // } // // 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), +// // vec3_darray_len(tmp_positions), vec2_darray_len(tmp_uvs), +// vec3_darray_len(tmp_normals), // // face_darray_len(tmp_faces)); // // // Clear current object faces @@ -339,7 +340,8 @@ bool model_load_obj_str(const char *file_string, Str8 relative_path, Model *out_ // // ¤t_material.ambient_colour.y, ¤t_material.ambient_colour.z); // // } else if (strcmp(line_header, "Kd") == 0) { // // // diffuse -// // sscanf(pch + offset, "%f %f %f", ¤t_material.diffuse.x, ¤t_material.diffuse.y, +// // sscanf(pch + offset, "%f %f %f", ¤t_material.diffuse.x, +// ¤t_material.diffuse.y, // // ¤t_material.diffuse.z); // // } else if (strcmp(line_header, "Ks") == 0) { // // // specular diff --git a/src/std/buf.h b/src/std/buf.h index de093ec..77fc7b9 100644 --- a/src/std/buf.h +++ b/src/std/buf.h @@ -1,12 +1,6 @@ /** * @file buf.h - * @author your name (you@domain.com) * @brief - * @version 0.1 - * @date 2024-04-28 - * - * @copyright Copyright (c) 2024 - * */ #pragma once #include "defines.h" |