Mesh component

This commit is contained in:
2026-04-10 10:19:44 -05:00
parent 0778ffb57a
commit 37cfdde1ee
10 changed files with 282 additions and 28 deletions
+2
View File
@@ -10,6 +10,7 @@
#include "scene/scene.h"
#include "display/spritebatch/spritebatch.h"
#include "display/mesh/quad.h"
#include "display/mesh/cube.h"
#include "display/screen/screen.h"
#include "ui/ui.h"
#include "display/text/text.h"
@@ -31,6 +32,7 @@ errorret_t displayInit(void) {
errorChain(displayPlatformInit());
#endif
errorChain(quadInit());
errorChain(cubeInit());
errorChain(frameBufferInitBackBuffer());
errorChain(spriteBatchInit());
errorChain(textInit());
+1
View File
@@ -8,4 +8,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
mesh.c
quad.c
cube.c
)
+98
View File
@@ -0,0 +1,98 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "cube.h"
#include "assert/assert.h"
mesh_t CUBE_MESH_SIMPLE;
meshvertex_t CUBE_MESH_SIMPLE_VERTICES[CUBE_VERTEX_COUNT];
errorret_t cubeInit() {
vec3 min = { 0.0f, 0.0f, 0.0f };
vec3 max = { 1.0f, 1.0f, 1.0f };
cubeBuffer(CUBE_MESH_SIMPLE_VERTICES, min, max, COLOR_WHITE_4B);
errorChain(meshInit(
&CUBE_MESH_SIMPLE,
CUBE_PRIMITIVE_TYPE,
CUBE_VERTEX_COUNT,
CUBE_MESH_SIMPLE_VERTICES
));
errorOk();
}
// Helper macro: set one vertex position, UV and color.
#define CUBE_VERT(i, px, py, pz, u, v) \
vertices[i].pos[0] = (px); \
vertices[i].pos[1] = (py); \
vertices[i].pos[2] = (pz); \
vertices[i].uv[0] = (u); \
vertices[i].uv[1] = (v); \
vertices[i].color = color
void cubeBuffer(
meshvertex_t *vertices,
const vec3 min,
const vec3 max,
const color_t color
) {
assertNotNull(vertices, "Vertices cannot be NULL");
assertNotNull(min, "Min vector cannot be NULL");
assertNotNull(max, "Max vector cannot be NULL");
const float_t x0 = min[0], y0 = min[1], z0 = min[2];
const float_t x1 = max[0], y1 = max[1], z1 = max[2];
// Front face (+Z normal) — CCW when viewed from +Z
CUBE_VERT( 0, x0, y0, z1, 0.0f, 0.0f);
CUBE_VERT( 1, x1, y0, z1, 1.0f, 0.0f);
CUBE_VERT( 2, x1, y1, z1, 1.0f, 1.0f);
CUBE_VERT( 3, x0, y0, z1, 0.0f, 0.0f);
CUBE_VERT( 4, x1, y1, z1, 1.0f, 1.0f);
CUBE_VERT( 5, x0, y1, z1, 0.0f, 1.0f);
// Back face (-Z normal) — CCW when viewed from -Z
CUBE_VERT( 6, x1, y0, z0, 0.0f, 0.0f);
CUBE_VERT( 7, x0, y0, z0, 1.0f, 0.0f);
CUBE_VERT( 8, x0, y1, z0, 1.0f, 1.0f);
CUBE_VERT( 9, x1, y0, z0, 0.0f, 0.0f);
CUBE_VERT(10, x0, y1, z0, 1.0f, 1.0f);
CUBE_VERT(11, x1, y1, z0, 0.0f, 1.0f);
// Right face (+X normal) — CCW when viewed from +X
CUBE_VERT(12, x1, y0, z1, 0.0f, 0.0f);
CUBE_VERT(13, x1, y0, z0, 1.0f, 0.0f);
CUBE_VERT(14, x1, y1, z0, 1.0f, 1.0f);
CUBE_VERT(15, x1, y0, z1, 0.0f, 0.0f);
CUBE_VERT(16, x1, y1, z0, 1.0f, 1.0f);
CUBE_VERT(17, x1, y1, z1, 0.0f, 1.0f);
// Left face (-X normal) — CCW when viewed from -X
CUBE_VERT(18, x0, y0, z0, 0.0f, 0.0f);
CUBE_VERT(19, x0, y0, z1, 1.0f, 0.0f);
CUBE_VERT(20, x0, y1, z1, 1.0f, 1.0f);
CUBE_VERT(21, x0, y0, z0, 0.0f, 0.0f);
CUBE_VERT(22, x0, y1, z1, 1.0f, 1.0f);
CUBE_VERT(23, x0, y1, z0, 0.0f, 1.0f);
// Top face (+Y normal) — CCW when viewed from +Y
CUBE_VERT(24, x0, y1, z1, 0.0f, 0.0f);
CUBE_VERT(25, x1, y1, z1, 1.0f, 0.0f);
CUBE_VERT(26, x1, y1, z0, 1.0f, 1.0f);
CUBE_VERT(27, x0, y1, z1, 0.0f, 0.0f);
CUBE_VERT(28, x1, y1, z0, 1.0f, 1.0f);
CUBE_VERT(29, x0, y1, z0, 0.0f, 1.0f);
// Bottom face (-Y normal) — CCW when viewed from -Y
CUBE_VERT(30, x0, y0, z0, 0.0f, 0.0f);
CUBE_VERT(31, x1, y0, z0, 1.0f, 0.0f);
CUBE_VERT(32, x1, y0, z1, 1.0f, 1.0f);
CUBE_VERT(33, x0, y0, z0, 0.0f, 0.0f);
CUBE_VERT(34, x1, y0, z1, 1.0f, 1.0f);
CUBE_VERT(35, x0, y0, z1, 0.0f, 1.0f);
#undef CUBE_VERT
}
+41
View File
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/mesh/mesh.h"
#include "display/color.h"
#define CUBE_FACE_COUNT 6
#define CUBE_VERTICES_PER_FACE 6
#define CUBE_VERTEX_COUNT (CUBE_FACE_COUNT * CUBE_VERTICES_PER_FACE)
#define CUBE_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES
extern mesh_t CUBE_MESH_SIMPLE;
extern meshvertex_t CUBE_MESH_SIMPLE_VERTICES[CUBE_VERTEX_COUNT];
/**
* Initializes the simple unit cube mesh (0,0,0) to (1,1,1).
*
* @return Error for initialization of the cube mesh.
*/
errorret_t cubeInit();
/**
* Buffers a 3D axis-aligned cube into the provided vertex array.
* Writes CUBE_VERTEX_COUNT vertices (6 faces x 6 vertices, CCW winding).
*
* @param vertices The vertex array to buffer into (must hold CUBE_VERTEX_COUNT).
* @param min The minimum XYZ corner of the cube.
* @param max The maximum XYZ corner of the cube.
* @param color The color applied to all vertices.
*/
void cubeBuffer(
meshvertex_t *vertices,
const vec3 min,
const vec3 max,
const color_t color
);
+12 -1
View File
@@ -19,6 +19,8 @@
#include "entity/entitymanager.h"
#include "game/game.h"
#include "display/mesh/cube.h"
engine_t ENGINE;
errorret_t engineInit(const int32_t argc, const char_t **argv) {
@@ -52,8 +54,17 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
componentid_t camCam = entityAddComponent(cam, COMPONENT_TYPE_CAMERA);
entityid_t ent1 = entityManagerAdd();
componentid_t ent1Pos = entityAddComponent(ent1, COMPONENT_TYPE_POSITION);
componentid_t ent1Mesh = entityAddComponent(ent1, COMPONENT_TYPE_MESH);
mesh_t *mesh = entityMeshGetMesh(ent1, ent1Mesh);
errorChain(meshInit(
mesh,
CUBE_PRIMITIVE_TYPE,
CUBE_VERTEX_COUNT,
CUBE_MESH_SIMPLE_VERTICES
));
entityid_t ent2 = entityManagerAdd();
// EOF
// Run the init script.
@@ -8,4 +8,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
entityposition.c
entitycamera.c
entitymesh.c
)
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entity/entitymanager.h"
void entityMeshInit(
const entityid_t entityId,
const componentid_t componentId
) {
entitymesh_t *comp = componentGetData(
entityId, componentId, COMPONENT_TYPE_MESH
);
comp->mesh.vertexCount = 0;
}
mesh_t * entityMeshGetMesh(
const entityid_t entityId,
const componentid_t componentId
) {
entitymesh_t *comp = componentGetData(
entityId, componentId, COMPONENT_TYPE_MESH
);
return &comp->mesh;
}
void entityMeshDispose(
const entityid_t entityId,
const componentid_t componentId
) {
entitymesh_t *comp = componentGetData(
entityId, componentId, COMPONENT_TYPE_MESH
);
if(comp->mesh.vertexCount > 0) {
meshDispose(&comp->mesh);
comp->mesh.vertexCount = 0;
}
}
@@ -0,0 +1,49 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity/entitybase.h"
#include "display/mesh/mesh.h"
typedef struct {
mesh_t mesh;
} entitymesh_t;
/**
* Initializes the entity mesh component.
*
* @param entityId The entity ID.
* @param componentId The component ID.
*/
void entityMeshInit(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Retrieves the mesh associated with the entity mesh component.
*
* @param entityId The entity ID.
* @param componentId The component ID.
* @return A pointer to the mesh associated with the entity mesh component.
*/
mesh_t * entityMeshGetMesh(
const entityid_t entityId,
const componentid_t componentId
);
/**
* Disposes of the entity mesh component, freeing GPU resources if the mesh
* was initialized.
*
* @param entityId The entity ID.
* @param componentId The component ID.
*/
void entityMeshDispose(
const entityid_t entityId,
const componentid_t componentId
);
+2
View File
@@ -7,6 +7,8 @@
#include "entity/component/display/entityposition.h"
#include "entity/component/display/entitycamera.h"
#include "entity/component/display/entitymesh.h"
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose)
+33 -25
View File
@@ -11,6 +11,7 @@
#include "display/screen/screen.h"
#include "entity/entitymanager.h"
#include "display/shader/shaderunlit.h"
#include "display/mesh/cube.h"
scene_t SCENE;
@@ -31,7 +32,7 @@ errorret_t sceneUpdate(void) {
}
errorret_t sceneRender(void) {
// For each camera
// Get Cameras
entityid_t camEnts[ENTITY_COUNT_MAX];
componentid_t camComps[ENTITY_COUNT_MAX];
entityid_t camCount = componentGetEntitiesWithComponent(
@@ -39,8 +40,17 @@ errorret_t sceneRender(void) {
);
if(camCount == 0) errorOk();
// Matricies
// Get meshes
entityid_t meshEnts[ENTITY_COUNT_MAX];
componentid_t meshComps[ENTITY_COUNT_MAX];
entityid_t meshCount = componentGetEntitiesWithComponent(
COMPONENT_TYPE_MESH, meshEnts, meshComps
);
if(meshCount == 0) errorOk();
// Prep Matricies
mat4 view, proj, model;
errorChain(shaderBind(&SHADER_UNLIT));
for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
entityid_t camEnt = camEnts[camIndex];
@@ -53,31 +63,29 @@ errorret_t sceneRender(void) {
entityCameraGetProjection(camEnt, camComp, proj);
entityPositionGetTransform(camEnt, camPos, view);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, 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);
if(meshPos == 0xFF) {
logError("Mesh entity without entity position found\n");
continue;
}
entityPositionGetTransform(meshEnt, meshPos, model);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
// Mesh
mesh_t *mesh = entityMeshGetMesh(meshEnt, meshComp);
errorChain(meshDraw(mesh, 0, -1));
}
}
glm_mat4_identity(model);
// Shader
errorChain(shaderBind(&SHADER_UNLIT));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
meshvertex_t quadVerts[QUAD_VERTEX_COUNT];
quadBuffer(
quadVerts,
0.0f, 0.0f, 1.0f, 1.0f,
COLOR_WHITE,
0.0f, 0.0f, 1.0f, 1.0f
);
mesh_t mesh;
errorChain(meshInit(
&mesh, MESH_PRIMITIVE_TYPE_TRIANGLES,
QUAD_VERTEX_COUNT, quadVerts
));
errorChain(meshDraw(&mesh, 0, -1));
meshDispose(&mesh);
errorOk();
}