A lot of PSP optimizations

This commit is contained in:
2026-06-30 21:01:11 -05:00
parent 55352805ee
commit 84ebaa0751
44 changed files with 287 additions and 863 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -341,7 +341,7 @@ errorret_t assetUpdate(void) {
continue; continue;
} }
consolePrint("Reaping asset %s", entry->name); // consolePrint("Reaping asset %s", entry->name);
errorChain(assetEntryDispose(entry)); errorChain(assetEntryDispose(entry));
entry++; entry++;
} while(entry < ASSET.entries + ASSET_ENTRY_COUNT_MAX); } while(entry < ASSET.entries + ASSET_ENTRY_COUNT_MAX);
-6
View File
@@ -45,10 +45,4 @@ assetloadercallbacks_t ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = {
.loadAsync = assetChunkLoaderAsync, .loadAsync = assetChunkLoaderAsync,
.dispose = assetChunkDispose .dispose = assetChunkDispose
}, },
[ASSET_LOADER_TYPE_DMF] = {
.loadSync = assetDmfLoaderSync,
.loadAsync = assetDmfLoaderAsync,
.dispose = assetDmfDispose
},
}; };
+9 -15
View File
@@ -6,13 +6,12 @@
*/ */
#pragma once #pragma once
#include "asset/loader/display/assetmeshloader.h" #include "asset/loader/dmf/assetmeshloader.h"
#include "asset/loader/display/assettextureloader.h" #include "asset/loader/display/assettextureloader.h"
#include "asset/loader/display/assettilesetloader.h" #include "asset/loader/display/assettilesetloader.h"
#include "asset/loader/locale/assetlocaleloader.h" #include "asset/loader/locale/assetlocaleloader.h"
#include "asset/loader/json/assetjsonloader.h" #include "asset/loader/json/assetjsonloader.h"
#include "asset/loader/chunk/assetchunkloader.h" #include "asset/loader/chunk/assetchunkloader.h"
#include "asset/loader/dmf/assetdmfloader.h"
typedef enum { typedef enum {
ASSET_LOADER_TYPE_NULL, ASSET_LOADER_TYPE_NULL,
@@ -23,21 +22,10 @@ typedef enum {
ASSET_LOADER_TYPE_LOCALE, ASSET_LOADER_TYPE_LOCALE,
ASSET_LOADER_TYPE_JSON, ASSET_LOADER_TYPE_JSON,
ASSET_LOADER_TYPE_CHUNK, ASSET_LOADER_TYPE_CHUNK,
ASSET_LOADER_TYPE_DMF,
ASSET_LOADER_TYPE_COUNT ASSET_LOADER_TYPE_COUNT
} assetloadertype_t; } assetloadertype_t;
typedef union {
assetmeshloaderinput_t mesh;
assettextureloaderinput_t texture;
assettilesetloaderinput_t tileset;
assetlocaleloaderinput_t locale;
assetjsonloaderinput_t json;
assetchunkloaderinput_t chunk;
assetdmfloaderinput_t dmf;
} assetloaderinput_t;
typedef union { typedef union {
assetmeshloaderloading_t mesh; assetmeshloaderloading_t mesh;
assettextureloaderloading_t texture; assettextureloaderloading_t texture;
@@ -45,7 +33,6 @@ typedef union {
assetlocaleloaderloading_t locale; assetlocaleloaderloading_t locale;
assetjsonloaderloading_t json; assetjsonloaderloading_t json;
assetchunkloaderloading_t chunk; assetchunkloaderloading_t chunk;
assetdmfloaderloading_t dmf;
} assetloaderloading_t; } assetloaderloading_t;
typedef union { typedef union {
@@ -55,9 +42,16 @@ typedef union {
assetlocaleoutput_t locale; assetlocaleoutput_t locale;
assetjsonoutput_t json; assetjsonoutput_t json;
assetchunkoutput_t chunk; assetchunkoutput_t chunk;
assetdmfoutput_t dmf;
} assetloaderoutput_t; } assetloaderoutput_t;
typedef union {
assettextureloaderinput_t texture;
assettilesetloaderinput_t tileset;
assetlocaleloaderinput_t locale;
assetjsonloaderinput_t json;
assetchunkloaderinput_t chunk;
} assetloaderinput_t;
typedef struct assetloading_s assetloading_t; typedef struct assetloading_s assetloading_t;
typedef struct assetentry_s assetentry_t; typedef struct assetentry_s assetentry_t;
@@ -6,7 +6,6 @@
# Sources # Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
assetmeshloader.c
assettextureloader.c assettextureloader.c
assettilesetloader.c assettilesetloader.c
) )
@@ -1,180 +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/endian.h"
#include "util/memory.h"
#include "asset/loader/assetloading.h"
#include "asset/loader/assetentry.h"
errorret_t assetMeshLoaderAsync(assetloading_t *loading) {
assertNotNull(loading, "Loading cannot be NULL");
if(loading->loading.mesh.state != ASSET_MESH_LOADING_STATE_READ_FILE) {
errorOk();
}
assetmeshoutput_t *out = &loading->entry->data.mesh;
assetfile_t *file = &loading->loading.mesh.file;
assetmeshinputaxis_t axis = loading->entry->inputData.mesh;
assetLoaderErrorChain(loading,
assetFileInit(file, loading->entry->name, NULL, NULL)
);
assetLoaderErrorChain(loading, assetFileOpen(file));
// Skip the 80-byte STL header.
assetLoaderErrorChain(loading, assetFileRead(file, NULL, 80));
if(file->lastRead != 80) {
assetLoaderErrorThrow(loading, "Failed to skip STL header.");
}
uint32_t triangleCount;
assetLoaderErrorChain(loading,
assetFileRead(file, &triangleCount, sizeof(uint32_t))
);
if(file->lastRead != sizeof(uint32_t)) {
assetLoaderErrorThrow(loading, "Failed to read tri count");
}
triangleCount = endianLittleToHost32(triangleCount);
out->vertices = memoryAllocate(sizeof(meshvertex_t) * triangleCount * 3);
meshvertex_t *verts = out->vertices;
errorret_t ret;
for(uint32_t i = 0; i < triangleCount; i++) {
assetmeshstltriangle_t triData;
ret = assetFileRead(file, &triData, sizeof(triData));
if(errorIsNotOk(ret)) {
memoryFree(verts);
out->vertices = NULL;
assetLoaderErrorChain(loading, ret);
}
if(file->lastRead != sizeof(triData)) {
memoryFree(verts);
out->vertices = NULL;
assetLoaderErrorThrow(loading, "Failed to read triangle 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;
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(axis) {
case MESH_INPUT_AXIS_Z_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: {
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:
verts[i * 3 + j].pos[1] = -verts[i * 3 + j].pos[1];
break;
case MESH_INPUT_AXIS_Z_DOWN: {
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: {
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:
break;
}
}
}
ret = assetFileClose(file);
if(errorIsNotOk(ret)) {
memoryFree(verts);
out->vertices = NULL;
assetLoaderErrorChain(loading, ret);
}
assetFileDispose(file);
loading->loading.mesh.triangleCount = triangleCount;
loading->loading.mesh.state = ASSET_MESH_LOADING_STATE_CREATE_MESH;
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
errorOk();
}
errorret_t assetMeshLoaderSync(assetloading_t *loading) {
assertNotNull(loading, "Loading cannot be NULL");
assertTrue(loading->type == ASSET_LOADER_TYPE_MESH, "Invalid type.");
switch(loading->loading.mesh.state) {
case ASSET_MESH_LOADING_STATE_INITIAL:
loading->loading.mesh.state = ASSET_MESH_LOADING_STATE_READ_FILE;
loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC;
errorOk();
break;
case ASSET_MESH_LOADING_STATE_CREATE_MESH:
break;
default:
errorOk();
}
assetmeshoutput_t *out = &loading->entry->data.mesh;
assertNotNull(out->vertices, "Mesh vertices should have been loaded by now.");
errorret_t ret = meshInit(
&out->mesh,
MESH_PRIMITIVE_TYPE_TRIANGLES,
loading->loading.mesh.triangleCount * 3,
out->vertices
);
if(errorIsNotOk(ret)) {
loading->entry->state = ASSET_ENTRY_STATE_ERROR;
memoryFree(out->vertices);
out->vertices = NULL;
assetLoaderErrorChain(loading, ret);
}
loading->entry->state = ASSET_ENTRY_STATE_LOADED;
errorOk();
}
errorret_t assetMeshDispose(assetentry_t *entry) {
assertNotNull(entry, "Asset entry cannot be NULL");
assertTrue(entry->type == ASSET_LOADER_TYPE_MESH, "Invalid type.");
errorChain(meshDispose(&entry->data.mesh.mesh));
memoryFree(entry->data.mesh.vertices);
errorOk();
}
@@ -1,58 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/assetfile.h"
#include "display/mesh/mesh.h"
#include "assert/assert.h"
typedef struct assetloading_s assetloading_t;
typedef struct assetentry_s assetentry_t;
typedef enum {
MESH_INPUT_AXIS_Y_UP,
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 assetmeshinputaxis_t assetmeshloaderinput_t;
typedef enum {
ASSET_MESH_LOADING_STATE_INITIAL,
ASSET_MESH_LOADING_STATE_READ_FILE,
ASSET_MESH_LOADING_STATE_CREATE_MESH,
ASSET_MESH_LOADING_STATE_DONE
} assetmeshloadingstate_t;
typedef struct {
assetfile_t file;
assetmeshloadingstate_t state;
uint32_t triangleCount;
} assetmeshloaderloading_t;
typedef struct {
mesh_t mesh;
meshvertex_t *vertices;
} 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);
errorret_t assetMeshLoaderAsync(assetloading_t *loading);
errorret_t assetMeshLoaderSync(assetloading_t *loading);
errorret_t assetMeshDispose(assetentry_t *entry);
+1 -1
View File
@@ -5,5 +5,5 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
assetdmfloader.c assetmeshloader.c
) )
@@ -1,65 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/assetfile.h"
#include "display/mesh/mesh.h"
#define ASSET_DMF_FILE_VERSION 1
typedef struct assetloading_s assetloading_t;
typedef struct assetentry_s assetentry_t;
typedef struct {
void *nothing;
} assetdmfloaderinput_t;
typedef enum {
ASSET_DMF_LOADING_STATE_INITIAL,
ASSET_DMF_LOADING_STATE_READ_FILE,
ASSET_DMF_LOADING_STATE_CREATE_MESH,
ASSET_DMF_LOADING_STATE_DONE
} assetdmfloadingstate_t;
typedef struct {
assetfile_t file;
assetdmfloadingstate_t state;
uint8_t *data;
} assetdmfloaderloading_t;
typedef struct {
mesh_t mesh;
meshvertex_t *vertices;
} assetdmfoutput_t;
/**
* Asynchronous loader for DMF mesh assets. Reads the raw DMF file bytes
* into the loading buffer so the sync phase can parse without blocking
* the main thread on I/O.
*
* @param loading Loading information for the asset being loaded.
* @return Error code indicating success or failure.
*/
errorret_t assetDmfLoaderAsync(assetloading_t *loading);
/**
* Synchronous loader for DMF mesh assets. Parses the DMF binary read by
* the async phase, then initializes and flushes the mesh to the GPU.
*
* @param loading Loading information for the asset being loaded.
* @return Error code indicating success or failure.
*/
errorret_t assetDmfLoaderSync(assetloading_t *loading);
/**
* Disposer for DMF mesh assets. Disposes the mesh and frees the vertex
* buffer.
*
* @param entry Asset entry containing the DMF data to dispose.
* @return Error code indicating success or failure.
*/
errorret_t assetDmfDispose(assetentry_t *entry);
@@ -5,96 +5,92 @@
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "assetdmfloader.h" #include "assetmeshloader.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/endian.h" #include "util/endian.h"
#include "asset/loader/assetloading.h" #include "asset/loader/assetloading.h"
#include "asset/loader/assetentry.h" #include "asset/loader/assetentry.h"
errorret_t assetDmfLoaderAsync(assetloading_t *loading) { errorret_t assetMeshLoaderAsync(assetloading_t *loading) {
assertNotNull(loading, "Loading cannot be NULL"); assertNotNull(loading, "Loading cannot be NULL");
assertNotMainThread("Should be called from an async thread."); assertNotMainThread("Should be called from an async thread.");
if(loading->loading.dmf.state != ASSET_DMF_LOADING_STATE_READ_FILE) { if(loading->loading.mesh.state != ASSET_MESH_LOADING_STATE_READ_FILE) {
errorOk(); errorOk();
} }
assertNull(loading->loading.dmf.data, "Data already defined?"); assertNull(loading->loading.mesh.data, "Data already defined?");
assetfile_t *file = &loading->loading.dmf.file; assetfile_t *file = &loading->loading.mesh.file;
assetLoaderErrorChain(loading, assetLoaderErrorChain(loading,
assetFileInit(file, loading->entry->name, NULL, NULL) assetFileInit(file, loading->entry->name, NULL, NULL)
); );
uint8_t *data = memoryAllocate(file->size); uint8_t *raw = memoryAllocate(file->size);
assetLoaderErrorChain(loading, assetFileOpen(file)); assetLoaderErrorChain(loading, assetFileOpen(file));
assetLoaderErrorChain(loading, assetFileRead(file, data, file->size)); assetLoaderErrorChain(loading, assetFileRead(file, raw, file->size));
assetLoaderErrorChain(loading, assetFileClose(file)); assetLoaderErrorChain(loading, assetFileClose(file));
assetLoaderErrorChain(loading, assetFileDispose(file)); assetLoaderErrorChain(loading, assetFileDispose(file));
assertTrue( assertTrue(file->lastRead == file->size, "Failed to read entire DMF file.");
file->lastRead == file->size,
"Failed to read entire DMF file."
);
loading->loading.dmf.data = data; if(raw[0] != 'D' || raw[1] != 'M' || raw[2] != 'F') {
loading->loading.dmf.state = ASSET_DMF_LOADING_STATE_CREATE_MESH; memoryFree(raw);
assetLoaderErrorThrow(loading, "Invalid DMF file header");
}
uint32_t version = endianLittleToHost32(*(uint32_t *)(raw + 4));
if(version != ASSET_MESH_FILE_VERSION) {
memoryFree(raw);
assetLoaderErrorThrow(loading, "Unsupported DMF version %u", version);
}
uint32_t vertCount = endianLittleToHost32(*(uint32_t *)(raw + 8));
meshvertex_t *vertices = NULL;
if(vertCount > 0) {
vertices = memoryAllocate(vertCount * sizeof(meshvertex_t));
memoryCopy(vertices, raw + 12, vertCount * sizeof(meshvertex_t));
}
memoryFree(raw);
loading->loading.mesh.vertCount = vertCount;
loading->loading.mesh.data = (uint8_t *)vertices;
loading->loading.mesh.state = ASSET_MESH_LOADING_STATE_CREATE_MESH;
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC; loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
errorOk(); errorOk();
} }
errorret_t assetDmfLoaderSync(assetloading_t *loading) { errorret_t assetMeshLoaderSync(assetloading_t *loading) {
assertNotNull(loading, "Loading cannot be NULL"); assertNotNull(loading, "Loading cannot be NULL");
assertTrue(loading->type == ASSET_LOADER_TYPE_DMF, "Invalid type."); assertTrue(loading->type == ASSET_LOADER_TYPE_MESH, "Invalid type.");
assertIsMainThread("Must be called from the main thread."); assertIsMainThread("Must be called from the main thread.");
switch(loading->loading.dmf.state) { switch(loading->loading.mesh.state) {
case ASSET_DMF_LOADING_STATE_INITIAL: case ASSET_MESH_LOADING_STATE_INITIAL:
loading->loading.dmf.state = ASSET_DMF_LOADING_STATE_READ_FILE; loading->loading.mesh.state = ASSET_MESH_LOADING_STATE_READ_FILE;
loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC; loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC;
errorOk(); errorOk();
break; break;
case ASSET_DMF_LOADING_STATE_CREATE_MESH: case ASSET_MESH_LOADING_STATE_CREATE_MESH:
break; break;
default: default:
errorOk(); errorOk();
} }
uint8_t *data = loading->loading.dmf.data; uint32_t vertCount = loading->loading.mesh.vertCount;
assertNotNull(data, "DMF data should have been loaded by now."); meshvertex_t *vertices = (meshvertex_t *)loading->loading.mesh.data;
loading->loading.mesh.data = NULL;
if(data[0] != 'D' || data[1] != 'M' || data[2] != 'F') { assetmeshoutput_t *out = &loading->entry->data.mesh;
memoryFree(data); out->vertices = vertices;
assetLoaderErrorThrow(loading, "Invalid DMF file header");
}
uint32_t version = endianLittleToHost32(*(uint32_t *)(data + 4));
if(version != ASSET_DMF_FILE_VERSION) {
memoryFree(data);
assetLoaderErrorThrow(
loading, "Unsupported DMF version %u", version
);
}
uint32_t vertCount = endianLittleToHost32(*(uint32_t *)(data + 8));
assetdmfoutput_t *out = &loading->entry->data.dmf;
if(vertCount == 0) { if(vertCount == 0) {
memoryFree(data);
loading->loading.dmf.data = NULL;
loading->entry->state = ASSET_ENTRY_STATE_LOADED; loading->entry->state = ASSET_ENTRY_STATE_LOADED;
errorOk(); errorOk();
} }
out->vertices = memoryAllocate(vertCount * sizeof(meshvertex_t));
memoryCopy(
out->vertices, data + 12, vertCount * sizeof(meshvertex_t)
);
memoryFree(data);
loading->loading.dmf.data = NULL;
errorret_t ret = meshInit( errorret_t ret = meshInit(
&out->mesh, &out->mesh,
MESH_PRIMITIVE_TYPE_TRIANGLES, MESH_PRIMITIVE_TYPE_TRIANGLES,
@@ -121,15 +117,15 @@ errorret_t assetDmfLoaderSync(assetloading_t *loading) {
errorOk(); errorOk();
} }
errorret_t assetDmfDispose(assetentry_t *entry) { errorret_t assetMeshDispose(assetentry_t *entry) {
assertNotNull(entry, "Entry cannot be NULL"); assertNotNull(entry, "Entry cannot be NULL");
assertTrue(entry->type == ASSET_LOADER_TYPE_DMF, "Invalid type."); assertTrue(entry->type == ASSET_LOADER_TYPE_MESH, "Invalid type.");
assertIsMainThread("Must be called from the main thread."); assertIsMainThread("Must be called from the main thread.");
assetdmfoutput_t *out = &entry->data.dmf; assetmeshoutput_t *out = &entry->data.mesh;
if(out->vertices != NULL) { if(out->vertices != NULL) {
errorChain(meshDispose(&out->mesh)); errorChain(meshDispose(&out->mesh));
memoryFree(out->vertices); // memoryFree(out->vertices);
out->vertices = NULL; out->vertices = NULL;
} }
errorOk(); errorOk();
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/assetfile.h"
#include "display/mesh/mesh.h"
#define ASSET_MESH_FILE_VERSION 1
typedef struct assetloading_s assetloading_t;
typedef struct assetentry_s assetentry_t;
typedef enum {
ASSET_MESH_LOADING_STATE_INITIAL,
ASSET_MESH_LOADING_STATE_READ_FILE,
ASSET_MESH_LOADING_STATE_CREATE_MESH,
ASSET_MESH_LOADING_STATE_DONE
} assetmeshloadingstate_t;
typedef struct {
assetfile_t file;
assetmeshloadingstate_t state;
uint32_t vertCount;
uint8_t *data;
} assetmeshloaderloading_t;
typedef struct {
mesh_t mesh;
meshvertex_t *vertices;
} assetmeshoutput_t;
/**
* Asynchronous loader for DMF mesh assets. Reads the file, validates the
* header, and prepares a ready-to-use vertex buffer so the sync phase only
* needs to upload to the GPU.
*
* @param loading Loading information for the asset being loaded.
* @return Error code indicating success or failure.
*/
errorret_t assetMeshLoaderAsync(assetloading_t *loading);
/**
* Synchronous loader for DMF mesh assets. Initializes the mesh from the
* vertex buffer prepared by the async phase and flushes it to the GPU.
*
* @param loading Loading information for the asset being loaded.
* @return Error code indicating success or failure.
*/
errorret_t assetMeshLoaderSync(assetloading_t *loading);
/**
* Disposer for DMF mesh assets. Disposes the mesh and frees the vertex
* buffer.
*
* @param entry Asset entry containing the mesh data to dispose.
* @return Error code indicating success or failure.
*/
errorret_t assetMeshDispose(assetentry_t *entry);
+1 -1
View File
@@ -17,7 +17,7 @@ console_t CONSOLE;
void consoleInit(void) { void consoleInit(void) {
memoryZero(&CONSOLE, sizeof(console_t)); memoryZero(&CONSOLE, sizeof(console_t));
CONSOLE.visible = true; CONSOLE.visible = false;
#ifdef DUSK_CONSOLE_POSIX #ifdef DUSK_CONSOLE_POSIX
threadMutexInit(&CONSOLE.printMutex); threadMutexInit(&CONSOLE.printMutex);
-18
View File
@@ -20,9 +20,6 @@ errorret_t capsuleInit() {
0.5f, 0.5f,
CAPSULE_CAP_RINGS, CAPSULE_CAP_RINGS,
CAPSULE_SECTORS CAPSULE_SECTORS
#if MESH_ENABLE_COLOR
, COLOR_WHITE_4B
#endif
); );
errorChain(meshInit( errorChain(meshInit(
&CAPSULE_MESH_SIMPLE, &CAPSULE_MESH_SIMPLE,
@@ -40,9 +37,6 @@ void capsuleBuffer(
const float_t halfHeight, const float_t halfHeight,
const int32_t capRings, const int32_t capRings,
const int32_t sectors const int32_t sectors
#if MESH_ENABLE_COLOR
, const color_t color
#endif
) { ) {
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
assertNotNull(center, "Center vector cannot be NULL"); assertNotNull(center, "Center vector cannot be NULL");
@@ -53,17 +47,6 @@ void capsuleBuffer(
const float_t sectorStep = 2.0f * (float_t)GLM_PI / (float_t)sectors; const float_t sectorStep = 2.0f * (float_t)GLM_PI / (float_t)sectors;
int32_t vi = 0; int32_t vi = 0;
/* Helper macro: write one vertex. */
#if MESH_ENABLE_COLOR
#define CAP_VERT(px, py, pz, u, v) \
vertices[vi].color = color; \
vertices[vi].pos[0] = (px); \
vertices[vi].pos[1] = (py); \
vertices[vi].pos[2] = (pz); \
vertices[vi].uv[0] = (u); \
vertices[vi].uv[1] = (v); \
vi++;
#else
#define CAP_VERT(px, py, pz, u, v) \ #define CAP_VERT(px, py, pz, u, v) \
vertices[vi].pos[0] = (px); \ vertices[vi].pos[0] = (px); \
vertices[vi].pos[1] = (py); \ vertices[vi].pos[1] = (py); \
@@ -71,7 +54,6 @@ void capsuleBuffer(
vertices[vi].uv[0] = (u); \ vertices[vi].uv[0] = (u); \
vertices[vi].uv[1] = (v); \ vertices[vi].uv[1] = (v); \
vi++; vi++;
#endif
/* ---- Top hemisphere ---- */ /* ---- Top hemisphere ---- */
/* phi ranges from PI/2 (top pole) down to 0 (equator). */ /* phi ranges from PI/2 (top pole) down to 0 (equator). */
-4
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "display/color.h"
#define CAPSULE_CAP_RINGS 4 #define CAPSULE_CAP_RINGS 4
#define CAPSULE_SECTORS 16 #define CAPSULE_SECTORS 16
@@ -46,7 +45,4 @@ void capsuleBuffer(
const float_t halfHeight, const float_t halfHeight,
const int32_t capRings, const int32_t capRings,
const int32_t sectors const int32_t sectors
#if MESH_ENABLE_COLOR
, const color_t color
#endif
); );
+1 -20
View File
@@ -14,12 +14,7 @@ meshvertex_t CUBE_MESH_SIMPLE_VERTICES[CUBE_VERTEX_COUNT];
errorret_t cubeInit() { errorret_t cubeInit() {
vec3 min = { 0.0f, 0.0f, 0.0f }; vec3 min = { 0.0f, 0.0f, 0.0f };
vec3 max = { 1.0f, 1.0f, 1.0f }; vec3 max = { 1.0f, 1.0f, 1.0f };
cubeBuffer( cubeBuffer(CUBE_MESH_SIMPLE_VERTICES, min, max);
CUBE_MESH_SIMPLE_VERTICES, min, max
#if MESH_ENABLE_COLOR
, COLOR_WHITE_4B
#endif
);
errorChain(meshInit( errorChain(meshInit(
&CUBE_MESH_SIMPLE, &CUBE_MESH_SIMPLE,
CUBE_PRIMITIVE_TYPE, CUBE_PRIMITIVE_TYPE,
@@ -29,31 +24,17 @@ errorret_t cubeInit() {
errorOk(); errorOk();
} }
// Helper macro: set one vertex position, UV and 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) \ #define CUBE_VERT(i, px, py, pz, u, v) \
vertices[i].pos[0] = (px); \ vertices[i].pos[0] = (px); \
vertices[i].pos[1] = (py); \ vertices[i].pos[1] = (py); \
vertices[i].pos[2] = (pz); \ vertices[i].pos[2] = (pz); \
vertices[i].uv[0] = (u); \ vertices[i].uv[0] = (u); \
vertices[i].uv[1] = (v); vertices[i].uv[1] = (v);
#endif
void cubeBuffer( void cubeBuffer(
meshvertex_t *vertices, meshvertex_t *vertices,
const vec3 min, const vec3 min,
const vec3 max const vec3 max
#if MESH_ENABLE_COLOR
, const color_t color
#endif
) { ) {
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
assertNotNull(min, "Min vector cannot be NULL"); assertNotNull(min, "Min vector cannot be NULL");
-4
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "display/color.h"
#define CUBE_FACE_COUNT 6 #define CUBE_FACE_COUNT 6
#define CUBE_VERTICES_PER_FACE 6 #define CUBE_VERTICES_PER_FACE 6
@@ -37,7 +36,4 @@ void cubeBuffer(
meshvertex_t *vertices, meshvertex_t *vertices,
const vec3 min, const vec3 min,
const vec3 max const vec3 max
#if MESH_ENABLE_COLOR
, const color_t color
#endif
); );
-9
View File
@@ -7,20 +7,11 @@
#pragma once #pragma once
#include "dusk.h" #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_UV_SIZE 2
#define MESH_VERTEX_POS_SIZE 3 #define MESH_VERTEX_POS_SIZE 3
typedef struct { typedef struct {
#if MESH_ENABLE_COLOR
color_t color;
#endif
float_t uv[MESH_VERTEX_UV_SIZE]; float_t uv[MESH_VERTEX_UV_SIZE];
float_t pos[MESH_VERTEX_POS_SIZE]; float_t pos[MESH_VERTEX_POS_SIZE];
} meshvertex_t; } meshvertex_t;
+4 -21
View File
@@ -20,11 +20,8 @@ errorret_t planeInit() {
PLANE_MESH_SIMPLE_VERTICES, PLANE_MESH_SIMPLE_VERTICES,
PLANE_AXIS_XZ, PLANE_AXIS_XZ,
min, min,
max max,
#if MESH_ENABLE_COLOR uvMin,
, COLOR_WHITE_4B
#endif
, uvMin,
uvMax uvMax
); );
errorChain(meshInit( errorChain(meshInit(
@@ -36,33 +33,19 @@ errorret_t planeInit() {
errorOk(); errorOk();
} }
/* Helper macro to write one vertex. */
#if MESH_ENABLE_COLOR
#define PLANE_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 PLANE_VERT(i, px, py, pz, u, v) \ #define PLANE_VERT(i, px, py, pz, u, v) \
vertices[i].pos[0] = (px); \ vertices[i].pos[0] = (px); \
vertices[i].pos[1] = (py); \ vertices[i].pos[1] = (py); \
vertices[i].pos[2] = (pz); \ vertices[i].pos[2] = (pz); \
vertices[i].uv[0] = (u); \ vertices[i].uv[0] = (u); \
vertices[i].uv[1] = (v); vertices[i].uv[1] = (v);
#endif
void planeBuffer( void planeBuffer(
meshvertex_t *vertices, meshvertex_t *vertices,
const planeaxis_t axis, const planeaxis_t axis,
const vec3 min, const vec3 min,
const vec3 max const vec3 max,
#if MESH_ENABLE_COLOR const vec2 uvMin,
, const color_t color
#endif
, const vec2 uvMin,
const vec2 uvMax const vec2 uvMax
) { ) {
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
+2 -6
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "display/color.h"
#define PLANE_VERTEX_COUNT 6 #define PLANE_VERTEX_COUNT 6
#define PLANE_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES #define PLANE_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES
@@ -52,10 +51,7 @@ void planeBuffer(
meshvertex_t *vertices, meshvertex_t *vertices,
const planeaxis_t axis, const planeaxis_t axis,
const vec3 min, const vec3 min,
const vec3 max const vec3 max,
#if MESH_ENABLE_COLOR const vec2 uvMin,
, const color_t color
#endif
, const vec2 uvMin,
const vec2 uvMax const vec2 uvMax
); );
+31 -150
View File
@@ -10,55 +10,12 @@
mesh_t QUAD_MESH_SIMPLE; mesh_t QUAD_MESH_SIMPLE;
meshvertex_t QUAD_MESH_SIMPLE_VERTICES[QUAD_VERTEX_COUNT] = { meshvertex_t QUAD_MESH_SIMPLE_VERTICES[QUAD_VERTEX_COUNT] = {
{ { .uv = { 0.0f, 0.0f }, .pos = { 0.0f, 0.0f, 0.0f } },
#if MESH_ENABLE_COLOR { .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 } },
#endif { .uv = { 0.0f, 0.0f }, .pos = { 0.0f, 0.0f, 0.0f } },
{ .uv = { 1.0f, 1.0f }, .pos = { 1.0f, 1.0f, 0.0f } },
.uv = { 0.0f, 0.0f }, { .uv = { 0.0f, 1.0f }, .pos = { 0.0f, 1.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() { errorret_t quadInit() {
@@ -81,68 +38,27 @@ void quadBuffer(
const float_t v0, const float_t v0,
const float_t u1, const float_t u1,
const float_t v1 const float_t v1
#if MESH_ENABLE_COLOR
, const color_t color
#endif
) { ) {
const float_t z = 0.0f; // Z coordinate for 2D rendering const float_t z = 0.0f;
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
// First triangle vertices[0].uv[0] = u0; vertices[0].uv[1] = v1;
#if MESH_ENABLE_COLOR vertices[0].pos[0] = minX; vertices[0].pos[1] = maxY; vertices[0].pos[2] = z;
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;
#if MESH_ENABLE_COLOR vertices[1].uv[0] = u1; vertices[1].uv[1] = v0;
vertices[1].color = color; vertices[1].pos[0] = maxX; vertices[1].pos[1] = minY; vertices[1].pos[2] = z;
#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;
#if MESH_ENABLE_COLOR vertices[2].uv[0] = u0; vertices[2].uv[1] = v0;
vertices[2].color = color; vertices[2].pos[0] = minX; vertices[2].pos[1] = minY; vertices[2].pos[2] = z;
#endif
vertices[2].uv[0] = u0;
vertices[2].uv[1] = v0;
vertices[2].pos[0] = minX;
vertices[2].pos[1] = minY;
vertices[2].pos[2] = z;
// Second triangle vertices[3].uv[0] = u0; vertices[3].uv[1] = v1;
#if MESH_ENABLE_COLOR vertices[3].pos[0] = minX; vertices[3].pos[1] = maxY; vertices[3].pos[2] = z;
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;
#if MESH_ENABLE_COLOR vertices[4].uv[0] = u1; vertices[4].uv[1] = v1;
vertices[4].color = color; vertices[4].pos[0] = maxX; vertices[4].pos[1] = maxY; vertices[4].pos[2] = z;
#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;
#if MESH_ENABLE_COLOR vertices[5].uv[0] = u1; vertices[5].uv[1] = v0;
vertices[5].color = color; vertices[5].pos[0] = maxX; vertices[5].pos[1] = minY; vertices[5].pos[2] = z;
#endif
vertices[5].uv[0] = u1;
vertices[5].uv[1] = v0;
vertices[5].pos[0] = maxX;
vertices[5].pos[1] = minY;
vertices[5].pos[2] = z;
} }
void quadBuffer3D( void quadBuffer3D(
@@ -151,9 +67,6 @@ void quadBuffer3D(
const vec3 max, const vec3 max,
const vec2 uvMin, const vec2 uvMin,
const vec2 uvMax const vec2 uvMax
#if MESH_ENABLE_COLOR
, const color_t color
#endif
) { ) {
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
assertNotNull(min, "Min vector cannot be NULL"); assertNotNull(min, "Min vector cannot be NULL");
@@ -161,59 +74,27 @@ void quadBuffer3D(
assertNotNull(uvMin, "UV Min vector cannot be NULL"); assertNotNull(uvMin, "UV Min vector cannot be NULL");
assertNotNull(uvMax, "UV Max vector cannot be NULL"); assertNotNull(uvMax, "UV Max vector cannot be NULL");
// First triangle vertices[0].uv[0] = uvMin[0]; vertices[0].uv[1] = uvMin[1];
#if MESH_ENABLE_COLOR vertices[0].pos[0] = min[0]; vertices[0].pos[1] = min[1];
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[0].pos[2] = min[2];
#if MESH_ENABLE_COLOR vertices[1].uv[0] = uvMax[0]; vertices[1].uv[1] = uvMin[1];
vertices[1].color = color; vertices[1].pos[0] = max[0]; vertices[1].pos[1] = min[1];
#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[1].pos[2] = min[2];
#if MESH_ENABLE_COLOR vertices[2].uv[0] = uvMax[0]; vertices[2].uv[1] = uvMax[1];
vertices[2].color = color; vertices[2].pos[0] = max[0]; vertices[2].pos[1] = max[1];
#endif
vertices[2].uv[0] = uvMax[0];
vertices[2].uv[1] = uvMax[1];
vertices[2].pos[0] = max[0];
vertices[2].pos[1] = max[1];
vertices[2].pos[2] = min[2]; vertices[2].pos[2] = min[2];
// Second triangle vertices[3].uv[0] = uvMin[0]; vertices[3].uv[1] = uvMin[1];
#if MESH_ENABLE_COLOR vertices[3].pos[0] = min[0]; vertices[3].pos[1] = min[1];
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[3].pos[2] = min[2];
#if MESH_ENABLE_COLOR vertices[4].uv[0] = uvMax[0]; vertices[4].uv[1] = uvMax[1];
vertices[4].color = color; vertices[4].pos[0] = max[0]; vertices[4].pos[1] = max[1];
#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[4].pos[2] = min[2];
#if MESH_ENABLE_COLOR vertices[5].uv[0] = uvMin[0]; vertices[5].uv[1] = uvMax[1];
vertices[5].color = color; vertices[5].pos[0] = min[0]; vertices[5].pos[1] = max[1];
#endif
vertices[5].uv[0] = uvMin[0];
vertices[5].uv[1] = uvMax[1];
vertices[5].pos[0] = min[0];
vertices[5].pos[1] = max[1];
vertices[5].pos[2] = min[2]; vertices[5].pos[2] = min[2];
} }
-8
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include "mesh.h" #include "mesh.h"
#include "display/color.h"
#define QUAD_VERTEX_COUNT 6 #define QUAD_VERTEX_COUNT 6
#define QUAD_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES #define QUAD_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES
@@ -46,9 +45,6 @@ void quadBuffer(
const float_t v0, const float_t v0,
const float_t u1, const float_t u1,
const float_t v1 const float_t v1
#if MESH_ENABLE_COLOR
, const color_t color
#endif
); );
/** /**
@@ -57,7 +53,6 @@ void quadBuffer(
* @param vertices The vertex array to buffer into. * @param vertices The vertex array to buffer into.
* @param min The minimum XYZ coordinates of the quad. * @param min The minimum XYZ coordinates of the quad.
* @param max The maximum XYZ coordinates of the quad. * @param max The maximum XYZ coordinates of the quad.
* @param color The color of the quad.
* @param uvMin The minimum UV coordinates of the quad. * @param uvMin The minimum UV coordinates of the quad.
* @param uvMax The maximum UV coordinates of the quad. * @param uvMax The maximum UV coordinates of the quad.
*/ */
@@ -67,7 +62,4 @@ void quadBuffer3D(
const vec3 max, const vec3 max,
const vec2 uvMin, const vec2 uvMin,
const vec2 uvMax const vec2 uvMax
#if MESH_ENABLE_COLOR
, const color_t color
#endif
); );
+12 -56
View File
@@ -19,9 +19,6 @@ errorret_t sphereInit() {
0.5f, 0.5f,
SPHERE_STACKS, SPHERE_STACKS,
SPHERE_SECTORS SPHERE_SECTORS
#if MESH_ENABLE_COLOR
, COLOR_WHITE_4B
#endif
); );
errorChain(meshInit( errorChain(meshInit(
&SPHERE_MESH_SIMPLE, &SPHERE_MESH_SIMPLE,
@@ -38,9 +35,6 @@ void sphereBuffer(
const float_t radius, const float_t radius,
const int32_t stacks, const int32_t stacks,
const int32_t sectors const int32_t sectors
#if MESH_ENABLE_COLOR
, const color_t color
#endif
) { ) {
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
assertNotNull(center, "Center vector cannot be NULL"); assertNotNull(center, "Center vector cannot be NULL");
@@ -79,67 +73,29 @@ void sphereBuffer(
const float_t u1 = (float_t)j / (float_t)sectors; const float_t u1 = (float_t)j / (float_t)sectors;
const float_t u2 = (float_t)(j + 1) / (float_t)sectors; const float_t u2 = (float_t)(j + 1) / (float_t)sectors;
/* Triangle 1: top-left, bottom-left, top-right */ vertices[vi].pos[0] = center[0] + x11; vertices[vi].pos[1] = center[1] + y1;
#if MESH_ENABLE_COLOR
vertices[vi].color = color;
#endif
vertices[vi].pos[0] = center[0] + x11;
vertices[vi].pos[1] = center[1] + y1;
vertices[vi].pos[2] = center[2] + z11; vertices[vi].pos[2] = center[2] + z11;
vertices[vi].uv[0] = u1; vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v1; vi++;
vertices[vi].uv[1] = v1;
vi++;
#if MESH_ENABLE_COLOR vertices[vi].pos[0] = center[0] + x21; vertices[vi].pos[1] = center[1] + y2;
vertices[vi].color = color;
#endif
vertices[vi].pos[0] = center[0] + x21;
vertices[vi].pos[1] = center[1] + y2;
vertices[vi].pos[2] = center[2] + z21; vertices[vi].pos[2] = center[2] + z21;
vertices[vi].uv[0] = u1; vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v2; vi++;
vertices[vi].uv[1] = v2;
vi++;
#if MESH_ENABLE_COLOR vertices[vi].pos[0] = center[0] + x12; vertices[vi].pos[1] = center[1] + y1;
vertices[vi].color = color;
#endif
vertices[vi].pos[0] = center[0] + x12;
vertices[vi].pos[1] = center[1] + y1;
vertices[vi].pos[2] = center[2] + z12; vertices[vi].pos[2] = center[2] + z12;
vertices[vi].uv[0] = u2; vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v1; vi++;
vertices[vi].uv[1] = v1;
vi++;
/* Triangle 2: top-right, bottom-left, bottom-right */ vertices[vi].pos[0] = center[0] + x12; vertices[vi].pos[1] = center[1] + y1;
#if MESH_ENABLE_COLOR
vertices[vi].color = color;
#endif
vertices[vi].pos[0] = center[0] + x12;
vertices[vi].pos[1] = center[1] + y1;
vertices[vi].pos[2] = center[2] + z12; vertices[vi].pos[2] = center[2] + z12;
vertices[vi].uv[0] = u2; vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v1; vi++;
vertices[vi].uv[1] = v1;
vi++;
#if MESH_ENABLE_COLOR vertices[vi].pos[0] = center[0] + x21; vertices[vi].pos[1] = center[1] + y2;
vertices[vi].color = color;
#endif
vertices[vi].pos[0] = center[0] + x21;
vertices[vi].pos[1] = center[1] + y2;
vertices[vi].pos[2] = center[2] + z21; vertices[vi].pos[2] = center[2] + z21;
vertices[vi].uv[0] = u1; vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v2; vi++;
vertices[vi].uv[1] = v2;
vi++;
#if MESH_ENABLE_COLOR vertices[vi].pos[0] = center[0] + x22; vertices[vi].pos[1] = center[1] + y2;
vertices[vi].color = color;
#endif
vertices[vi].pos[0] = center[0] + x22;
vertices[vi].pos[1] = center[1] + y2;
vertices[vi].pos[2] = center[2] + z22; vertices[vi].pos[2] = center[2] + z22;
vertices[vi].uv[0] = u2; vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v2; vi++;
vertices[vi].uv[1] = v2;
vi++;
} }
} }
} }
-4
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "display/color.h"
#define SPHERE_STACKS 8 #define SPHERE_STACKS 8
#define SPHERE_SECTORS 16 #define SPHERE_SECTORS 16
@@ -41,7 +40,4 @@ void sphereBuffer(
const float_t radius, const float_t radius,
const int32_t stacks, const int32_t stacks,
const int32_t sectors const int32_t sectors
#if MESH_ENABLE_COLOR
, const color_t color
#endif
); );
+4 -22
View File
@@ -14,13 +14,10 @@ meshvertex_t TRIPRISM_MESH_SIMPLE_VERTICES[TRIPRISM_VERTEX_COUNT];
errorret_t triPrismInit() { errorret_t triPrismInit() {
triPrismBuffer( triPrismBuffer(
TRIPRISM_MESH_SIMPLE_VERTICES, TRIPRISM_MESH_SIMPLE_VERTICES,
0.0f, 0.0f, /* p0: bottom-left */ 0.0f, 0.0f,
1.0f, 0.0f, /* p1: bottom-right */ 1.0f, 0.0f,
0.5f, 1.0f, /* p2: apex */ 0.5f, 1.0f,
0.0f, 1.0f /* minZ, maxZ */ 0.0f, 1.0f
#if MESH_ENABLE_COLOR
, COLOR_WHITE_4B
#endif
); );
errorChain(meshInit( errorChain(meshInit(
&TRIPRISM_MESH_SIMPLE, &TRIPRISM_MESH_SIMPLE,
@@ -38,24 +35,10 @@ void triPrismBuffer(
const float_t x2, const float_t y2, const float_t x2, const float_t y2,
const float_t minZ, const float_t minZ,
const float_t maxZ const float_t maxZ
#if MESH_ENABLE_COLOR
, const color_t color
#endif
) { ) {
assertNotNull(vertices, "Vertices cannot be NULL"); assertNotNull(vertices, "Vertices cannot be NULL");
/* Helper macro: write one vertex then advance index. */
int32_t vi = 0; int32_t vi = 0;
#if MESH_ENABLE_COLOR
#define PRISM_VERT(px, py, pz, u, v) \
vertices[vi].color = color; \
vertices[vi].pos[0] = (px); \
vertices[vi].pos[1] = (py); \
vertices[vi].pos[2] = (pz); \
vertices[vi].uv[0] = (u); \
vertices[vi].uv[1] = (v); \
vi++;
#else
#define PRISM_VERT(px, py, pz, u, v) \ #define PRISM_VERT(px, py, pz, u, v) \
vertices[vi].pos[0] = (px); \ vertices[vi].pos[0] = (px); \
vertices[vi].pos[1] = (py); \ vertices[vi].pos[1] = (py); \
@@ -63,7 +46,6 @@ void triPrismBuffer(
vertices[vi].uv[0] = (u); \ vertices[vi].uv[0] = (u); \
vertices[vi].uv[1] = (v); \ vertices[vi].uv[1] = (v); \
vi++; vi++;
#endif
/* --- Front face (z = maxZ), CCW from +Z --- */ /* --- Front face (z = maxZ), CCW from +Z --- */
PRISM_VERT(x0, y0, maxZ, 0.0f, 0.0f) PRISM_VERT(x0, y0, maxZ, 0.0f, 0.0f)
-4
View File
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "display/color.h"
#define TRIPRISM_VERTEX_COUNT 24 #define TRIPRISM_VERTEX_COUNT 24
#define TRIPRISM_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES #define TRIPRISM_PRIMITIVE_TYPE MESH_PRIMITIVE_TYPE_TRIANGLES
@@ -44,7 +43,4 @@ void triPrismBuffer(
const float_t x2, const float_t y2, const float_t x2, const float_t y2,
const float_t minZ, const float_t minZ,
const float_t maxZ const float_t maxZ
#if MESH_ENABLE_COLOR
, const color_t color
#endif
); );
+2 -8
View File
@@ -37,9 +37,6 @@ errorret_t screenInit() {
1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f 1.0f, 1.0f
#if MESH_ENABLE_COLOR
, COLOR_WHITE
#endif
); );
errorChain(meshInit( errorChain(meshInit(
&SCREEN.frameBufferMesh, &SCREEN.frameBufferMesh,
@@ -383,13 +380,10 @@ errorret_t screenRender() {
quadBuffer( quadBuffer(
SCREEN.frameBufferMeshVertices, SCREEN.frameBufferMeshVertices,
centerX - fbWidth * 0.5f, centerY + fbHeight * 0.5f, // top-left centerX - fbWidth * 0.5f, centerY + fbHeight * 0.5f,
centerX + fbWidth * 0.5f, centerY - fbHeight * 0.5f, // bottom-right centerX + fbWidth * 0.5f, centerY - fbHeight * 0.5f,
0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f 1.0f, 1.0f
#if MESH_ENABLE_COLOR
, COLOR_WHITE
#endif
); );
frameBufferClear( frameBufferClear(
+7
View File
@@ -46,6 +46,13 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
errorChain(sceneInit()); errorChain(sceneInit());
consolePrint("Engine initialized"); consolePrint("Engine initialized");
#ifdef DUSK_ASSERTIONS_FAKED
consolePrint("Assertions faked");
#else
consolePrint("Assertions real");
#endif
sceneSet(SCENE_TYPE_OVERWORLD); sceneSet(SCENE_TYPE_OVERWORLD);
+1
View File
@@ -24,6 +24,7 @@ typedef struct chunk_s {
uint8_t meshCount; uint8_t meshCount;
char_t meshNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX]; char_t meshNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX];
vec3 meshOffsets[CHUNK_MESH_COUNT_MAX]; vec3 meshOffsets[CHUNK_MESH_COUNT_MAX];
mat4 meshModels[CHUNK_MESH_COUNT_MAX];
assetentry_t *meshEntries[CHUNK_MESH_COUNT_MAX]; assetentry_t *meshEntries[CHUNK_MESH_COUNT_MAX];
uint8_t entities[CHUNK_ENTITY_COUNT_MAX]; uint8_t entities[CHUNK_ENTITY_COUNT_MAX];
+14 -3
View File
@@ -140,6 +140,8 @@ void mapChunkUnload(chunk_t *chunk) {
} }
} }
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
if(chunk->dcfEntry != NULL) { if(chunk->dcfEntry != NULL) {
assetUnlockEntry(chunk->dcfEntry); assetUnlockEntry(chunk->dcfEntry);
chunk->dcfEntry = NULL; chunk->dcfEntry = NULL;
@@ -199,6 +201,10 @@ errorret_t mapWaitForChunks() {
chunk->dcfEntry->data.chunk.tiles, chunk->dcfEntry->data.chunk.tiles,
sizeof(chunk->tiles) sizeof(chunk->tiles)
); );
worldpos_t wp;
chunkPosToWorldPos(&chunk->position, &wp);
vec3 wpf = { (float_t)wp.x, (float_t)wp.y, (float_t)wp.z };
for(uint8_t m = 0; m < meshCount; m++) { for(uint8_t m = 0; m < meshCount; m++) {
stringCopy( stringCopy(
chunk->meshNames[m], chunk->meshNames[m],
@@ -209,13 +215,16 @@ errorret_t mapWaitForChunks() {
chunk->dcfEntry->data.chunk.meshOffsets[m], chunk->dcfEntry->data.chunk.meshOffsets[m],
chunk->meshOffsets[m] chunk->meshOffsets[m]
); );
vec3 pos;
glm_vec3_add(wpf, chunk->meshOffsets[m], pos);
glm_translate_make(chunk->meshModels[m], pos);
} }
assetUnlockEntry(chunk->dcfEntry); assetUnlockEntry(chunk->dcfEntry);
chunk->dcfEntry = NULL; chunk->dcfEntry = NULL;
for(uint8_t m = 0; m < meshCount; m++) { for(uint8_t m = 0; m < meshCount; m++) {
chunk->meshEntries[m] = assetLock( chunk->meshEntries[m] = assetLock(
chunk->meshNames[m], ASSET_LOADER_TYPE_DMF, NULL chunk->meshNames[m], ASSET_LOADER_TYPE_MESH, NULL
); );
if(chunk->meshEntries[m] == NULL) { if(chunk->meshEntries[m] == NULL) {
for(uint8_t j = 0; j < m; j++) { for(uint8_t j = 0; j < m; j++) {
@@ -226,17 +235,19 @@ errorret_t mapWaitForChunks() {
} }
} }
chunk->meshCount = meshCount; chunk->meshCount = meshCount;
anyPending = true; // Fall through to the mesh-state check below so cached meshes
// don't force an unnecessary extra sleep iteration.
} else if(state == ASSET_ENTRY_STATE_ERROR) { } else if(state == ASSET_ENTRY_STATE_ERROR) {
assetUnlockEntry(chunk->dcfEntry); assetUnlockEntry(chunk->dcfEntry);
chunk->dcfEntry = NULL; chunk->dcfEntry = NULL;
memorySet(chunk->tiles, TILE_SHAPE_GROUND, sizeof(chunk->tiles)); memorySet(chunk->tiles, TILE_SHAPE_GROUND, sizeof(chunk->tiles));
continue;
} else { } else {
anyPending = true; anyPending = true;
}
continue; continue;
} }
}
for(uint8_t m = 0; m < chunk->meshCount; m++) { for(uint8_t m = 0; m < chunk->meshCount; m++) {
if(chunk->meshEntries[m] == NULL) continue; if(chunk->meshEntries[m] == NULL) continue;
+4 -4
View File
@@ -13,13 +13,13 @@
#define CHUNK_WIDTH 16 #define CHUNK_WIDTH 16
#define CHUNK_HEIGHT 16 #define CHUNK_HEIGHT 16
#define CHUNK_DEPTH 32 #define CHUNK_DEPTH 4
#define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH) #define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH)
#define MAP_CHUNK_WIDTH mathCeilDiv(6, DUSK_DISPLAY_SCALE_3D) #define MAP_CHUNK_WIDTH 3
#define MAP_CHUNK_HEIGHT mathCeilDiv(4, DUSK_DISPLAY_SCALE_3D) #define MAP_CHUNK_HEIGHT 3
#define MAP_CHUNK_DEPTH 2 #define MAP_CHUNK_DEPTH 4
#define MAP_CHUNK_COUNT (MAP_CHUNK_WIDTH * MAP_CHUNK_HEIGHT * MAP_CHUNK_DEPTH) #define MAP_CHUNK_COUNT (MAP_CHUNK_WIDTH * MAP_CHUNK_HEIGHT * MAP_CHUNK_DEPTH)
#define ENTITY_COUNT 32 #define ENTITY_COUNT 32
+19 -7
View File
@@ -17,6 +17,7 @@ rpgcamera_t RPG_CAMERA;
void rpgCameraInit(void) { void rpgCameraInit(void) {
memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t)); memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t));
RPG_CAMERA.projectionDirty = true;
} }
void rpgCameraGetPosition(vec3 out) { void rpgCameraGetPosition(vec3 out) {
@@ -40,20 +41,31 @@ void rpgCameraGetPosition(vec3 out) {
} }
} }
void rpgCameraUpdateProjection(void) {
#ifdef DUSK_DISPLAY_WIDTH
if(!RPG_CAMERA.projectionDirty) return;
RPG_CAMERA.projectionDirty = false;
#endif
glm_perspective(
glm_rad(45.0f),
SCREEN.aspect,
0.1f,
100.0f,
RPG_CAMERA.projection
);
}
errorret_t rpgCameraUpdate(void) { errorret_t rpgCameraUpdate(void) {
if(!mapIsLoaded()) errorOk(); if(!mapIsLoaded()) errorOk();
vec3 pos; vec3 pos;
rpgCameraGetPosition(pos); rpgCameraGetPosition(pos);
// Round to the nearest chunk center rather than flooring, so the
// loaded window is always most centered on what the camera sees.
// Adding half the chunk dimension before flooring snaps at the
// midpoint of each chunk instead of at the boundary.
chunkpos_t chunkPos = { chunkpos_t chunkPos = {
.x = (chunkunit_t)floorf(pos[0] / CHUNK_WIDTH + 0.5f), .x = (chunkunit_t)floorf(pos[0] / CHUNK_WIDTH),
.y = (chunkunit_t)floorf(pos[1] / CHUNK_HEIGHT + 0.5f), .y = (chunkunit_t)floorf(pos[1] / CHUNK_HEIGHT),
.z = (chunkunit_t)floorf(pos[2] / CHUNK_DEPTH + 0.5f) .z = (chunkunit_t)floorf(pos[2] / CHUNK_DEPTH)
}; };
errorChain(mapPositionSet((chunkpos_t){ errorChain(mapPositionSet((chunkpos_t){
+10
View File
@@ -26,6 +26,8 @@ typedef struct {
}; };
mat4 eye; mat4 eye;
mat4 projection;
bool_t projectionDirty;
} rpgcamera_t; } rpgcamera_t;
extern rpgcamera_t RPG_CAMERA; extern rpgcamera_t RPG_CAMERA;
@@ -48,3 +50,11 @@ void rpgCameraGetPosition(vec3 out);
* @return An error code. * @return An error code.
*/ */
errorret_t rpgCameraUpdate(void); errorret_t rpgCameraUpdate(void);
/**
* Recomputes the camera projection matrix and stores it in
* RPG_CAMERA.projection. On platforms with a fixed display size the
* matrix is computed once and cached; on dynamic-display platforms it
* is recomputed every call.
*/
void rpgCameraUpdateProjection(void);
+10 -22
View File
@@ -63,8 +63,7 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) {
.flags = DISPLAY_STATE_FLAG_DEPTH_TEST | DISPLAY_STATE_FLAG_CULL .flags = DISPLAY_STATE_FLAG_DEPTH_TEST | DISPLAY_STATE_FLAG_CULL
})); }));
mat4 proj, model, eye; mat4 model, eye;
errorChain(shaderBind(&SHADER_UNLIT)); errorChain(shaderBind(&SHADER_UNLIT));
@@ -73,17 +72,13 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) {
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
// Camera projection // Camera projection
float_t fov = glm_rad(45.0f); rpgCameraUpdateProjection();
glm_perspective( errorChain(shaderSetMatrix(
fov, &SHADER_UNLIT, SHADER_UNLIT_PROJECTION, RPG_CAMERA.projection
SCREEN.aspect, ));
0.1f,
100.0f,
proj
);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
// Camera Eye // Camera Eye
float_t fov = glm_rad(45.0f);
float_t pixelsPerUnit = TILE_SIZE_PIXELS; float_t pixelsPerUnit = TILE_SIZE_PIXELS;
float_t worldH = (float_t)(SCREEN.height / SCREEN.scale3d) / pixelsPerUnit; float_t worldH = (float_t)(SCREEN.height / SCREEN.scale3d) / pixelsPerUnit;
float_t z = (worldH * 0.5f) / tanf(fov * 0.5f); float_t z = (worldH * 0.5f) / tanf(fov * 0.5f);
@@ -122,7 +117,6 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) {
glm_vec2_copy((vec2){ 0, 0 }, sprite.uvMin); glm_vec2_copy((vec2){ 0, 0 }, sprite.uvMin);
glm_vec2_copy((vec2){ 1, 1 }, sprite.uvMax); glm_vec2_copy((vec2){ 1, 1 }, sprite.uvMax);
color_t color; color_t color;
switch(ent->direction) { switch(ent->direction) {
case ENTITY_DIR_NORTH: color = COLOR_YELLOW; break; case ENTITY_DIR_NORTH: color = COLOR_YELLOW; break;
@@ -155,20 +149,14 @@ errorret_t sceneOverworldDrawChunks() {
chunk_t *chunk = &MAP.chunks[i]; chunk_t *chunk = &MAP.chunks[i];
if(chunk->meshCount == 0) continue; if(chunk->meshCount == 0) continue;
worldpos_t wp;
chunkPosToWorldPos(&chunk->position, &wp);
vec3 wpf = { (float_t)wp.x, (float_t)wp.y, (float_t)wp.z };
for(uint8_t m = 0; m < chunk->meshCount; m++) { for(uint8_t m = 0; m < chunk->meshCount; m++) {
if(chunk->meshEntries[m] == NULL) continue; if(chunk->meshEntries[m] == NULL) continue;
vec3 pos; errorChain(shaderSetMatrix(
glm_vec3_add(wpf, chunk->meshOffsets[m], pos); &SHADER_UNLIT, SHADER_UNLIT_MODEL, chunk->meshModels[m]
mat4 model; ));
glm_translate_make(model, pos);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
errorChain(shaderSetMaterial(&SHADER_UNLIT, &chunkMaterial)); errorChain(shaderSetMaterial(&SHADER_UNLIT, &chunkMaterial));
errorChain(meshDraw(&chunk->meshEntries[m]->data.dmf.mesh, 0, -1)); errorChain(meshDraw(&chunk->meshEntries[m]->data.mesh.mesh, 0, -1));
} }
} }
+1
View File
@@ -10,6 +10,7 @@
#include "util/memory.h" #include "util/memory.h"
#include "display/spritebatch/spritebatch.h" #include "display/spritebatch/spritebatch.h"
#include "display/text/text.h" #include "display/text/text.h"
#include "assert/assert.h"
uisettings_t UI_SETTINGS; uisettings_t UI_SETTINGS;
-6
View File
@@ -81,14 +81,8 @@ errorret_t displayInitDolphin(void) {
// Describe mesh vertex format. // Describe mesh vertex format.
GX_ClearVtxDesc(); GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); GX_SetVtxDesc(GX_VA_POS, GX_INDEX16);
#if MESH_ENABLE_COLOR
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16);
#endif
GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); 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_POS, GX_POS_XYZ, GX_F32, 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); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
errorOk(); errorOk();
@@ -42,15 +42,8 @@ errorret_t meshDrawDolphin(
assertTrue(vertexCount <= UINT16_MAX, "Vertex count exceeds GX limit"); assertTrue(vertexCount <= UINT16_MAX, "Vertex count exceeds GX limit");
// Matches vertex format described in displaydolphin.c // Matches vertex format described in displaydolphin.c
assertTrue(sizeof(color_t) == 4, "color_t must be exactly 4 bytes");
#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, uv) == 0, "uv offset wrong");
assertTrue(offsetof(meshvertex_t, pos) == 8, "pos offset wrong"); assertTrue(offsetof(meshvertex_t, pos) == 8, "pos offset wrong");
#endif
// Flush vertex data to GPU. This is required before drawing with GX. // Flush vertex data to GPU. This is required before drawing with GX.
DCFlushRange( DCFlushRange(
@@ -63,12 +56,6 @@ errorret_t meshDrawDolphin(
const uint8_t stride = (uint8_t)sizeof(meshvertex_t); 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_POS, (void*)&mesh->vertices[vertexOffset].pos[0], 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_SetArray(GX_VA_TEX0, (void*)&mesh->vertices[vertexOffset].uv[0], stride);
GX_InvVtxCache(); GX_InvVtxCache();
@@ -76,9 +63,6 @@ errorret_t meshDrawDolphin(
GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)vertexCount); GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)vertexCount);
for(uint16_t i = 0; i < (uint16_t)vertexCount; ++i) { for(uint16_t i = 0; i < (uint16_t)vertexCount; ++i) {
GX_Position1x16(i); GX_Position1x16(i);
#if MESH_ENABLE_COLOR
GX_Color1x16(i);
#endif
GX_TexCoord1x16(i); GX_TexCoord1x16(i);
} }
GX_End(); GX_End();
+4
View File
@@ -16,6 +16,10 @@ errorret_t displayOpenGLInit(void) {
errorChain(errorGLCheck()); errorChain(errorGLCheck());
glShadeModel(GL_SMOOTH); // Fixes color on PSP? glShadeModel(GL_SMOOTH); // Fixes color on PSP?
errorChain(errorGLCheck()); errorChain(errorGLCheck());
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
errorChain(errorGLCheck());
glEnableClientState(GL_VERTEX_ARRAY);
errorChain(errorGLCheck());
#endif #endif
errorOk(); errorOk();
+1 -33
View File
@@ -25,16 +25,7 @@ errorret_t meshInitGL(
mesh->vertices = vertices; mesh->vertices = vertices;
#ifdef DUSK_OPENGL_LEGACY #ifdef DUSK_OPENGL_LEGACY
// Nothing needed. // Nothing needed; client state is enabled once globally in displayOpenGLInit.
#if MESH_ENABLE_COLOR
glEnableClientState(GL_COLOR_ARRAY);
errorChain(errorGLCheck());
#endif
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
errorChain(errorGLCheck());
glEnableClientState(GL_VERTEX_ARRAY);
errorChain(errorGLCheck());
#else #else
// Generate Vertex Buffer Object // Generate Vertex Buffer Object
glGenBuffers(1, &mesh->vboId); glGenBuffers(1, &mesh->vboId);
@@ -82,20 +73,6 @@ errorret_t meshInitGL(
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
errorChain(errorGLCheck()); 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 // Unbind VAO and VBO to prevent accidental modification
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
errorChain(errorGLCheck()); errorChain(errorGLCheck());
@@ -138,15 +115,6 @@ errorret_t meshDrawGL(
// Legacy pointer style rendering // Legacy pointer style rendering
const GLsizei stride = sizeof(meshvertex_t); const GLsizei stride = sizeof(meshvertex_t);
#if MESH_ENABLE_COLOR
glColorPointer(
sizeof(color4b_t),
GL_UNSIGNED_BYTE,
stride,
(const GLvoid*)&mesh->vertices[offset].color
);
#endif
glTexCoordPointer( glTexCoordPointer(
MESH_VERTEX_UV_SIZE, MESH_VERTEX_UV_SIZE,
GL_FLOAT, GL_FLOAT,
-20
View File
@@ -87,50 +87,30 @@
#ifdef DUSK_OPENGL_ES #ifdef DUSK_OPENGL_ES
"#version 300 es\n" "#version 300 es\n"
"precision mediump float;\n" "precision mediump float;\n"
// Attributes
"layout(location = 0) in vec3 a_Pos;\n" "layout(location = 0) in vec3 a_Pos;\n"
"layout(location = 1) in vec2 a_TexCoord;\n" "layout(location = 1) in vec2 a_TexCoord;\n"
#if MESH_ENABLE_COLOR
"layout(location = 2) in vec4 a_Color;\n"
#endif
// Uniforms
"uniform mat4 u_Proj;\n" "uniform mat4 u_Proj;\n"
"uniform mat4 u_View;\n" "uniform mat4 u_View;\n"
"uniform mat4 u_Model;\n" "uniform mat4 u_Model;\n"
// Vertex shader outputs
"out vec4 v_Color;\n" "out vec4 v_Color;\n"
"out vec2 v_TexCoord;\n" "out vec2 v_TexCoord;\n"
"void main() {\n" "void main() {\n"
" gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0);\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" " v_Color = vec4(1.0);\n"
#endif
" v_TexCoord = a_TexCoord;\n" " v_TexCoord = a_TexCoord;\n"
"}\n", "}\n",
#else #else
"#version 330 core\n" "#version 330 core\n"
// Attributes
"layout(location = 0) in vec3 a_Pos;\n" "layout(location = 0) in vec3 a_Pos;\n"
"layout(location = 1) in vec2 a_TexCoord;\n" "layout(location = 1) in vec2 a_TexCoord;\n"
#if MESH_ENABLE_COLOR
"layout(location = 2) in vec4 a_Color;\n"
#endif
// Uniforms
"uniform mat4 u_Proj;\n" "uniform mat4 u_Proj;\n"
"uniform mat4 u_View;\n" "uniform mat4 u_View;\n"
"uniform mat4 u_Model;\n" "uniform mat4 u_Model;\n"
// Vertex shader outputs
"out vec4 v_Color;\n" "out vec4 v_Color;\n"
"out vec2 v_TexCoord;\n" "out vec2 v_TexCoord;\n"
"void main() {\n" "void main() {\n"
" gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0);\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" " v_Color = vec4(1.0);\n"
#endif
" v_TexCoord = a_TexCoord;\n" " v_TexCoord = a_TexCoord;\n"
"}\n", "}\n",
#endif #endif
+2 -2
View File
@@ -55,8 +55,8 @@ ASSETS_DIR = os.path.join(PROJECT_ROOT, 'assets')
CHUNK_WIDTH = 16 CHUNK_WIDTH = 16
CHUNK_HEIGHT = 16 CHUNK_HEIGHT = 16
CHUNK_DEPTH = 32 CHUNK_DEPTH = 4
CHUNK_TILE_COUNT = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH # 8192 CHUNK_TILE_COUNT = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH # 1024
CHUNK_MESH_COUNT_MAX = 10 CHUNK_MESH_COUNT_MAX = 10
CHUNK_MESH_NAME_MAX = 64 CHUNK_MESH_NAME_MAX = 64