Use UNSIGNED_SHORT for indices when possible;

This commit is contained in:
bjorn 2017-10-22 07:04:52 -07:00
parent e8e09c425e
commit 2c0d85a84a
5 changed files with 50 additions and 30 deletions

View File

@ -273,27 +273,30 @@ 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);
unsigned int* indices = malloc(count * sizeof(unsigned int)); int indexSize = mesh->indexSize;
void* indices = realloc(lovrMeshGetVertexMap(mesh, NULL), 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);
if (!lua_isnumber(L, -1)) { if (!lua_isnumber(L, -1)) {
free(indices);
return luaL_error(L, "Mesh vertex map index #%d must be numeric", i); return luaL_error(L, "Mesh vertex map index #%d must be numeric", i);
} }
int index = lua_tointeger(L, -1); int index = lua_tointeger(L, -1);
if (index > lovrMeshGetVertexCount(mesh) || index < 1) { if (index > lovrMeshGetVertexCount(mesh) || index < 1) {
free(indices);
return luaL_error(L, "Invalid vertex map value: %d", index); return luaL_error(L, "Invalid vertex map value: %d", index);
} }
indices[i] = index - 1; if (indexSize == sizeof(uint16_t)) {
*(((uint16_t*) indices) + i) = index - 1;
} else if (indexSize == sizeof(uint32_t)) {
*(((uint32_t*) indices) + i) = index - 1;
}
lua_pop(L, 1); lua_pop(L, 1);
} }
lovrMeshSetVertexMap(mesh, indices, count); lovrMeshSetVertexMap(mesh, indices, count);
free(indices);
return 0; return 0;
} }

View File

@ -1,5 +1,6 @@
#include "graphics/mesh.h" #include "graphics/mesh.h"
#include "graphics/graphics.h" #include "graphics/graphics.h"
#include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -43,7 +44,6 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy); Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy);
if (!mesh) return NULL; if (!mesh) return NULL;
vec_init(&mesh->map);
vec_init(&mesh->format); vec_init(&mesh->format);
if (format) { if (format) {
@ -79,6 +79,9 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
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 = 0; mesh->isRangeEnabled = 0;
mesh->rangeStart = 0; mesh->rangeStart = 0;
mesh->rangeCount = mesh->count; mesh->rangeCount = mesh->count;
@ -102,8 +105,8 @@ 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);
vec_deinit(&mesh->map);
vec_deinit(&mesh->format); vec_deinit(&mesh->format);
free(mesh->indices);
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
free(mesh->data); free(mesh->data);
#endif #endif
@ -126,9 +129,10 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform) {
lovrMeshBindAttributes(mesh); lovrMeshBindAttributes(mesh);
size_t start = mesh->rangeStart; size_t start = mesh->rangeStart;
size_t count = mesh->rangeCount; size_t count = mesh->rangeCount;
if (mesh->map.length > 0) { if (mesh->indexCount > 0) {
count = mesh->isRangeEnabled ? mesh->rangeCount : mesh->map.length; count = mesh->isRangeEnabled ? mesh->rangeCount : mesh->indexCount;
glDrawElements(mesh->drawMode, count, GL_UNSIGNED_INT, (GLvoid*) (start * sizeof(unsigned int))); GLenum indexType = mesh->indexSize == sizeof(uint16_t) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
glDrawElements(mesh->drawMode, count, indexType, (GLvoid*) (start * mesh->indexSize));
} else { } else {
glDrawArrays(mesh->drawMode, start, count); glDrawArrays(mesh->drawMode, start, count);
} }
@ -159,21 +163,22 @@ int lovrMeshGetVertexSize(Mesh* mesh) {
return mesh->stride; return mesh->stride;
} }
unsigned int* lovrMeshGetVertexMap(Mesh* mesh, size_t* count) { void* lovrMeshGetVertexMap(Mesh* mesh, size_t* count) {
*count = mesh->map.length; *count = mesh->indexCount;
return mesh->map.data; return mesh->indices;
} }
void lovrMeshSetVertexMap(Mesh* mesh, unsigned int* map, size_t count) { void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count) {
if (count == 0 || !map) { if (!data || count == 0) {
vec_clear(&mesh->map); mesh->indexCount = 0;
} else { return;
vec_clear(&mesh->map);
vec_pusharr(&mesh->map, map, count);
lovrGraphicsBindVertexArray(mesh->vao);
lovrGraphicsBindIndexBuffer(mesh->ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), mesh->map.data, GL_STATIC_DRAW);
} }
mesh->indices = data;
mesh->indexCount = count;
lovrGraphicsBindVertexArray(mesh->vao);
lovrGraphicsBindIndexBuffer(mesh->ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->indexCount * mesh->indexSize, mesh->indices, GL_STATIC_DRAW);
} }
int lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) { int lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
@ -226,7 +231,7 @@ void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count) {
} }
int lovrMeshSetDrawRange(Mesh* mesh, int start, int count) { int lovrMeshSetDrawRange(Mesh* mesh, int start, int count) {
size_t limit = mesh->map.length > 0 ? mesh->map.length : mesh->count; size_t limit = mesh->indexCount > 0 ? mesh->indexCount : mesh->count;
if (start < 0 || count < 0 || (size_t) start + count > limit) { if (start < 0 || count < 0 || (size_t) start + count > limit) {
return 1; return 1;

View File

@ -49,7 +49,9 @@ typedef struct {
GLuint vao; GLuint vao;
GLuint vbo; GLuint vbo;
GLuint ibo; GLuint ibo;
vec_uint_t map; void* indices;
size_t indexCount;
size_t indexSize;
int isRangeEnabled; int isRangeEnabled;
int rangeStart; int rangeStart;
int rangeCount; int rangeCount;
@ -64,8 +66,8 @@ MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
int lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode); int lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
int lovrMeshGetVertexCount(Mesh* mesh); int lovrMeshGetVertexCount(Mesh* mesh);
int lovrMeshGetVertexSize(Mesh* mesh); int lovrMeshGetVertexSize(Mesh* mesh);
unsigned int* lovrMeshGetVertexMap(Mesh* mesh, size_t* count); void* lovrMeshGetVertexMap(Mesh* mesh, size_t* count);
void lovrMeshSetVertexMap(Mesh* mesh, unsigned int* map, size_t count); void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count);
int lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name); int lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name);
void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, int enabled); void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, int enabled);
int lovrMeshIsRangeEnabled(Mesh* mesh); int lovrMeshIsRangeEnabled(Mesh* mesh);

View File

@ -3,6 +3,7 @@
#include "filesystem/file.h" #include "filesystem/file.h"
#include "math/math.h" #include "math/math.h"
#include "math/mat4.h" #include "math/mat4.h"
#include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <assimp/cfileio.h> #include <assimp/cfileio.h>
@ -202,11 +203,12 @@ ModelData* lovrModelDataCreate(Blob* blob) {
} }
// Allocate // Allocate
int indexSize = modelData->vertexCount > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
modelData->primitiveCount = scene->mNumMeshes; modelData->primitiveCount = scene->mNumMeshes;
modelData->primitives = malloc(modelData->primitiveCount * sizeof(ModelPrimitive)); modelData->primitives = malloc(modelData->primitiveCount * sizeof(ModelPrimitive));
modelData->vertexSize = 3 + (modelData->hasNormals ? 3 : 0) + (modelData->hasUVs ? 2 : 0); modelData->vertexSize = 3 + (modelData->hasNormals ? 3 : 0) + (modelData->hasUVs ? 2 : 0);
modelData->vertices = malloc(modelData->vertexSize * modelData->vertexCount * sizeof(float)); modelData->vertices = malloc(modelData->vertexSize * modelData->vertexCount * sizeof(float));
modelData->indices = malloc(modelData->indexCount * sizeof(uint32_t)); modelData->indices = malloc(modelData->indexCount * indexSize);
// Load // Load
int vertex = 0; int vertex = 0;
@ -224,8 +226,16 @@ ModelData* lovrModelDataCreate(Blob* blob) {
modelData->primitives[m].drawCount += assimpFace.mNumIndices; modelData->primitives[m].drawCount += assimpFace.mNumIndices;
for (unsigned int i = 0; i < assimpFace.mNumIndices; i++) { if (indexSize == sizeof(uint16_t)) {
modelData->indices[index++] = (vertex / modelData->vertexSize) + assimpFace.mIndices[i]; uint16_t* indices = modelData->indices;
for (unsigned int i = 0; i < assimpFace.mNumIndices; i++) {
indices[index++] = (vertex / modelData->vertexSize) + assimpFace.mIndices[i];
}
} else if (indexSize == sizeof(uint32_t)) {
uint32_t* indices = modelData->indices;
for (unsigned int i = 0; i < assimpFace.mNumIndices; i++) {
indices[index++] = (vertex / modelData->vertexSize) + assimpFace.mIndices[i];
}
} }
} }

View File

@ -23,7 +23,7 @@ typedef struct {
ModelPrimitive* primitives; ModelPrimitive* primitives;
MaterialData* materials; MaterialData* materials;
float* vertices; float* vertices;
uint32_t* indices; void* indices;
int nodeCount; int nodeCount;
int primitiveCount; int primitiveCount;
int materialCount; int materialCount;