Mesh component
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
#include "display/mesh/quad.h"
|
#include "display/mesh/quad.h"
|
||||||
|
#include "display/mesh/cube.h"
|
||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "display/text/text.h"
|
#include "display/text/text.h"
|
||||||
@@ -31,6 +32,7 @@ errorret_t displayInit(void) {
|
|||||||
errorChain(displayPlatformInit());
|
errorChain(displayPlatformInit());
|
||||||
#endif
|
#endif
|
||||||
errorChain(quadInit());
|
errorChain(quadInit());
|
||||||
|
errorChain(cubeInit());
|
||||||
errorChain(frameBufferInitBackBuffer());
|
errorChain(frameBufferInitBackBuffer());
|
||||||
errorChain(spriteBatchInit());
|
errorChain(spriteBatchInit());
|
||||||
errorChain(textInit());
|
errorChain(textInit());
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
mesh.c
|
mesh.c
|
||||||
quad.c
|
quad.c
|
||||||
|
cube.c
|
||||||
)
|
)
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
);
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
#include "entity/entitymanager.h"
|
#include "entity/entitymanager.h"
|
||||||
#include "game/game.h"
|
#include "game/game.h"
|
||||||
|
|
||||||
|
#include "display/mesh/cube.h"
|
||||||
|
|
||||||
engine_t ENGINE;
|
engine_t ENGINE;
|
||||||
|
|
||||||
errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
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);
|
componentid_t camCam = entityAddComponent(cam, COMPONENT_TYPE_CAMERA);
|
||||||
|
|
||||||
entityid_t ent1 = entityManagerAdd();
|
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
|
// EOF
|
||||||
|
|
||||||
// Run the init script.
|
// Run the init script.
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
entityposition.c
|
entityposition.c
|
||||||
entitycamera.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
|
||||||
|
);
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "entity/component/display/entityposition.h"
|
#include "entity/component/display/entityposition.h"
|
||||||
#include "entity/component/display/entitycamera.h"
|
#include "entity/component/display/entitycamera.h"
|
||||||
|
#include "entity/component/display/entitymesh.h"
|
||||||
|
|
||||||
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
|
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
|
||||||
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
|
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
|
||||||
|
X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose)
|
||||||
+33
-25
@@ -11,6 +11,7 @@
|
|||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
#include "entity/entitymanager.h"
|
#include "entity/entitymanager.h"
|
||||||
#include "display/shader/shaderunlit.h"
|
#include "display/shader/shaderunlit.h"
|
||||||
|
#include "display/mesh/cube.h"
|
||||||
|
|
||||||
scene_t SCENE;
|
scene_t SCENE;
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ errorret_t sceneUpdate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t sceneRender(void) {
|
errorret_t sceneRender(void) {
|
||||||
// For each camera
|
// Get Cameras
|
||||||
entityid_t camEnts[ENTITY_COUNT_MAX];
|
entityid_t camEnts[ENTITY_COUNT_MAX];
|
||||||
componentid_t camComps[ENTITY_COUNT_MAX];
|
componentid_t camComps[ENTITY_COUNT_MAX];
|
||||||
entityid_t camCount = componentGetEntitiesWithComponent(
|
entityid_t camCount = componentGetEntitiesWithComponent(
|
||||||
@@ -39,8 +40,17 @@ errorret_t sceneRender(void) {
|
|||||||
);
|
);
|
||||||
if(camCount == 0) errorOk();
|
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;
|
mat4 view, proj, model;
|
||||||
|
errorChain(shaderBind(&SHADER_UNLIT));
|
||||||
|
|
||||||
for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
|
for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
|
||||||
entityid_t camEnt = camEnts[camIndex];
|
entityid_t camEnt = camEnts[camIndex];
|
||||||
@@ -53,31 +63,29 @@ errorret_t sceneRender(void) {
|
|||||||
|
|
||||||
entityCameraGetProjection(camEnt, camComp, proj);
|
entityCameraGetProjection(camEnt, camComp, proj);
|
||||||
entityPositionGetTransform(camEnt, camPos, view);
|
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();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user