Compare commits

...

5 Commits

Author SHA1 Message Date
YourWishes 4b3826edd9 Cleanup the test mesh 2026-04-13 13:05:39 -05:00
YourWishes bae1ff3759 Allow reaxising mesh 2026-04-13 12:58:54 -05:00
YourWishes fd82486431 Fix dolphin color-less 2026-04-13 12:37:54 -05:00
YourWishes c9cd91cbd8 Make color optional 2026-04-13 12:29:06 -05:00
YourWishes c8abd374fe STL Loader 2026-04-13 11:41:51 -05:00
27 changed files with 574 additions and 122 deletions
-20
View File
@@ -1,20 +0,0 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
include(FetchContent)
if(NOT TARGET fast_obj)
FetchContent_Declare(
fast_obj
GIT_REPOSITORY https://github.com/thisistherk/fast_obj.git
GIT_TAG master
)
FetchContent_MakeAvailable(fast_obj)
endif()
set(fast_obj_FOUND TRUE)
set(FAST_OBJ_INCLUDE_DIRS "${fast_obj_SOURCE_DIR}")
set(FAST_OBJ_LIBRARIES fast_obj)
mark_as_advanced(FAST_OBJ_INCLUDE_DIRS FAST_OBJ_LIBRARIES fast_obj_FOUND)
-9
View File
@@ -32,15 +32,6 @@ if(NOT yyjson_FOUND)
endif()
endif()
if(NOT fast_obj_FOUND)
find_package(fast_obj REQUIRED)
if(fast_obj_FOUND)
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC fast_obj)
else()
message(FATAL_ERROR "fast_obj not found. Please ensure fast_obj is correctly fetched.")
endif()
endif()
if(NOT Lua_FOUND)
find_package(Lua REQUIRED)
if(Lua_FOUND AND NOT TARGET Lua::Lua)
+6 -1
View File
@@ -216,4 +216,9 @@
#define assertStrLenMax(str, len, message) ((void)0)
#define assertStrLenMin(str, len, message) ((void)0)
#endif
#endif
#define assertStructSize(struct, size) \
_Static_assert(sizeof(struct) == size, "Size of " #struct " must be " #size)
// EOF
+14
View File
@@ -8,6 +8,7 @@
#include "asset/asset.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "util/math.h"
errorret_t assetFileInit(
assetfile_t *file,
@@ -70,6 +71,19 @@ errorret_t assetFileRead(
) {
assertNotNull(file, "Asset file cannot be NULL.");
assertNotNull(file->zipFile, "Asset file must be opened before reading.");
if(buffer == NULL) {
size_t bytesRemaining = bufferSize;
uint8_t tempBuffer[256];
while(bytesRemaining > 0) {
size_t chunkSize = mathMin(bytesRemaining, sizeof(tempBuffer));
errorChain(assetFileRead(file, tempBuffer, chunkSize));
file->position += chunkSize;
bytesRemaining -= chunkSize;
}
file->lastRead = bufferSize;
errorOk();
}
// I assume zip_fread takes buffer NULL for skipping?
zip_int64_t bytesRead = zip_fread(file->zipFile, buffer, bufferSize);
@@ -6,6 +6,7 @@
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
assetmeshloader.c
assettextureloader.c
assettilesetloader.c
)
@@ -0,0 +1,182 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset/loader/display/assetmeshloader.h"
#include "asset/asset.h"
#include "assert/assert.h"
#include "util/endian.h"
#include "util/memory.h"
errorret_t assetMeshLoader(assetfile_t *file) {
assertNotNull(file, "Asset file cannot be null");
assetmeshoutput_t *output = (assetmeshoutput_t *)file->output;
assertNotNull(output, "Output cannot be null");
assertNotNull(output->outMesh, "Output mesh cannot be null");
assertNotNull(output->outVertices, "Output vertices cannot be null");
// STL file loading
errorChain(assetFileOpen(file));
// Skip the 80 byte header
errorChain(assetFileRead(file, NULL, 80));
if(file->lastRead != 80) errorThrow("Failed to skip STL header");
uint32_t triangleCount;
errorChain(assetFileRead(file, &triangleCount, sizeof(uint32_t)));
if(file->lastRead != sizeof(uint32_t)) errorThrow("Failed read tri count");
// normalize
triangleCount = endianLittleToHost32(triangleCount);
// Allocate mesh and vertex data
errorret_t ret;
meshvertex_t *verts = memoryAllocate(
sizeof(meshvertex_t) * triangleCount * 3
);
*output->outVertices = verts;
// Read triangle data
for(uint32_t i = 0; i < triangleCount; i++) {
assetmeshstltriangle_t triData;
ret = assetFileRead(file, &triData, sizeof(triData));
if(ret.code != ERROR_OK) {
memoryFree(verts);
errorChain(ret);
}
if(file->lastRead != sizeof(triData)) {
memoryFree(verts);
errorThrow("Failed to read triangle data");
}
// Skip normals, we don't use them
// Fix endianess of of data
for(uint8_t j = 0; j < 3; j++) {
#if MESH_ENABLE_COLOR
verts[i * 3 + j].color.r = (uint8_t)(endianLittleToHostFloat(
triData.normal[0]
) * 255.0f);
verts[i * 3 + j].color.g = (uint8_t)(endianLittleToHostFloat(
triData.normal[1]
) * 255.0f);
verts[i * 3 + j].color.b = (uint8_t)(endianLittleToHostFloat(
triData.normal[2]
) * 255.0f);
verts[i * 3 + j].color.a = 0xFF;
#endif
verts[i * 3 + j].uv[0] = 0.0f; // No UV data in STL, just set to 0
verts[i * 3 + j].uv[1] = 0.0f;
for(uint8_t k = 0; k < 3; k++) {
verts[i * 3 + j].pos[k] = endianLittleToHostFloat(
triData.positions[j][k]
);
}
switch(output->inputAxis) {
case MESH_INPUT_AXIS_Z_UP:
// Convert Z-Up to Y-Up
{
float_t temp = verts[i * 3 + j].pos[1];
verts[i * 3 + j].pos[1] = verts[i * 3 + j].pos[2];
verts[i * 3 + j].pos[2] = temp;
}
break;
case MESH_INPUT_AXIS_X_UP:
// Convert X-Up to Y-Up
{
float_t temp = verts[i * 3 + j].pos[0];
verts[i * 3 + j].pos[0] = verts[i * 3 + j].pos[1];
verts[i * 3 + j].pos[1] = temp;
}
break;
case MESH_INPUT_AXIS_Y_DOWN:
// Invert Y axis
verts[i * 3 + j].pos[1] = -verts[i * 3 + j].pos[1];
break;
case MESH_INPUT_AXIS_Z_DOWN:
// Convert Z-Up to Y-Up and invert Y axis
{
float_t temp = verts[i * 3 + j].pos[1];
verts[i * 3 + j].pos[1] = -verts[i * 3 + j].pos[2];
verts[i * 3 + j].pos[2] = temp;
}
break;
case MESH_INPUT_AXIS_X_DOWN:
// Convert X-Up to Y-Up and invert Y axis
{
float_t temp = verts[i * 3 + j].pos[0];
verts[i * 3 + j].pos[0] = verts[i * 3 + j].pos[1];
verts[i * 3 + j].pos[1] = -temp;
}
break;
case MESH_INPUT_AXIS_Y_UP:
default:
// No covnersion possible / Needed
break;
}
}
}
// Finally, init mesh
ret = meshInit(
output->outMesh,
MESH_PRIMITIVE_TYPE_TRIANGLES,
triangleCount * 3,
verts
);
if(ret.code != ERROR_OK) {
memoryFree(verts);
errorChain(ret);
}
ret = assetFileClose(file);
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(meshDispose(output->outMesh)));
memoryFree(verts);
errorChain(ret);
}
errorOk();
}
errorret_t assetMeshLoadToOutput(
const char_t *path,
assetmeshoutput_t *output
) {
assertNotNull(path, "Path cannot be null");
assertNotNull(output, "Output cannot be null");
assertNotNull(output->outMesh, "Output mesh cannot be null");
assertNotNull(output->outVertices, "Output vertices cannot be null");
return assetLoad(path, &assetMeshLoader, NULL, output);
}
errorret_t assetMeshLoad(
const char_t *path,
mesh_t *outMesh,
meshvertex_t **outVertices,
const assetmeshinputaxis_t inputAxis
) {
assertNotNull(path, "Path cannot be null");
assertNotNull(outMesh, "Output mesh cannot be null");
assertNotNull(outVertices, "Output vertices cannot be null");
assetmeshoutput_t output = {
outMesh,
outVertices,
inputAxis
};
return assetMeshLoadToOutput(path, &output);
}
@@ -0,0 +1,61 @@
/**
* 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"
#include "assert/assert.h"
typedef enum {
MESH_INPUT_AXIS_Y_UP,// Default
MESH_INPUT_AXIS_Z_UP,
MESH_INPUT_AXIS_X_UP,
MESH_INPUT_AXIS_Y_DOWN,
MESH_INPUT_AXIS_Z_DOWN,
MESH_INPUT_AXIS_X_DOWN,
} assetmeshinputaxis_t;
typedef struct {
mesh_t *outMesh;
meshvertex_t **outVertices;
assetmeshinputaxis_t inputAxis;
} assetmeshoutput_t;
#pragma pack(push, 1)
typedef struct {
vec3 normal;
float_t positions[3][3];
uint16_t attributeByteCount;
} assetmeshstltriangle_t;
#pragma pack(pop)
assertStructSize(assetmeshstltriangle_t, 50);
/**
* Loader for mesh assets.
*
* @param file Asset file to load the mesh from.
* @return Any error that occurs during loading.
*/
errorret_t assetMeshLoader(assetfile_t *file);
/**
* Handler for mesh assets.
*
* @param file Asset file to load the mesh from.
* @param outMesh Output mesh to load the data into.
* @param outVertices Output pointer to the vertex data, used for cleanup.
* @param inputAxis The axis orientation of the input mesh data.
* @return Any error that occurs during loading.
*/
errorret_t assetMeshLoad(
const char_t *path,
mesh_t *outMesh,
meshvertex_t **outVertices,
const assetmeshinputaxis_t inputAxis
);
+16 -7
View File
@@ -25,13 +25,22 @@ errorret_t cubeInit() {
}
// 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
#if MESH_ENABLE_COLOR
#define CUBE_VERT(i, px, py, pz, u, v) \
vertices[i].color = color; \
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);
#else
#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);
#endif
void cubeBuffer(
meshvertex_t *vertices,
+24
View File
@@ -8,6 +8,7 @@
#include "mesh.h"
#include "util/memory.h"
#include "assert/assert.h"
#include "util/math.h"
errorret_t meshInit(
mesh_t *mesh,
@@ -75,6 +76,29 @@ errorret_t meshDraw(
errorOk();
}
void meshGetBounds(
const mesh_t *mesh,
vec3 outMin,
vec3 outMax
) {
assertNotNull(mesh, "Mesh cannot be NULL");
assertNotNull(outMin, "Output min cannot be NULL");
assertNotNull(outMax, "Output max cannot be NULL");
for(int i = 0; i < 3; i++) {
outMin[i] = FLT_MAX;
outMax[i] = -FLT_MAX;
}
for(uint32_t i = 0; i < mesh->vertexCount; i++) {
meshvertex_t vert = mesh->vertices[i];
for(int j = 0; j < 3; j++) {
outMin[j] = mathMin(outMin[j], vert.pos[j]);
outMax[j] = mathMax(outMax[j], vert.pos[j]);
}
}
}
int32_t meshGetVertexCount(const mesh_t *mesh) {
assertNotNull(mesh, "Mesh cannot be NULL");
return meshGetVertexCountPlatform(mesh);
+13
View File
@@ -70,6 +70,19 @@ errorret_t meshDraw(
const int32_t vertexCount
);
/**
* Gets the axis-aligned bounding box of a mesh.
*
* @param mesh The mesh to get the bounds of.
* @param outMin Output parameter for the minimum corner of the bounding box.
* @param outMax Output parameter for the maximum corner of the bounding box.
*/
void meshGetBounds(
const mesh_t *mesh,
vec3 outMin,
vec3 outMax
);
/**
* Gets the vertex count of a mesh.
*
+8 -1
View File
@@ -9,11 +9,18 @@
#include "dusk.h"
#include "display/color.h"
#ifndef MESH_ENABLE_COLOR
#define MESH_ENABLE_COLOR 0
#endif
#define MESH_VERTEX_UV_SIZE 2
#define MESH_VERTEX_POS_SIZE 3
typedef struct {
color_t color;
#if MESH_ENABLE_COLOR
color_t color;
#endif
float_t uv[MESH_VERTEX_UV_SIZE];
float_t pos[MESH_VERTEX_POS_SIZE];
} meshvertex_t;
+90 -20
View File
@@ -10,13 +10,55 @@
mesh_t QUAD_MESH_SIMPLE;
meshvertex_t QUAD_MESH_SIMPLE_VERTICES[QUAD_VERTEX_COUNT] = {
{ .color = COLOR_WHITE_4B, .uv = { 0.0f, 0.0f }, .pos = { 0.0f, 0.0f, 0.0f } },
{ .color = COLOR_WHITE_4B, .uv = { 1.0f, 0.0f }, .pos = { 1.0f, 0.0f, 0.0f } },
{ .color = COLOR_WHITE_4B, .uv = { 1.0f, 1.0f }, .pos = { 1.0f, 1.0f, 0.0f } },
{
#if MESH_ENABLE_COLOR
.color = COLOR_WHITE_4B,
#endif
{ .color = COLOR_WHITE_4B, .uv = { 0.0f, 0.0f }, .pos = { 0.0f, 0.0f, 0.0f } },
{ .color = COLOR_WHITE_4B, .uv = { 1.0f, 1.0f }, .pos = { 1.0f, 1.0f, 0.0f } },
{ .color = COLOR_WHITE_4B, .uv = { 0.0f, 1.0f }, .pos = { 0.0f, 1.0f, 0.0f } }
.uv = { 0.0f, 0.0f },
.pos = { 0.0f, 0.0f, 0.0f }
},
{
#if MESH_ENABLE_COLOR
.color = COLOR_WHITE_4B,
#endif
.uv = { 1.0f, 0.0f },
.pos = { 1.0f, 0.0f, 0.0f }
},
{
#if MESH_ENABLE_COLOR
.color = COLOR_WHITE_4B,
#endif
.uv = { 1.0f, 1.0f },
.pos = { 1.0f, 1.0f, 0.0f }
},
{
#if MESH_ENABLE_COLOR
.color = COLOR_WHITE_4B,
#endif
.uv = { 0.0f, 0.0f },
.pos = { 0.0f, 0.0f, 0.0f }
},
{
#if MESH_ENABLE_COLOR
.color = COLOR_WHITE_4B,
#endif
.uv = { 1.0f, 1.0f },
.pos = { 1.0f, 1.0f, 0.0f }
},
{
#if MESH_ENABLE_COLOR
.color = COLOR_WHITE_4B,
#endif
.uv = { 0.0f, 1.0f },
.pos = { 0.0f, 1.0f, 0.0f }
}
};
errorret_t quadInit() {
@@ -35,7 +77,9 @@ void quadBuffer(
const float_t minY,
const float_t maxX,
const float_t maxY,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const float_t u0,
const float_t v0,
const float_t u1,
@@ -45,21 +89,27 @@ void quadBuffer(
assertNotNull(vertices, "Vertices cannot be NULL");
// First triangle
vertices[0].color = color;
#if MESH_ENABLE_COLOR
vertices[0].color = color;
#endif
vertices[0].uv[0] = u0;
vertices[0].uv[1] = v1;
vertices[0].pos[0] = minX;
vertices[0].pos[1] = maxY;
vertices[0].pos[2] = z;
vertices[1].color = color;
#if MESH_ENABLE_COLOR
vertices[1].color = color;
#endif
vertices[1].uv[0] = u1;
vertices[1].uv[1] = v0;
vertices[1].pos[0] = maxX;
vertices[1].pos[1] = minY;
vertices[1].pos[2] = z;
vertices[2].color = color;
#if MESH_ENABLE_COLOR
vertices[2].color = color;
#endif
vertices[2].uv[0] = u0;
vertices[2].uv[1] = v0;
vertices[2].pos[0] = minX;
@@ -67,21 +117,27 @@ void quadBuffer(
vertices[2].pos[2] = z;
// Second triangle
vertices[3].color = color;
#if MESH_ENABLE_COLOR
vertices[3].color = color;
#endif
vertices[3].uv[0] = u0;
vertices[3].uv[1] = v1;
vertices[3].pos[0] = minX;
vertices[3].pos[1] = maxY;
vertices[3].pos[2] = z;
vertices[4].color = color;
#if MESH_ENABLE_COLOR
vertices[4].color = color;
#endif
vertices[4].uv[0] = u1;
vertices[4].uv[1] = v1;
vertices[4].pos[0] = maxX;
vertices[4].pos[1] = maxY;
vertices[4].pos[2] = z;
vertices[5].color = color;
#if MESH_ENABLE_COLOR
vertices[5].color = color;
#endif
vertices[5].uv[0] = u1;
vertices[5].uv[1] = v0;
vertices[5].pos[0] = maxX;
@@ -93,7 +149,9 @@ void quadBuffer3D(
meshvertex_t *vertices,
const vec3 min,
const vec3 max,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const vec2 uvMin,
const vec2 uvMax
) {
@@ -104,21 +162,27 @@ void quadBuffer3D(
assertNotNull(uvMax, "UV Max vector cannot be NULL");
// First triangle
vertices[0].color = color;
#if MESH_ENABLE_COLOR
vertices[0].color = color;
#endif
vertices[0].uv[0] = uvMin[0];
vertices[0].uv[1] = uvMin[1];
vertices[0].pos[0] = min[0];
vertices[0].pos[1] = min[1];
vertices[0].pos[2] = min[2];
vertices[1].color = color;
#if MESH_ENABLE_COLOR
vertices[1].color = color;
#endif
vertices[1].uv[0] = uvMax[0];
vertices[1].uv[1] = uvMin[1];
vertices[1].pos[0] = max[0];
vertices[1].pos[1] = min[1];
vertices[1].pos[2] = min[2];
vertices[2].color = color;
#if MESH_ENABLE_COLOR
vertices[2].color = color;
#endif
vertices[2].uv[0] = uvMax[0];
vertices[2].uv[1] = uvMax[1];
vertices[2].pos[0] = max[0];
@@ -126,21 +190,27 @@ void quadBuffer3D(
vertices[2].pos[2] = min[2];
// Second triangle
vertices[3].color = color;
#if MESH_ENABLE_COLOR
vertices[3].color = color;
#endif
vertices[3].uv[0] = uvMin[0];
vertices[3].uv[1] = uvMin[1];
vertices[3].pos[0] = min[0];
vertices[3].pos[1] = min[1];
vertices[3].pos[2] = min[2];
vertices[4].color = color;
#if MESH_ENABLE_COLOR
vertices[4].color = color;
#endif
vertices[4].uv[0] = uvMax[0];
vertices[4].uv[1] = uvMax[1];
vertices[4].pos[0] = max[0];
vertices[4].pos[1] = max[1];
vertices[4].pos[2] = min[2];
vertices[5].color = color;
#if MESH_ENABLE_COLOR
vertices[5].color = color;
#endif
vertices[5].uv[0] = uvMin[0];
vertices[5].uv[1] = uvMax[1];
vertices[5].pos[0] = min[0];
+6 -2
View File
@@ -42,7 +42,9 @@ void quadBuffer(
const float_t minY,
const float_t maxX,
const float_t maxY,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const float_t u0,
const float_t v0,
const float_t u1,
@@ -63,7 +65,9 @@ void quadBuffer3D(
meshvertex_t *vertices,
const vec3 min,
const vec3 max,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const vec2 uvMin,
const vec2 uvMax
);
+6 -2
View File
@@ -26,7 +26,9 @@ errorret_t screenInit() {
SCREEN.frameBufferMeshVertices,
0.0f, 0.0f,
1.0f, 1.0f,
COLOR_WHITE,
#if MESH_ENABLE_COLOR
COLOR_WHITE,
#endif
0.0f, 0.0f,
1.0f, 1.0f
);
@@ -361,7 +363,9 @@ errorret_t screenRender() {
SCREEN.frameBufferMeshVertices,
centerX - fbWidth * 0.5f, centerY + fbHeight * 0.5f, // top-left
centerX + fbWidth * 0.5f, centerY - fbHeight * 0.5f, // bottom-right
COLOR_WHITE,
#if MESH_ENABLE_COLOR
COLOR_WHITE,
#endif
0.0f, 0.0f,
1.0f, 1.0f
);
+14 -4
View File
@@ -29,7 +29,9 @@ errorret_t spriteBatchPush(
const float_t minY,
const float_t maxX,
const float_t maxY,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const float_t u0,
const float_t v0,
const float_t u1,
@@ -38,7 +40,9 @@ errorret_t spriteBatchPush(
return spriteBatchPush3D(
(vec3){ minX, minY, 0 },
(vec3){ maxX, maxY, 0 },
color,
#if MESH_ENABLE_COLOR
color,
#endif
(vec2){ u0, v0 },
(vec2){ u1, v1 }
);
@@ -47,7 +51,9 @@ errorret_t spriteBatchPush(
errorret_t spriteBatchPush3D(
const vec3 min,
const vec3 max,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const vec2 uv0,
const vec2 uv1
) {
@@ -62,7 +68,11 @@ errorret_t spriteBatchPush3D(
) * QUAD_VERTEX_COUNT;
quadBuffer3D(
&SPRITEBATCH_VERTICES[vertexOffset],
min, max, color, uv0, uv1
min, max,
#if MESH_ENABLE_COLOR
color,
#endif
uv0, uv1
);
SPRITEBATCH.spriteCount++;
errorOk();
+6 -2
View File
@@ -57,7 +57,9 @@ errorret_t spriteBatchPush(
const float_t minY,
const float_t maxX,
const float_t maxY,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const float_t u0,
const float_t v0,
const float_t u1,
@@ -78,7 +80,9 @@ errorret_t spriteBatchPush(
errorret_t spriteBatchPush3D(
const vec3 min,
const vec3 max,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const vec2 uvMin,
const vec2 uvMax
);
+16 -4
View File
@@ -33,7 +33,9 @@ errorret_t textDrawChar(
const float_t x,
const float_t y,
const char_t c,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const tileset_t *tileset,
texture_t *texture
) {
@@ -55,7 +57,9 @@ errorret_t textDrawChar(
x, y,
x + tileset->tileWidth,
y + tileset->tileHeight,
color,
#if MESH_ENABLE_COLOR
color,
#endif
uv[0], uv[1], uv[2], uv[3]
));
errorOk();
@@ -66,7 +70,9 @@ errorret_t textDraw(
const float_t x,
const float_t y,
const char_t *text,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const tileset_t *tileset,
texture_t *texture
) {
@@ -100,7 +106,13 @@ errorret_t textDraw(
continue;
}
errorChain(textDrawChar(posX, posY, c, color, tileset, texture));
errorChain(textDrawChar(
posX, posY, c,
#if MESH_ENABLE_COLOR
color,
#endif
tileset, texture
));
posX += tileset->tileWidth;
}
errorOk();
+6 -2
View File
@@ -44,7 +44,9 @@ errorret_t textDrawChar(
const float_t x,
const float_t y,
const char_t c,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const tileset_t *tileset,
texture_t *texture
);
@@ -64,7 +66,9 @@ errorret_t textDraw(
const float_t x,
const float_t y,
const char_t *text,
const color_t color,
#if MESH_ENABLE_COLOR
const color_t color,
#endif
const tileset_t *tileset,
texture_t *texture
);
+25 -17
View File
@@ -20,19 +20,17 @@
#include "game/game.h"
#include "display/mesh/quad.h"
#include "asset/loader/display/assetmeshloader.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
// };
entityid_t ent1;
componentid_t ent1Pos;
componentid_t ent1Mesh;
componentid_t ent1Mat;
mesh_t loadedMesh;
meshvertex_t *loadedVertices;
errorret_t engineInit(const int32_t argc, const char_t **argv) {
memoryZero(&ENGINE, sizeof(engine_t));
ENGINE.running = true;
@@ -54,30 +52,37 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
// FOF
entityid_t cam = entityManagerAdd();
componentid_t camPos = entityAddComponent(cam, COMPONENT_TYPE_POSITION);
float_t distance = 1.5f;
float_t up = distance / 2.0f;
entityPositionLookAt(
cam,
camPos,
(vec3){ 0.0f, 0.0f, 0.0f },
(vec3){ 0.0f, up, 0.0f },
(vec3){ 0.0f, 1.0f, 0.0f },
(vec3){ 3.0f, 3.0f, 3.0f }
(vec3){ distance, distance + up, distance }
);
componentid_t camCam = entityAddComponent(cam, COMPONENT_TYPE_CAMERA);
entityCameraSetZFar(cam, camCam, 100.0f);
entityCameraSetZFar(cam, camCam, distance * 5.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
// });
entityMeshSetMesh(ent1, ent1Mesh, &QUAD_MESH_SIMPLE);
errorChain(assetMeshLoad(
"test/Mei.stl",
&loadedMesh,
&loadedVertices,
MESH_INPUT_AXIS_Y_UP
));
entityMeshSetMesh(ent1, ent1Mesh, &loadedMesh);
vec3 min, max;
meshGetBounds(&loadedMesh, min, max);
printf("Mesh bounds: min(%f, %f, %f), max(%f, %f, %f)\n", min[0], min[1], min[2], max[0], max[1], max[2]);
shadermaterial_t *mat = entityMaterialGetShaderMaterial(ent1, ent1Mat);
mat->unlit.color = COLOR_MAGENTA;
// mat->unlit.texture = &TEXTURE;
mat->unlit.color = COLOR_WHITE;
// EOF
@@ -118,6 +123,9 @@ void engineExit(void) {
}
errorret_t engineDispose(void) {
errorChain(meshDispose(&loadedMesh));
memoryFree(loadedVertices);
sceneDispose();
errorChain(gameDispose());
entityManagerDispose();
@@ -84,7 +84,9 @@ int moduleSpriteBatchPush(lua_State *L) {
minY,
maxX,
maxY,
color == NULL ? COLOR_WHITE : *color,
#if MESH_ENABLE_COLOR
color == NULL ? COLOR_WHITE : *color,
#endif
u0,
v0,
u1,
+3 -1
View File
@@ -52,7 +52,9 @@ int moduleTextDraw(lua_State *L) {
x,
y,
text,
color == NULL ? COLOR_WHITE : *color,
#if MESH_ENABLE_COLOR
color == NULL ? COLOR_WHITE : *color,
#endif
&DEFAULT_FONT_TILESET,
&DEFAULT_FONT_TEXTURE
);
+7
View File
@@ -8,12 +8,19 @@
#include "memory.h"
#include "assert/assert.h"
#include "util/math.h"
#include "log/log.h"
size_t memoryGetAllocatedCount(void) {
return MEMORY_POINTERS_IN_USE;
}
void * memoryAllocate(const size_t size) {
logDebug(
"Attempt to allocate %u bytes (%.2fKB) of memory\n",
size,
size / 1024.0f
);
assertTrue(size > 0, "Cannot allocate 0 bytes of memory.");
void *ptr = malloc(size);
assertNotNull(ptr, "Memory allocation failed.");
+6 -2
View File
@@ -85,10 +85,14 @@ errorret_t displayInitDolphin(void) {
// Describe mesh vertex format.
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_INDEX16);
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16);
#if MESH_ENABLE_COLOR
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16);
#endif
GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
#if MESH_ENABLE_COLOR
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
#endif
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
errorOk();
+17 -5
View File
@@ -43,9 +43,14 @@ errorret_t meshDrawDolphin(
// Matches vertex format described in displaydolphin.c
assertTrue(sizeof(color_t) == 4, "color_t must be exactly 4 bytes");
assertTrue(offsetof(meshvertex_t, color) == 0, "color offset wrong");
assertTrue(offsetof(meshvertex_t, uv) == 4, "uv offset wrong");
assertTrue(offsetof(meshvertex_t, pos) == 12, "pos offset wrong");
#if MESH_ENABLE_COLOR
assertTrue(offsetof(meshvertex_t, color) == 0, "color offset wrong");
assertTrue(offsetof(meshvertex_t, uv) == 4, "uv offset wrong");
assertTrue(offsetof(meshvertex_t, pos) == 12, "pos offset wrong");
#else
assertTrue(offsetof(meshvertex_t, uv) == 0, "uv offset wrong");
assertTrue(offsetof(meshvertex_t, pos) == 8, "pos offset wrong");
#endif
DCFlushRange(
(void*)&mesh->vertices[vertexOffset],
@@ -57,7 +62,12 @@ errorret_t meshDrawDolphin(
const uint8_t stride = (uint8_t)sizeof(meshvertex_t);
GX_SetArray(GX_VA_POS, (void*)&mesh->vertices[vertexOffset].pos[0], stride);
GX_SetArray(GX_VA_CLR0, (void*)&mesh->vertices[vertexOffset].color.r, stride);
#if MESH_ENABLE_COLOR
GX_SetArray(
GX_VA_CLR0,
(void*)&mesh->vertices[vertexOffset].color.r, stride
);
#endif
GX_SetArray(GX_VA_TEX0, (void*)&mesh->vertices[vertexOffset].uv[0], stride);
GX_InvVtxCache();
@@ -65,7 +75,9 @@ errorret_t meshDrawDolphin(
GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)vertexCount);
for(uint16_t i = 0; i < (uint16_t)vertexCount; ++i) {
GX_Position1x16(i);
GX_Color1x16(i);
#if MESH_ENABLE_COLOR
GX_Color1x16(i);
#endif
GX_TexCoord1x16(i);
}
GX_End();
+28 -19
View File
@@ -26,8 +26,11 @@ errorret_t meshInitGL(
#ifdef DUSK_OPENGL_LEGACY
// Nothing needed.
glEnableClientState(GL_COLOR_ARRAY);
errorChain(errorGLCheck());
#if MESH_ENABLE_COLOR
glEnableClientState(GL_COLOR_ARRAY);
errorChain(errorGLCheck());
#endif
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
errorChain(errorGLCheck());
glEnableClientState(GL_VERTEX_ARRAY);
@@ -79,17 +82,19 @@ errorret_t meshInitGL(
glEnableVertexAttribArray(1);
errorChain(errorGLCheck());
glVertexAttribPointer(
2,
sizeof(color_t) / sizeof(GLubyte),
GL_UNSIGNED_BYTE,
GL_TRUE,
sizeof(meshvertex_t),
(const GLvoid*)offsetof(meshvertex_t, color)
);
errorChain(errorGLCheck());
glEnableVertexAttribArray(2);
errorChain(errorGLCheck());
#if MESH_ENABLE_COLOR
glVertexAttribPointer(
2,
sizeof(color_t) / sizeof(GLubyte),
GL_UNSIGNED_BYTE,
GL_TRUE,
sizeof(meshvertex_t),
(const GLvoid*)offsetof(meshvertex_t, color)
);
errorChain(errorGLCheck());
glEnableVertexAttribArray(2);
errorChain(errorGLCheck());
#endif
// Unbind VAO and VBO to prevent accidental modification
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -133,18 +138,22 @@ errorret_t meshDrawGL(
// Legacy pointer style rendering
const GLsizei stride = sizeof(meshvertex_t);
glColorPointer(
sizeof(color4b_t),
GL_UNSIGNED_BYTE,
stride,
(const GLvoid*)&mesh->vertices[offset].color
);
#if MESH_ENABLE_COLOR
glColorPointer(
sizeof(color4b_t),
GL_UNSIGNED_BYTE,
stride,
(const GLvoid*)&mesh->vertices[offset].color
);
#endif
glTexCoordPointer(
MESH_VERTEX_UV_SIZE,
GL_FLOAT,
stride,
(const GLvoid*)&mesh->vertices[offset].uv[0]
);
glVertexPointer(
MESH_VERTEX_POS_SIZE,
GL_FLOAT,
+1
View File
@@ -311,6 +311,7 @@ errorret_t shaderSetColorGL(
// errorChain(errorGLCheck());
// glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
// errorChain(errorGLCheck());
#else
GLint location;
errorChain(shaderParamGetLocationGL(shader, name, &location));
+15 -3
View File
@@ -90,7 +90,9 @@
// Attributes
"layout(location = 0) in vec3 a_Pos;\n"
"layout(location = 1) in vec2 a_TexCoord;\n"
"layout(location = 2) in vec4 a_Color;\n"
#if MESH_ENABLE_COLOR
"layout(location = 2) in vec4 a_Color;\n"
#endif
// Uniforms
"uniform mat4 u_Proj;\n"
"uniform mat4 u_View;\n"
@@ -100,7 +102,11 @@
"out vec2 v_TexCoord;\n"
"void main() {\n"
" gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0);\n"
#if MESH_ENABLE_COLOR
" v_Color = a_Color;\n"
#else
" v_Color = vec4(1.0);\n"
#endif
" v_TexCoord = a_TexCoord;\n"
"}\n",
#else
@@ -108,7 +114,9 @@
// Attributes
"layout(location = 0) in vec3 a_Pos;\n"
"layout(location = 1) in vec2 a_TexCoord;\n"
"layout(location = 2) in vec4 a_Color;\n"
#if MESH_ENABLE_COLOR
"layout(location = 2) in vec4 a_Color;\n"
#endif
// Uniforms
"uniform mat4 u_Proj;\n"
"uniform mat4 u_View;\n"
@@ -118,7 +126,11 @@
"out vec2 v_TexCoord;\n"
"void main() {\n"
" gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0);\n"
" v_Color = a_Color;\n"
#if MESH_ENABLE_COLOR
" v_Color = a_Color;\n"
#else
" v_Color = vec4(1.0);\n"
#endif
" v_TexCoord = a_TexCoord;\n"
"}\n",
#endif