VertexData; IndexData;

This commit is contained in:
bjorn 2018-01-27 12:51:41 -08:00
parent 84de048fa3
commit 032788003a
8 changed files with 87 additions and 96 deletions

View File

@ -940,7 +940,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
if (dataIndex) { if (dataIndex) {
int count = lua_objlen(L, dataIndex); int count = lua_objlen(L, dataIndex);
format = *lovrMeshGetVertexFormat(mesh); format = *lovrMeshGetVertexFormat(mesh);
char* vertex = lovrMeshMap(mesh, 0, count, false, true); VertexData vertices = lovrMeshMap(mesh, 0, count, false, true);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
lua_rawgeti(L, dataIndex, i + 1); lua_rawgeti(L, dataIndex, i + 1);
@ -954,11 +954,10 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
for (int k = 0; k < attribute.count; k++) { for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component); lua_rawgeti(L, -1, ++component);
switch (attribute.type) { switch (attribute.type) {
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break; case ATTR_FLOAT: *vertices.floats++ = luaL_optnumber(L, -1, 0.f); break;
case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break; case ATTR_BYTE: *vertices.bytes++ = luaL_optint(L, -1, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break; case ATTR_INT: *vertices.ints++ = luaL_optint(L, -1, 0); break;
} }
vertex += attribute.size;
lua_pop(L, 1); lua_pop(L, 1);
} }
} }

View File

@ -62,7 +62,7 @@ int l_lovrMeshGetVertexCount(lua_State* L) {
int l_lovrMeshGetVertex(lua_State* L) { int l_lovrMeshGetVertex(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
int index = luaL_checkint(L, 2) - 1; int index = luaL_checkint(L, 2) - 1;
uint8_t* vertex = lovrMeshMap(mesh, index, 1, true, false); VertexData vertex = lovrMeshMap(mesh, index, 1, true, false);
VertexFormat* format = lovrMeshGetVertexFormat(mesh); VertexFormat* format = lovrMeshGetVertexFormat(mesh);
int count = 0; int count = 0;
@ -71,11 +71,10 @@ int l_lovrMeshGetVertex(lua_State* L) {
count += attribute.count; count += attribute.count;
for (int j = 0; j < attribute.count; j++) { for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) { switch (attribute.type) {
case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break; case ATTR_FLOAT: lua_pushnumber(L, *vertex.floats++); break;
case ATTR_BYTE: lua_pushnumber(L, *((uint8_t*) vertex)); break; case ATTR_BYTE: lua_pushnumber(L, *vertex.bytes++); break;
case ATTR_INT: lua_pushnumber(L, *((int*) vertex)); break; case ATTR_INT: lua_pushnumber(L, *vertex.ints++); break;
} }
vertex += attribute.size * attribute.count;
} }
} }
@ -91,7 +90,7 @@ int l_lovrMeshSetVertex(lua_State* L) {
} }
VertexFormat* format = lovrMeshGetVertexFormat(mesh); VertexFormat* format = lovrMeshGetVertexFormat(mesh);
char* vertex = lovrMeshMap(mesh, index, 1, false, true); VertexData vertex = lovrMeshMap(mesh, index, 1, false, true);
// Unwrap table // Unwrap table
int arg = 3; int arg = 3;
@ -106,11 +105,10 @@ int l_lovrMeshSetVertex(lua_State* L) {
Attribute attribute = format->attributes[i]; Attribute attribute = format->attributes[i];
for (int j = 0; j < attribute.count; j++) { for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) { switch (attribute.type) {
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break; case ATTR_FLOAT: *vertex.floats++ = luaL_optnumber(L, arg++, 0.f); break;
case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, arg++, 255); break; case ATTR_BYTE: *vertex.bytes++ = luaL_optint(L, arg++, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break; case ATTR_INT: *vertex.ints++ = luaL_optint(L, arg++, 0); break;
} }
vertex += attribute.size * attribute.count;
} }
} }
@ -130,15 +128,14 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
} }
Attribute attribute = format->attributes[attributeIndex]; Attribute attribute = format->attributes[attributeIndex];
char* vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false); VertexData vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false);
vertex += attribute.offset; vertex.bytes += attribute.offset;
for (int i = 0; i < attribute.count; i++) { for (int i = 0; i < attribute.count; i++) {
switch (attribute.type) { switch (attribute.type) {
case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break; case ATTR_FLOAT: lua_pushnumber(L, *vertex.floats++); break;
case ATTR_BYTE: lua_pushinteger(L, *((uint8_t*) vertex)); break; case ATTR_BYTE: lua_pushinteger(L, *vertex.bytes++); break;
case ATTR_INT: lua_pushinteger(L, *((int*) vertex)); break; case ATTR_INT: lua_pushinteger(L, *vertex.ints++); break;
} }
vertex += attribute.size;
} }
return attribute.count; return attribute.count;
@ -157,16 +154,15 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
} }
int arg = 4; int arg = 4;
char* vertex = lovrMeshMap(mesh, vertexIndex, 1, false, true); VertexData vertex = lovrMeshMap(mesh, vertexIndex, 1, false, true);
Attribute attribute = format->attributes[attributeIndex]; Attribute attribute = format->attributes[attributeIndex];
vertex += attribute.offset; vertex.bytes += attribute.offset;
for (int i = 0; i < attribute.count; i++) { for (int i = 0; i < attribute.count; i++) {
switch (attribute.type) { switch (attribute.type) {
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break; case ATTR_FLOAT: *vertex.floats++ = luaL_optnumber(L, arg++, 0.f); break;
case ATTR_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break; case ATTR_BYTE: *vertex.bytes++ = luaL_optint(L, arg++, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break; case ATTR_INT: *vertex.ints++ = luaL_optint(L, arg++, 0); break;
} }
vertex += attribute.size;
} }
return 0; return 0;
@ -184,8 +180,7 @@ int l_lovrMeshSetVertices(lua_State* L) {
return luaL_error(L, "Mesh can only hold %d vertices", maxVertices); return luaL_error(L, "Mesh can only hold %d vertices", maxVertices);
} }
void* vertices = lovrMeshMap(mesh, start, vertexCount, false, true); VertexData vertices = lovrMeshMap(mesh, start, vertexCount, false, true);
char* vertex = vertices;
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
lua_rawgeti(L, 2, i + 1); lua_rawgeti(L, 2, i + 1);
@ -195,11 +190,10 @@ int l_lovrMeshSetVertices(lua_State* L) {
for (int k = 0; k < attribute.count; k++) { for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component); lua_rawgeti(L, -1, ++component);
switch (attribute.type) { switch (attribute.type) {
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break; case ATTR_FLOAT: *vertices.floats++ = luaL_optnumber(L, -1, 0.f); break;
case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break; case ATTR_BYTE: *vertices.bytes++ = luaL_optint(L, -1, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break; case ATTR_INT: *vertices.ints++ = luaL_optint(L, -1, 0); break;
} }
vertex += attribute.size;
lua_pop(L, 1); lua_pop(L, 1);
} }
} }
@ -212,7 +206,7 @@ int l_lovrMeshSetVertices(lua_State* L) {
int l_lovrMeshGetVertexMap(lua_State* L) { int l_lovrMeshGetVertexMap(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
size_t count; size_t count;
unsigned int* indices = lovrMeshGetVertexMap(mesh, &count); IndexData indices = lovrMeshGetVertexMap(mesh, &count);
if (count == 0) { if (count == 0) {
lua_pushnil(L); lua_pushnil(L);
@ -221,7 +215,8 @@ int l_lovrMeshGetVertexMap(lua_State* L) {
lua_newtable(L); lua_newtable(L);
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
lua_pushinteger(L, indices[i] + 1); uint32_t index = mesh->indexSize == sizeof(uint32_t) ? indices.ints[i] : indices.shorts[i];
lua_pushinteger(L, index + 1);
lua_rawseti(L, -2, i + 1); lua_rawseti(L, -2, i + 1);
} }
@ -238,8 +233,10 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
luaL_checktype(L, 2, LUA_TTABLE); luaL_checktype(L, 2, LUA_TTABLE);
int count = lua_objlen(L, 2); int count = lua_objlen(L, 2);
int vertexCount = lovrMeshGetVertexCount(mesh);
int indexSize = mesh->indexSize; int indexSize = mesh->indexSize;
void* indices = realloc(lovrMeshGetVertexMap(mesh, NULL), indexSize * count); IndexData indices = lovrMeshGetVertexMap(mesh, NULL);
indices.data = realloc(indices.data, indexSize * count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
lua_rawgeti(L, 2, i + 1); lua_rawgeti(L, 2, i + 1);
@ -248,20 +245,20 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
} }
int index = lua_tointeger(L, -1); int index = lua_tointeger(L, -1);
if (index > lovrMeshGetVertexCount(mesh) || index < 1) { if (index > vertexCount || index < 1) {
return luaL_error(L, "Invalid vertex map value: %d", index); return luaL_error(L, "Invalid vertex map value: %d", index);
} }
if (indexSize == sizeof(uint16_t)) { if (indexSize == sizeof(uint16_t)) {
*(((uint16_t*) indices) + i) = index - 1; indices.shorts[i] = index - 1;
} else if (indexSize == sizeof(uint32_t)) { } else if (indexSize == sizeof(uint32_t)) {
*(((uint32_t*) indices) + i) = index - 1; indices.ints[i] = index - 1;
} }
lua_pop(L, 1); lua_pop(L, 1);
} }
lovrMeshSetVertexMap(mesh, indices, count); lovrMeshSetVertexMap(mesh, indices.data, count);
return 0; return 0;
} }

View File

@ -239,7 +239,7 @@ ModelData* lovrModelDataCreate(Blob* blob) {
memset(modelData->vertices.data, 0, modelData->format.stride * modelData->vertexCount); memset(modelData->vertices.data, 0, modelData->format.stride * modelData->vertexCount);
// Load vertices // Load vertices
ModelIndices indices = modelData->indices; IndexData indices = modelData->indices;
uint32_t vertex = 0; uint32_t vertex = 0;
uint32_t index = 0; uint32_t index = 0;
for (unsigned int m = 0; m < scene->mNumMeshes; m++) { for (unsigned int m = 0; m < scene->mNumMeshes; m++) {
@ -270,7 +270,7 @@ ModelData* lovrModelDataCreate(Blob* blob) {
// Vertices // Vertices
for (unsigned int v = 0; v < assimpMesh->mNumVertices; v++) { for (unsigned int v = 0; v < assimpMesh->mNumVertices; v++) {
ModelVertices vertices = modelData->vertices; VertexData vertices = modelData->vertices;
vertices.bytes += vertex * modelData->format.stride; vertices.bytes += vertex * modelData->format.stride;
*vertices.floats++ = assimpMesh->mVertices[v].x; *vertices.floats++ = assimpMesh->mVertices[v].x;
@ -331,7 +331,7 @@ ModelData* lovrModelDataCreate(Blob* blob) {
for (unsigned int w = 0; w < assimpBone->mNumWeights; w++) { for (unsigned int w = 0; w < assimpBone->mNumWeights; w++) {
uint32_t vertexIndex = baseVertex + assimpBone->mWeights[w].mVertexId; uint32_t vertexIndex = baseVertex + assimpBone->mWeights[w].mVertexId;
float weight = assimpBone->mWeights[w].mWeight; float weight = assimpBone->mWeights[w].mWeight;
ModelVertices vertices = modelData->vertices; VertexData vertices = modelData->vertices;
vertices.bytes += vertexIndex * modelData->format.stride; vertices.bytes += vertexIndex * modelData->format.stride;
uint32_t* bones = (uint32_t*) (vertices.bytes + boneByteOffset); uint32_t* bones = (uint32_t*) (vertices.bytes + boneByteOffset);
float* weights = (float*) (bones + MAX_BONES_PER_VERTEX); float* weights = (float*) (bones + MAX_BONES_PER_VERTEX);

View File

@ -10,19 +10,6 @@
#define MAX_BONES_PER_VERTEX 4 #define MAX_BONES_PER_VERTEX 4
#define MAX_BONES 48 #define MAX_BONES 48
typedef union {
void* data;
uint8_t* bytes;
uint32_t* ints;
float* floats;
} ModelVertices;
typedef union {
void* data;
uint16_t* shorts;
uint32_t* ints;
} ModelIndices;
typedef struct { typedef struct {
const char* name; const char* name;
float offset[16]; float offset[16];
@ -53,8 +40,8 @@ typedef struct {
AnimationData* animationData; AnimationData* animationData;
MaterialData** materials; MaterialData** materials;
VertexFormat format; VertexFormat format;
ModelVertices vertices; VertexData vertices;
ModelIndices indices; IndexData indices;
int nodeCount; int nodeCount;
int primitiveCount; int primitiveCount;
int animationCount; int animationCount;

View File

@ -56,33 +56,35 @@ Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode,
vertexFormatAppend(&mesh->format, "lovrVertexColor", ATTR_BYTE, 4); vertexFormatAppend(&mesh->format, "lovrVertexColor", ATTR_BYTE, 4);
} }
mesh->data = NULL; mesh->vertexCount = count;
mesh->count = count; mesh->vertices.data = NULL;
mesh->indices.data = NULL;
mesh->indexCount = 0;
mesh->indexSize = count > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
mesh->enabledAttributes = ~0; mesh->enabledAttributes = ~0;
mesh->attributesDirty = true; mesh->attributesDirty = true;
mesh->isMapped = false; mesh->isMapped = false;
mesh->mapStart = 0;
mesh->mapCount = 0;
mesh->isRangeEnabled = false;
mesh->rangeStart = 0;
mesh->rangeCount = count;
mesh->drawMode = drawMode; mesh->drawMode = drawMode;
mesh->usage = usage; mesh->usage = usage;
mesh->vao = 0; mesh->vao = 0;
mesh->vbo = 0; mesh->vbo = 0;
mesh->ibo = 0; mesh->ibo = 0;
mesh->indices = NULL;
mesh->indexCount = 0;
mesh->indexSize = count > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
mesh->isRangeEnabled = false;
mesh->rangeStart = 0;
mesh->rangeCount = mesh->count;
mesh->material = NULL; mesh->material = NULL;
mesh->lastShader = NULL; mesh->lastShader = NULL;
glGenBuffers(1, &mesh->vbo); glGenBuffers(1, &mesh->vbo);
glGenBuffers(1, &mesh->ibo); glGenBuffers(1, &mesh->ibo);
lovrGraphicsBindVertexBuffer(mesh->vbo); lovrGraphicsBindVertexBuffer(mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, mesh->count * mesh->format.stride, NULL, mesh->usage); glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount * mesh->format.stride, NULL, mesh->usage);
glGenVertexArrays(1, &mesh->vao); glGenVertexArrays(1, &mesh->vao);
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
mesh->data = malloc(mesh->count * mesh->format.stride); mesh->vertices.data = malloc(mesh->vertexCount * mesh->format.stride);
#endif #endif
return mesh; return mesh;
@ -96,9 +98,9 @@ void lovrMeshDestroy(const Ref* ref) {
glDeleteBuffers(1, &mesh->vbo); glDeleteBuffers(1, &mesh->vbo);
glDeleteBuffers(1, &mesh->ibo); glDeleteBuffers(1, &mesh->ibo);
glDeleteVertexArrays(1, &mesh->vao); glDeleteVertexArrays(1, &mesh->vao);
free(mesh->indices); free(mesh->indices.data);
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
free(mesh->data); free(mesh->vertices.data);
#endif #endif
free(mesh); free(mesh);
} }
@ -145,10 +147,10 @@ void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode) {
} }
int lovrMeshGetVertexCount(Mesh* mesh) { int lovrMeshGetVertexCount(Mesh* mesh) {
return mesh->count; return mesh->vertexCount;
} }
void* lovrMeshGetVertexMap(Mesh* mesh, size_t* count) { IndexData lovrMeshGetVertexMap(Mesh* mesh, size_t* count) {
if (count) { if (count) {
*count = mesh->indexCount; *count = mesh->indexCount;
} }
@ -163,14 +165,14 @@ void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count) {
} }
if (mesh->indexCount < count) { if (mesh->indexCount < count) {
mesh->indices = realloc(mesh->indices, count * mesh->indexSize); mesh->indices.data = realloc(mesh->indices.data, count * mesh->indexSize);
} }
mesh->indexCount = count; mesh->indexCount = count;
memcpy(mesh->indices, data, mesh->indexCount * mesh->indexSize); memcpy(mesh->indices.data, data, mesh->indexCount * mesh->indexSize);
lovrGraphicsBindVertexArray(mesh->vao); lovrGraphicsBindVertexArray(mesh->vao);
lovrGraphicsBindIndexBuffer(mesh->ibo); lovrGraphicsBindIndexBuffer(mesh->ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->indexCount * mesh->indexSize, mesh->indices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->indexCount * mesh->indexSize, mesh->indices.data, GL_STATIC_DRAW);
} }
bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) { bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
@ -207,7 +209,7 @@ void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled) {
if (!isEnabled) { if (!isEnabled) {
mesh->rangeStart = 0; mesh->rangeStart = 0;
mesh->rangeCount = mesh->count; mesh->rangeCount = mesh->vertexCount;
} }
} }
@ -217,7 +219,7 @@ void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count) {
} }
void lovrMeshSetDrawRange(Mesh* mesh, int start, int count) { void lovrMeshSetDrawRange(Mesh* mesh, int start, int count) {
size_t limit = mesh->indexCount > 0 ? mesh->indexCount : mesh->count; size_t limit = mesh->indexCount > 0 ? mesh->indexCount : mesh->vertexCount;
bool isValidRange = start >= 0 && count >= 0 && (size_t) start + count <= limit; bool isValidRange = start >= 0 && count >= 0 && (size_t) start + count <= limit;
lovrAssert(isValidRange, "Invalid mesh draw range [%d, %d]", start + 1, start + count + 1); lovrAssert(isValidRange, "Invalid mesh draw range [%d, %d]", start + 1, start + count + 1);
mesh->rangeStart = start; mesh->rangeStart = start;
@ -242,12 +244,12 @@ void lovrMeshSetMaterial(Mesh* mesh, Material* material) {
} }
} }
void* lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) { VertexData lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) {
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
mesh->isMapped = true; mesh->isMapped = true;
mesh->mapStart = start; mesh->mapStart = start;
mesh->mapCount = count; mesh->mapCount = count;
return (char*) mesh->data + start * mesh->format.stride; return (VertexData) { .data = mesh->vertices.bytes + start * mesh->format.stride };
#else #else
if (mesh->isMapped) { if (mesh->isMapped) {
lovrMeshUnmap(mesh); lovrMeshUnmap(mesh);
@ -259,9 +261,9 @@ void* lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) {
GLbitfield access = 0; GLbitfield access = 0;
access |= read ? GL_MAP_READ_BIT : 0; access |= read ? GL_MAP_READ_BIT : 0;
access |= write ? GL_MAP_WRITE_BIT : 0; access |= write ? GL_MAP_WRITE_BIT : 0;
access |= (write && start == 0 && count == mesh->count) ? GL_MAP_INVALIDATE_BUFFER_BIT : 0; access |= (write && start == 0 && count == mesh->vertexCount) ? GL_MAP_INVALIDATE_BUFFER_BIT : 0;
lovrGraphicsBindVertexBuffer(mesh->vbo); lovrGraphicsBindVertexBuffer(mesh->vbo);
return glMapBufferRange(GL_ARRAY_BUFFER, start * mesh->format.stride, count * mesh->format.stride, access); return (VertexData) { .data = glMapBufferRange(GL_ARRAY_BUFFER, start * mesh->format.stride, count * mesh->format.stride, access) };
#endif #endif
} }
@ -274,9 +276,9 @@ void lovrMeshUnmap(Mesh* mesh) {
lovrGraphicsBindVertexBuffer(mesh->vbo); lovrGraphicsBindVertexBuffer(mesh->vbo);
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
int start = mesh->mapStart * mesh->format.stride; size_t start = mesh->mapStart * mesh->format.stride;
size_t count = mesh->mapCount * mesh->format.stride; size_t count = mesh->mapCount * mesh->format.stride;
glBufferSubData(GL_ARRAY_BUFFER, start, count, (char*) mesh->data + start); glBufferSubData(GL_ARRAY_BUFFER, start, count, mesh->vertices.bytes + start);
#else #else
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
#endif #endif

View File

@ -24,25 +24,25 @@ typedef enum {
typedef struct { typedef struct {
Ref ref; Ref ref;
size_t count; size_t vertexCount;
void* data;
VertexFormat format; VertexFormat format;
VertexData vertices;
IndexData indices;
size_t indexCount;
size_t indexSize;
int enabledAttributes; int enabledAttributes;
bool attributesDirty; bool attributesDirty;
bool isMapped; bool isMapped;
int mapStart; int mapStart;
size_t mapCount; size_t mapCount;
bool isRangeEnabled;
int rangeStart;
int rangeCount;
MeshDrawMode drawMode; MeshDrawMode drawMode;
MeshUsage usage; MeshUsage usage;
GLuint vao; GLuint vao;
GLuint vbo; GLuint vbo;
GLuint ibo; GLuint ibo;
void* indices;
size_t indexCount;
size_t indexSize;
bool isRangeEnabled;
int rangeStart;
int rangeCount;
Material* material; Material* material;
Shader* lastShader; Shader* lastShader;
} Mesh; } Mesh;
@ -54,7 +54,7 @@ VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh);
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh); MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode); void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
int lovrMeshGetVertexCount(Mesh* mesh); int lovrMeshGetVertexCount(Mesh* mesh);
void* lovrMeshGetVertexMap(Mesh* mesh, size_t* count); IndexData lovrMeshGetVertexMap(Mesh* mesh, size_t* count);
void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count); void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count);
bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name); bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name);
void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enabled); void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enabled);
@ -64,5 +64,5 @@ void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count);
void lovrMeshSetDrawRange(Mesh* mesh, int start, int count); void lovrMeshSetDrawRange(Mesh* mesh, int start, int count);
Material* lovrMeshGetMaterial(Mesh* mesh); Material* lovrMeshGetMaterial(Mesh* mesh);
void lovrMeshSetMaterial(Mesh* mesh, Material* material); void lovrMeshSetMaterial(Mesh* mesh, Material* material);
void* lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write); VertexData lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write);
void lovrMeshUnmap(Mesh* mesh); void lovrMeshUnmap(Mesh* mesh);

View File

@ -60,8 +60,8 @@ Model* lovrModelCreate(ModelData* modelData) {
model->material = NULL; model->material = NULL;
model->mesh = lovrMeshCreate(modelData->vertexCount, &modelData->format, MESH_TRIANGLES, MESH_STATIC); model->mesh = lovrMeshCreate(modelData->vertexCount, &modelData->format, MESH_TRIANGLES, MESH_STATIC);
void* data = lovrMeshMap(model->mesh, 0, modelData->vertexCount, false, true); VertexData vertices = lovrMeshMap(model->mesh, 0, modelData->vertexCount, false, true);
memcpy(data, modelData->vertices.data, modelData->vertexCount * modelData->format.stride); memcpy(vertices.data, modelData->vertices.data, modelData->vertexCount * modelData->format.stride);
lovrMeshUnmap(model->mesh); lovrMeshUnmap(model->mesh);
lovrMeshSetVertexMap(model->mesh, modelData->indices.data, modelData->indexCount); lovrMeshSetVertexMap(model->mesh, modelData->indices.data, modelData->indexCount);
lovrMeshSetRangeEnabled(model->mesh, true); lovrMeshSetRangeEnabled(model->mesh, true);

View File

@ -23,11 +23,17 @@ typedef struct {
} VertexFormat; } VertexFormat;
typedef union { typedef union {
void* raw; void* data;
float* floats; float* floats;
uint8_t* bytes; uint8_t* bytes;
int* ints; int* ints;
} VertexData; } VertexData;
typedef union {
void* data;
uint16_t* shorts;
uint32_t* ints;
} IndexData;
void vertexFormatInit(VertexFormat* format); void vertexFormatInit(VertexFormat* format);
void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count); void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count);