A lot of PSP optimizations
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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);
|
||||||
|
|||||||
@@ -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
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
|
||||||
@@ -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);
|
|
||||||
+45
-49
@@ -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);
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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). */
|
||||||
|
|||||||
@@ -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
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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.
|
#define CUBE_VERT(i, px, py, pz, u, v) \
|
||||||
#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[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);
|
||||||
#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(
|
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");
|
||||||
|
|||||||
@@ -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
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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. */
|
#define PLANE_VERT(i, px, py, pz, u, v) \
|
||||||
#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[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);
|
||||||
#else
|
|
||||||
#define PLANE_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 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");
|
||||||
|
|||||||
@@ -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
@@ -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];
|
||||||
}
|
}
|
||||||
@@ -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
|
|
||||||
);
|
);
|
||||||
@@ -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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user