From 2b9ee8f721ee58bf981ce8601b82a55f52f09509 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 13 Apr 2026 09:40:40 -0500 Subject: [PATCH] Entity does not own mesh. --- src/dusk/asset/loader/display/CMakeLists.txt | 1 - .../asset/loader/display/assetmeshloader.c | 122 ------------------ .../asset/loader/display/assetmeshloader.h | 27 ---- src/dusk/engine/engine.c | 34 +++-- .../entity/component/display/entitymesh.c | 16 +-- .../entity/component/display/entitymesh.h | 13 +- src/dusk/entity/componentlist.h | 2 +- src/dusk/scene/scene.c | 14 +- 8 files changed, 40 insertions(+), 189 deletions(-) delete mode 100644 src/dusk/asset/loader/display/assetmeshloader.c delete mode 100644 src/dusk/asset/loader/display/assetmeshloader.h diff --git a/src/dusk/asset/loader/display/CMakeLists.txt b/src/dusk/asset/loader/display/CMakeLists.txt index 391df145..562a1298 100644 --- a/src/dusk/asset/loader/display/CMakeLists.txt +++ b/src/dusk/asset/loader/display/CMakeLists.txt @@ -6,7 +6,6 @@ # Sources target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC - assetmeshloader.c assettextureloader.c assettilesetloader.c ) \ No newline at end of file diff --git a/src/dusk/asset/loader/display/assetmeshloader.c b/src/dusk/asset/loader/display/assetmeshloader.c deleted file mode 100644 index 8c4b907e..00000000 --- a/src/dusk/asset/loader/display/assetmeshloader.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "assetmeshloader.h" -#include "assert/assert.h" -#include "util/memory.h" -#define FAST_OBJ_IMPLEMENTATION -#include "fast_obj.h" - -// Wraps assetfile_t for fast_obj callbacks. Only the primary OBJ file is -// opened through the ZIP; returning NULL for any secondary path (e.g. .mtl) -// causes fast_obj to skip material loading, which is fine for our use case. -static void* meshFileOpen(const char *path, void *user_data) { - assetfile_t *file = (assetfile_t *)user_data; - if(file->zipFile != NULL) return NULL; - errorret_t ret = assetFileOpen(file); - if(ret.code != ERROR_OK) return NULL; - return file; -} - -static void meshFileClose(void *handle, void *user_data) { - if(handle == NULL) return; - assetfile_t *file = (assetfile_t *)handle; - errorCatch(assetFileClose(file)); -} - -static size_t meshFileRead(void *handle, void *dst, size_t bytes, void *user_data) { - if(handle == NULL) return 0; - assetfile_t *file = (assetfile_t *)handle; - errorret_t ret = assetFileRead(file, dst, bytes); - if(ret.code != ERROR_OK) return 0; - return (size_t)file->lastRead; -} - -static unsigned long meshFileSize(void *handle, void *user_data) { - if(handle == NULL) return 0; - assetfile_t *file = (assetfile_t *)handle; - return (unsigned long)file->size; -} - -errorret_t assetMeshLoader(assetfile_t *file) { - assertNotNull(file, "Asset file cannot be NULL."); - assertNotNull(file->output, "Asset file output cannot be NULL."); - - fastObjCallbacks callbacks = { - .file_open = meshFileOpen, - .file_close = meshFileClose, - .file_read = meshFileRead, - .file_size = meshFileSize, - }; - - fastObjMesh *obj = fast_obj_read_with_callbacks(file->filename, &callbacks, file); - if(obj == NULL) { - errorThrow("Failed to parse OBJ: %s", file->filename); - } - - // Count output vertices, triangulating any polygons via fan decomposition. - int32_t vertexCount = 0; - for(unsigned int i = 0; i < obj->face_count; i++) { - if(obj->face_vertices[i] >= 3) { - vertexCount += (int32_t)(obj->face_vertices[i] - 2) * 3; - } - } - - if(vertexCount == 0) { - fast_obj_destroy(obj); - errorThrow("OBJ has no valid faces: %s", file->filename); - } - - meshvertex_t *vertices = (meshvertex_t *)memoryAllocate( - sizeof(meshvertex_t) * vertexCount - ); - memoryZero(vertices, sizeof(meshvertex_t) * vertexCount); - - int32_t vi = 0; - fastObjIndex *idx = obj->indices; - for(unsigned int fi = 0; fi < obj->face_count; fi++) { - unsigned int fv = obj->face_vertices[fi]; - // Fan triangulation: anchor at idx[0], triangle (0, j, j+1). - for(unsigned int j = 1; j + 1 < fv; j++) { - fastObjIndex corners[3] = { idx[0], idx[j], idx[j + 1] }; - for(int c = 0; c < 3; c++) { - vertices[vi].color = COLOR_WHITE_4B; - - unsigned int p = corners[c].p; - if(p > 0 && p < obj->position_count) { - vertices[vi].pos[0] = obj->positions[p * 3 + 0]; - vertices[vi].pos[1] = obj->positions[p * 3 + 1]; - vertices[vi].pos[2] = obj->positions[p * 3 + 2]; - } - - unsigned int t = corners[c].t; - if(t > 0 && t < obj->texcoord_count) { - vertices[vi].uv[0] = obj->texcoords[t * 2 + 0]; - vertices[vi].uv[1] = obj->texcoords[t * 2 + 1]; - } - - vi++; - } - } - idx += fv; - } - - fast_obj_destroy(obj); - - errorret_t ret = meshInit( - (mesh_t *)file->output, - MESH_PRIMITIVE_TYPE_TRIANGLES, - vertexCount, - vertices - ); - memoryFree(vertices); - return ret; -} - -errorret_t assetMeshLoad(const char_t *path, mesh_t *out) { - return assetLoad(path, assetMeshLoader, NULL, out); -} diff --git a/src/dusk/asset/loader/display/assetmeshloader.h b/src/dusk/asset/loader/display/assetmeshloader.h deleted file mode 100644 index bedef3b1..00000000 --- a/src/dusk/asset/loader/display/assetmeshloader.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "asset/asset.h" -#include "display/mesh/mesh.h" - -/** - * Loads a mesh from an OBJ asset file. - * - * @param file Asset file to load from. - * @return Any error that occurs during loading. - */ -errorret_t assetMeshLoader(assetfile_t *file); - -/** - * Loads a mesh from the specified OBJ asset path. - * - * @param path Path to the OBJ asset. - * @param out Output mesh to load into. - * @return Any error that occurs during loading. - */ -errorret_t assetMeshLoad(const char_t *path, mesh_t *out); diff --git a/src/dusk/engine/engine.c b/src/dusk/engine/engine.c index f5619fd7..886143b7 100644 --- a/src/dusk/engine/engine.c +++ b/src/dusk/engine/engine.c @@ -18,17 +18,16 @@ #include "assert/assert.h" #include "entity/entitymanager.h" #include "game/game.h" - -#include "asset/loader/display/assetmeshloader.h" +#include "display/mesh/quad.h" engine_t ENGINE; -texture_t TEXTURE; -color_t TEXTURE_COLORS[] = { - COLOR_RED, COLOR_GREEN, COLOR_MAGENTA, COLOR_CYAN, - COLOR_BLUE, COLOR_WHITE, COLOR_YELLOW, COLOR_BLACK, - COLOR_CYAN, COLOR_MAGENTA, COLOR_GREEN, COLOR_RED, - COLOR_WHITE, COLOR_BLUE, COLOR_BLACK, COLOR_YELLOW -}; +// texture_t TEXTURE; +// color_t TEXTURE_COLORS[] = { +// COLOR_RED, COLOR_GREEN, COLOR_MAGENTA, COLOR_CYAN, +// COLOR_BLUE, COLOR_WHITE, COLOR_YELLOW, COLOR_BLACK, +// COLOR_CYAN, COLOR_MAGENTA, COLOR_GREEN, COLOR_RED, +// COLOR_WHITE, COLOR_BLUE, COLOR_BLACK, COLOR_YELLOW +// }; entityid_t ent1; componentid_t ent1Pos; componentid_t ent1Mesh; @@ -60,26 +59,25 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { camPos, (vec3){ 0.0f, 0.0f, 0.0f }, (vec3){ 0.0f, 1.0f, 0.0f }, - (vec3){ 300.0f, 300.0f, 300.0f } + (vec3){ 3.0f, 3.0f, 3.0f } ); componentid_t camCam = entityAddComponent(cam, COMPONENT_TYPE_CAMERA); - entityCameraSetZFar(cam, camCam, 5000.0f); + entityCameraSetZFar(cam, camCam, 100.0f); ent1 = entityManagerAdd(); ent1Pos = entityAddComponent(ent1, COMPONENT_TYPE_POSITION); ent1Mesh = entityAddComponent(ent1, COMPONENT_TYPE_MESH); ent1Mat = entityAddComponent(ent1, COMPONENT_TYPE_MATERIAL); - textureInit(&TEXTURE, 4, 4, TEXTURE_FORMAT_RGBA, (texturedata_t){ - .rgbaColors = TEXTURE_COLORS - }); + // textureInit(&TEXTURE, 4, 4, TEXTURE_FORMAT_RGBA, (texturedata_t){ + // .rgbaColors = TEXTURE_COLORS + // }); - mesh_t *mesh = entityMeshGetMesh(ent1, ent1Mesh); - errorChain(assetMeshLoad("test/test.obj", mesh)); + entityMeshSetMesh(ent1, ent1Mesh, &QUAD_MESH_SIMPLE); shadermaterial_t *mat = entityMaterialGetShaderMaterial(ent1, ent1Mat); - mat->unlit.color = COLOR_BLACK; - mat->unlit.texture = &TEXTURE; + mat->unlit.color = COLOR_MAGENTA; + // mat->unlit.texture = &TEXTURE; // EOF diff --git a/src/dusk/entity/component/display/entitymesh.c b/src/dusk/entity/component/display/entitymesh.c index 00953fe5..4ab1f8f2 100644 --- a/src/dusk/entity/component/display/entitymesh.c +++ b/src/dusk/entity/component/display/entitymesh.c @@ -14,7 +14,7 @@ void entityMeshInit( entitymesh_t *comp = componentGetData( entityId, componentId, COMPONENT_TYPE_MESH ); - comp->mesh.vertexCount = 0; + comp->mesh = NULL; } mesh_t * entityMeshGetMesh( @@ -24,18 +24,16 @@ mesh_t * entityMeshGetMesh( entitymesh_t *comp = componentGetData( entityId, componentId, COMPONENT_TYPE_MESH ); - return &comp->mesh; + return comp->mesh; } -void entityMeshDispose( +void entityMeshSetMesh( const entityid_t entityId, - const componentid_t componentId + const componentid_t componentId, + mesh_t *mesh ) { entitymesh_t *comp = componentGetData( entityId, componentId, COMPONENT_TYPE_MESH ); - if(comp->mesh.vertexCount > 0) { - meshDispose(&comp->mesh); - comp->mesh.vertexCount = 0; - } -} + comp->mesh = mesh; +} \ No newline at end of file diff --git a/src/dusk/entity/component/display/entitymesh.h b/src/dusk/entity/component/display/entitymesh.h index c53d4223..83bc0876 100644 --- a/src/dusk/entity/component/display/entitymesh.h +++ b/src/dusk/entity/component/display/entitymesh.h @@ -10,7 +10,7 @@ #include "display/mesh/mesh.h" typedef struct { - mesh_t mesh; + mesh_t *mesh; } entitymesh_t; /** @@ -37,13 +37,14 @@ mesh_t * entityMeshGetMesh( ); /** - * Disposes of the entity mesh component, freeing GPU resources if the mesh - * was initialized. + * Sets the mesh associated with the entity mesh component. * * @param entityId The entity ID. * @param componentId The component ID. + * @param mesh A pointer to the mesh to associate with the entity mesh component. */ -void entityMeshDispose( +void entityMeshSetMesh( const entityid_t entityId, - const componentid_t componentId -); + const componentid_t componentId, + mesh_t *mesh +); \ No newline at end of file diff --git a/src/dusk/entity/componentlist.h b/src/dusk/entity/componentlist.h index 6333b9ec..7c8bbb98 100644 --- a/src/dusk/entity/componentlist.h +++ b/src/dusk/entity/componentlist.h @@ -12,5 +12,5 @@ X(POSITION, entityposition_t, position, entityPositionInit, NULL) X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL) -X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose) +X(MESH, entitymesh_t, mesh, entityMeshInit, NULL) X(MATERIAL, entitymaterial_t, material, entityMaterialInit, NULL) \ No newline at end of file diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index 501b2eab..9a24fbc9 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -64,12 +64,19 @@ errorret_t sceneRender(void) { entityCameraGetProjection(camEnt, camComp, proj); entityPositionGetTransform(camEnt, camPos, view); - // For each mesh. for(entityid_t meshIndex = 0; meshIndex < meshCount; meshIndex++) { entityid_t meshEnt = meshEnts[meshIndex]; + componentid_t meshComp = meshComps[meshIndex]; - componentid_t meshPos = entityGetComponent(meshEnt, COMPONENT_TYPE_POSITION); + mesh_t *mesh = entityMeshGetMesh(meshEnt, meshComp); + if(mesh == NULL) { + continue; + } + + componentid_t meshPos = entityGetComponent( + meshEnt, COMPONENT_TYPE_POSITION + ); if(meshPos == 0xFF) { logError("Mesh entity without entity position found\n"); continue; @@ -99,9 +106,6 @@ errorret_t sceneRender(void) { errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view)); errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model)); errorChain(shaderSetMaterial(shader, material)); - - // Mesh - mesh_t *mesh = entityMeshGetMesh(meshEnt, meshComp); errorChain(meshDraw(mesh, 0, -1)); } }