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);
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++) {
lua_rawgeti(L, 2, i + 1);
if (!lua_isnumber(L, -1)) {
free(indices);
return luaL_error(L, "Mesh vertex map index #%d must be numeric", i);
}
int index = lua_tointeger(L, -1);
if (index > lovrMeshGetVertexCount(mesh) || index < 1) {
free(indices);
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);
}
lovrMeshSetVertexMap(mesh, indices, count);
free(indices);
return 0;
}

View File

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

View File

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

View File

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