From 032788003a6db1dc7965115377b0c2e7d6a73384 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sat, 27 Jan 2018 12:51:41 -0800 Subject: [PATCH] VertexData; IndexData; --- src/api/graphics.c | 9 +++--- src/api/types/mesh.c | 67 +++++++++++++++++++++----------------------- src/data/model.c | 6 ++-- src/data/model.h | 17 ++--------- src/graphics/mesh.c | 52 +++++++++++++++++----------------- src/graphics/mesh.h | 20 ++++++------- src/graphics/model.c | 4 +-- src/lib/vertex.h | 8 +++++- 8 files changed, 87 insertions(+), 96 deletions(-) diff --git a/src/api/graphics.c b/src/api/graphics.c index 6f0d5c44..004aef39 100644 --- a/src/api/graphics.c +++ b/src/api/graphics.c @@ -940,7 +940,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) { if (dataIndex) { int count = lua_objlen(L, dataIndex); 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++) { lua_rawgeti(L, dataIndex, i + 1); @@ -954,11 +954,10 @@ int l_lovrGraphicsNewMesh(lua_State* L) { for (int k = 0; k < attribute.count; k++) { lua_rawgeti(L, -1, ++component); switch (attribute.type) { - case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break; - case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break; - case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break; + case ATTR_FLOAT: *vertices.floats++ = luaL_optnumber(L, -1, 0.f); break; + case ATTR_BYTE: *vertices.bytes++ = luaL_optint(L, -1, 255); break; + case ATTR_INT: *vertices.ints++ = luaL_optint(L, -1, 0); break; } - vertex += attribute.size; lua_pop(L, 1); } } diff --git a/src/api/types/mesh.c b/src/api/types/mesh.c index 46b0dd46..b5bc3250 100644 --- a/src/api/types/mesh.c +++ b/src/api/types/mesh.c @@ -62,7 +62,7 @@ int l_lovrMeshGetVertexCount(lua_State* L) { int l_lovrMeshGetVertex(lua_State* L) { Mesh* mesh = luax_checktype(L, 1, Mesh); 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); int count = 0; @@ -71,11 +71,10 @@ int l_lovrMeshGetVertex(lua_State* L) { count += attribute.count; for (int j = 0; j < attribute.count; j++) { switch (attribute.type) { - case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break; - case ATTR_BYTE: lua_pushnumber(L, *((uint8_t*) vertex)); break; - case ATTR_INT: lua_pushnumber(L, *((int*) vertex)); break; + case ATTR_FLOAT: lua_pushnumber(L, *vertex.floats++); break; + case ATTR_BYTE: lua_pushnumber(L, *vertex.bytes++); 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); - char* vertex = lovrMeshMap(mesh, index, 1, false, true); + VertexData vertex = lovrMeshMap(mesh, index, 1, false, true); // Unwrap table int arg = 3; @@ -106,11 +105,10 @@ int l_lovrMeshSetVertex(lua_State* L) { Attribute attribute = format->attributes[i]; for (int j = 0; j < attribute.count; j++) { switch (attribute.type) { - case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break; - case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, arg++, 255); break; - case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break; + case ATTR_FLOAT: *vertex.floats++ = luaL_optnumber(L, arg++, 0.f); break; + case ATTR_BYTE: *vertex.bytes++ = luaL_optint(L, arg++, 255); 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]; - char* vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false); - vertex += attribute.offset; + VertexData vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false); + vertex.bytes += attribute.offset; for (int i = 0; i < attribute.count; i++) { switch (attribute.type) { - case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break; - case ATTR_BYTE: lua_pushinteger(L, *((uint8_t*) vertex)); break; - case ATTR_INT: lua_pushinteger(L, *((int*) vertex)); break; + case ATTR_FLOAT: lua_pushnumber(L, *vertex.floats++); break; + case ATTR_BYTE: lua_pushinteger(L, *vertex.bytes++); break; + case ATTR_INT: lua_pushinteger(L, *vertex.ints++); break; } - vertex += attribute.size; } return attribute.count; @@ -157,16 +154,15 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) { } int arg = 4; - char* vertex = lovrMeshMap(mesh, vertexIndex, 1, false, true); + VertexData vertex = lovrMeshMap(mesh, vertexIndex, 1, false, true); Attribute attribute = format->attributes[attributeIndex]; - vertex += attribute.offset; + vertex.bytes += attribute.offset; for (int i = 0; i < attribute.count; i++) { switch (attribute.type) { - case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break; - case ATTR_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break; - case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break; + case ATTR_FLOAT: *vertex.floats++ = luaL_optnumber(L, arg++, 0.f); break; + case ATTR_BYTE: *vertex.bytes++ = luaL_optint(L, arg++, 255); break; + case ATTR_INT: *vertex.ints++ = luaL_optint(L, arg++, 0); break; } - vertex += attribute.size; } return 0; @@ -184,8 +180,7 @@ int l_lovrMeshSetVertices(lua_State* L) { return luaL_error(L, "Mesh can only hold %d vertices", maxVertices); } - void* vertices = lovrMeshMap(mesh, start, vertexCount, false, true); - char* vertex = vertices; + VertexData vertices = lovrMeshMap(mesh, start, vertexCount, false, true); for (int i = 0; i < vertexCount; i++) { lua_rawgeti(L, 2, i + 1); @@ -195,11 +190,10 @@ int l_lovrMeshSetVertices(lua_State* L) { for (int k = 0; k < attribute.count; k++) { lua_rawgeti(L, -1, ++component); switch (attribute.type) { - case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break; - case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break; - case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break; + case ATTR_FLOAT: *vertices.floats++ = luaL_optnumber(L, -1, 0.f); break; + case ATTR_BYTE: *vertices.bytes++ = luaL_optint(L, -1, 255); break; + case ATTR_INT: *vertices.ints++ = luaL_optint(L, -1, 0); break; } - vertex += attribute.size; lua_pop(L, 1); } } @@ -212,7 +206,7 @@ int l_lovrMeshSetVertices(lua_State* L) { int l_lovrMeshGetVertexMap(lua_State* L) { Mesh* mesh = luax_checktype(L, 1, Mesh); size_t count; - unsigned int* indices = lovrMeshGetVertexMap(mesh, &count); + IndexData indices = lovrMeshGetVertexMap(mesh, &count); if (count == 0) { lua_pushnil(L); @@ -221,7 +215,8 @@ int l_lovrMeshGetVertexMap(lua_State* L) { lua_newtable(L); 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); } @@ -238,8 +233,10 @@ int l_lovrMeshSetVertexMap(lua_State* L) { luaL_checktype(L, 2, LUA_TTABLE); int count = lua_objlen(L, 2); + int vertexCount = lovrMeshGetVertexCount(mesh); 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++) { lua_rawgeti(L, 2, i + 1); @@ -248,20 +245,20 @@ int l_lovrMeshSetVertexMap(lua_State* L) { } 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); } if (indexSize == sizeof(uint16_t)) { - *(((uint16_t*) indices) + i) = index - 1; + indices.shorts[i] = index - 1; } else if (indexSize == sizeof(uint32_t)) { - *(((uint32_t*) indices) + i) = index - 1; + indices.ints[i] = index - 1; } lua_pop(L, 1); } - lovrMeshSetVertexMap(mesh, indices, count); + lovrMeshSetVertexMap(mesh, indices.data, count); return 0; } diff --git a/src/data/model.c b/src/data/model.c index 19217a5b..dba82af9 100644 --- a/src/data/model.c +++ b/src/data/model.c @@ -239,7 +239,7 @@ ModelData* lovrModelDataCreate(Blob* blob) { memset(modelData->vertices.data, 0, modelData->format.stride * modelData->vertexCount); // Load vertices - ModelIndices indices = modelData->indices; + IndexData indices = modelData->indices; uint32_t vertex = 0; uint32_t index = 0; for (unsigned int m = 0; m < scene->mNumMeshes; m++) { @@ -270,7 +270,7 @@ ModelData* lovrModelDataCreate(Blob* blob) { // Vertices for (unsigned int v = 0; v < assimpMesh->mNumVertices; v++) { - ModelVertices vertices = modelData->vertices; + VertexData vertices = modelData->vertices; vertices.bytes += vertex * modelData->format.stride; *vertices.floats++ = assimpMesh->mVertices[v].x; @@ -331,7 +331,7 @@ ModelData* lovrModelDataCreate(Blob* blob) { for (unsigned int w = 0; w < assimpBone->mNumWeights; w++) { uint32_t vertexIndex = baseVertex + assimpBone->mWeights[w].mVertexId; float weight = assimpBone->mWeights[w].mWeight; - ModelVertices vertices = modelData->vertices; + VertexData vertices = modelData->vertices; vertices.bytes += vertexIndex * modelData->format.stride; uint32_t* bones = (uint32_t*) (vertices.bytes + boneByteOffset); float* weights = (float*) (bones + MAX_BONES_PER_VERTEX); diff --git a/src/data/model.h b/src/data/model.h index e4a085d2..19d342d8 100644 --- a/src/data/model.h +++ b/src/data/model.h @@ -10,19 +10,6 @@ #define MAX_BONES_PER_VERTEX 4 #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 { const char* name; float offset[16]; @@ -53,8 +40,8 @@ typedef struct { AnimationData* animationData; MaterialData** materials; VertexFormat format; - ModelVertices vertices; - ModelIndices indices; + VertexData vertices; + IndexData indices; int nodeCount; int primitiveCount; int animationCount; diff --git a/src/graphics/mesh.c b/src/graphics/mesh.c index f0641cec..4e50e3c9 100644 --- a/src/graphics/mesh.c +++ b/src/graphics/mesh.c @@ -56,33 +56,35 @@ Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode, vertexFormatAppend(&mesh->format, "lovrVertexColor", ATTR_BYTE, 4); } - mesh->data = NULL; - mesh->count = count; + mesh->vertexCount = 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->attributesDirty = true; mesh->isMapped = false; + mesh->mapStart = 0; + mesh->mapCount = 0; + mesh->isRangeEnabled = false; + mesh->rangeStart = 0; + mesh->rangeCount = count; mesh->drawMode = drawMode; mesh->usage = usage; mesh->vao = 0; mesh->vbo = 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->lastShader = NULL; glGenBuffers(1, &mesh->vbo); glGenBuffers(1, &mesh->ibo); 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); #ifdef EMSCRIPTEN - mesh->data = malloc(mesh->count * mesh->format.stride); + mesh->vertices.data = malloc(mesh->vertexCount * mesh->format.stride); #endif return mesh; @@ -96,9 +98,9 @@ void lovrMeshDestroy(const Ref* ref) { glDeleteBuffers(1, &mesh->vbo); glDeleteBuffers(1, &mesh->ibo); glDeleteVertexArrays(1, &mesh->vao); - free(mesh->indices); + free(mesh->indices.data); #ifdef EMSCRIPTEN - free(mesh->data); + free(mesh->vertices.data); #endif free(mesh); } @@ -145,10 +147,10 @@ void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode) { } 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) { *count = mesh->indexCount; } @@ -163,14 +165,14 @@ void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t 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; - memcpy(mesh->indices, data, mesh->indexCount * mesh->indexSize); + memcpy(mesh->indices.data, data, mesh->indexCount * mesh->indexSize); lovrGraphicsBindVertexArray(mesh->vao); 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) { @@ -207,7 +209,7 @@ void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled) { if (!isEnabled) { 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) { - 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; lovrAssert(isValidRange, "Invalid mesh draw range [%d, %d]", start + 1, start + count + 1); 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 mesh->isMapped = true; mesh->mapStart = start; mesh->mapCount = count; - return (char*) mesh->data + start * mesh->format.stride; + return (VertexData) { .data = mesh->vertices.bytes + start * mesh->format.stride }; #else if (mesh->isMapped) { lovrMeshUnmap(mesh); @@ -259,9 +261,9 @@ void* lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) { GLbitfield access = 0; access |= read ? GL_MAP_READ_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); - 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 } @@ -274,9 +276,9 @@ void lovrMeshUnmap(Mesh* mesh) { lovrGraphicsBindVertexBuffer(mesh->vbo); #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; - glBufferSubData(GL_ARRAY_BUFFER, start, count, (char*) mesh->data + start); + glBufferSubData(GL_ARRAY_BUFFER, start, count, mesh->vertices.bytes + start); #else glUnmapBuffer(GL_ARRAY_BUFFER); #endif diff --git a/src/graphics/mesh.h b/src/graphics/mesh.h index ecbadfd4..6aa43bc0 100644 --- a/src/graphics/mesh.h +++ b/src/graphics/mesh.h @@ -24,25 +24,25 @@ typedef enum { typedef struct { Ref ref; - size_t count; - void* data; + size_t vertexCount; VertexFormat format; + VertexData vertices; + IndexData indices; + size_t indexCount; + size_t indexSize; int enabledAttributes; bool attributesDirty; bool isMapped; int mapStart; size_t mapCount; + bool isRangeEnabled; + int rangeStart; + int rangeCount; MeshDrawMode drawMode; MeshUsage usage; GLuint vao; GLuint vbo; GLuint ibo; - void* indices; - size_t indexCount; - size_t indexSize; - bool isRangeEnabled; - int rangeStart; - int rangeCount; Material* material; Shader* lastShader; } Mesh; @@ -54,7 +54,7 @@ VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh); MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh); void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode); 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); bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name); 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); Material* lovrMeshGetMaterial(Mesh* mesh); 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); diff --git a/src/graphics/model.c b/src/graphics/model.c index a357e0f6..c2a2395f 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -60,8 +60,8 @@ Model* lovrModelCreate(ModelData* modelData) { model->material = NULL; model->mesh = lovrMeshCreate(modelData->vertexCount, &modelData->format, MESH_TRIANGLES, MESH_STATIC); - void* data = lovrMeshMap(model->mesh, 0, modelData->vertexCount, false, true); - memcpy(data, modelData->vertices.data, modelData->vertexCount * modelData->format.stride); + VertexData vertices = lovrMeshMap(model->mesh, 0, modelData->vertexCount, false, true); + memcpy(vertices.data, modelData->vertices.data, modelData->vertexCount * modelData->format.stride); lovrMeshUnmap(model->mesh); lovrMeshSetVertexMap(model->mesh, modelData->indices.data, modelData->indexCount); lovrMeshSetRangeEnabled(model->mesh, true); diff --git a/src/lib/vertex.h b/src/lib/vertex.h index 76c6c16a..dea3792f 100644 --- a/src/lib/vertex.h +++ b/src/lib/vertex.h @@ -23,11 +23,17 @@ typedef struct { } VertexFormat; typedef union { - void* raw; + void* data; float* floats; uint8_t* bytes; int* ints; } VertexData; +typedef union { + void* data; + uint16_t* shorts; + uint32_t* ints; +} IndexData; + void vertexFormatInit(VertexFormat* format); void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count);