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