Make Mesh more lightweight;

This commit is contained in:
bjorn 2018-03-21 14:48:46 -07:00
parent d2e0642b59
commit d77b139d21
12 changed files with 173 additions and 147 deletions

View File

@ -100,7 +100,7 @@ int l_lovrDataNewVertexData(lua_State* L) {
VertexFormat format;
vertexFormatInit(&format);
bool hasFormat = luax_checkvertexformat(L, 2, &format);
VertexData* vertexData = lovrVertexDataCreate(count, hasFormat ? &format : NULL, true);
VertexData* vertexData = lovrVertexDataCreate(count, hasFormat ? &format : NULL);
luax_pushtype(L, VertexData, vertexData);
lovrRelease(vertexData);
return 1;

View File

@ -976,22 +976,20 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
return 0;
}
if (!vertexData) {
#ifdef EMSCRIPTEN
vertexData = lovrVertexDataCreate(count, hasFormat ? &format : NULL, true);
#else
vertexData = lovrVertexDataCreate(count, hasFormat ? &format : NULL, false);
#endif
if (!hasFormat) {
vertexFormatAppend(&format, "lovrPosition", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrTexCoord", ATTR_FLOAT, 2);
}
MeshDrawMode* drawMode = (MeshDrawMode*) luax_optenum(L, drawModeIndex, "fan", &MeshDrawModes, "mesh draw mode");
MeshUsage* usage = (MeshUsage*) luax_optenum(L, drawModeIndex + 1, "dynamic", &MeshUsages, "mesh usage");
Mesh* mesh = lovrMeshCreate(vertexData, *drawMode, *usage);
Mesh* mesh = lovrMeshCreate(count, format, *drawMode, *usage);
if (dataIndex) {
uint32_t dataCount = lua_objlen(L, dataIndex);
format = *lovrMeshGetVertexFormat(mesh);
VertexPointer vertices = lovrMeshMap(mesh, 0, dataCount, false, true);
VertexPointer vertices = lovrMeshMapVertices(mesh, 0, dataCount, false, true);
for (uint32_t i = 0; i < dataCount; i++) {
lua_rawgeti(L, dataIndex, i + 1);
@ -1015,6 +1013,9 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
lua_pop(L, 1);
}
} else if (vertexData) {
VertexPointer vertices = lovrMeshMapVertices(mesh, 0, count, false, true);
memcpy(vertices.raw, vertexData->blob.data, vertexData->count * vertexData->format.stride);
}
luax_pushtype(L, Mesh, mesh);

View File

@ -1,4 +1,5 @@
#include "api.h"
#include <limits.h>
int l_lovrMeshAttachAttributes(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
@ -93,7 +94,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;
VertexPointer vertex = lovrMeshMap(mesh, index, 1, true, false);
VertexPointer vertex = lovrMeshMapVertices(mesh, index, 1, true, false);
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
return luax_pushvertex(L, &vertex, format);
}
@ -103,7 +104,7 @@ int l_lovrMeshSetVertex(lua_State* L) {
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < lovrMeshGetVertexCount(mesh), "Invalid mesh vertex index: %d", index + 1);
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
VertexPointer vertex = lovrMeshMap(mesh, index, 1, false, true);
VertexPointer vertex = lovrMeshMapVertices(mesh, index, 1, false, true);
luax_setvertex(L, 3, &vertex, format);
return 0;
}
@ -116,7 +117,7 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
lovrAssert(vertexIndex >= 0 && vertexIndex < lovrMeshGetVertexCount(mesh), "Invalid mesh vertex: %d", vertexIndex + 1);
lovrAssert(attributeIndex >= 0 && attributeIndex < format->count, "Invalid mesh attribute: %d", attributeIndex + 1);
Attribute attribute = format->attributes[attributeIndex];
VertexPointer vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false);
VertexPointer vertex = lovrMeshMapVertices(mesh, vertexIndex, 1, true, false);
vertex.bytes += attribute.offset;
return luax_pushvertexattribute(L, &vertex, attribute);
}
@ -129,7 +130,7 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
lovrAssert(vertexIndex >= 0 && vertexIndex < lovrMeshGetVertexCount(mesh), "Invalid mesh vertex: %d", vertexIndex + 1);
lovrAssert(attributeIndex >= 0 && attributeIndex < format->count, "Invalid mesh attribute: %d", attributeIndex + 1);
Attribute attribute = format->attributes[attributeIndex];
VertexPointer vertex = lovrMeshMap(mesh, vertexIndex, 1, false, true);
VertexPointer vertex = lovrMeshMapVertices(mesh, vertexIndex, 1, false, true);
vertex.bytes += attribute.offset;
luax_setvertexattribute(L, 4, &vertex, attribute);
return 0;
@ -156,7 +157,7 @@ int l_lovrMeshSetVertices(lua_State* L) {
lovrAssert(start + count <= capacity, "Overflow in Mesh:setVertices: Mesh can only hold %d vertices", capacity);
lovrAssert(count <= sourceSize, "Cannot set %d vertices on Mesh: source only has %d vertices", count, sourceSize);
VertexPointer vertices = lovrMeshMap(mesh, start, count, false, true);
VertexPointer vertices = lovrMeshMapVertices(mesh, start, count, false, true);
if (vertexData) {
memcpy(vertices.raw, vertexData->blob.data, count * format->stride);
@ -174,17 +175,18 @@ int l_lovrMeshSetVertices(lua_State* L) {
int l_lovrMeshGetVertexMap(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
size_t count;
IndexPointer indices = lovrMeshGetVertexMap(mesh, &count);
uint32_t count;
size_t size;
IndexPointer indices = lovrMeshReadIndices(mesh, &count, &size);
if (count == 0) {
if (count == 0 || !indices.raw) {
lua_pushnil(L);
return 1;
}
lua_newtable(L);
for (size_t i = 0; i < count; i++) {
uint32_t index = mesh->indexSize == sizeof(uint32_t) ? indices.ints[i] : indices.shorts[i];
uint32_t index = size == sizeof(uint32_t) ? indices.ints[i] : indices.shorts[i];
lua_pushinteger(L, index + 1);
lua_rawseti(L, -2, i + 1);
}
@ -196,38 +198,36 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
if (lua_isnoneornil(L, 2)) {
lovrMeshSetVertexMap(mesh, NULL, 0);
lovrMeshWriteIndices(mesh, 0, 0);
return 0;
}
luaL_checktype(L, 2, LUA_TTABLE);
int count = lua_objlen(L, 2);
int vertexCount = lovrMeshGetVertexCount(mesh);
int indexSize = mesh->indexSize;
IndexPointer indices = lovrMeshGetVertexMap(mesh, NULL);
indices.raw = realloc(indices.raw, indexSize * count);
uint32_t count = lua_objlen(L, 2);
uint32_t vertexCount = lovrMeshGetVertexCount(mesh);
size_t size = vertexCount > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
IndexPointer indices = lovrMeshWriteIndices(mesh, count, size);
for (int i = 0; i < count; i++) {
for (uint32_t i = 0; i < count; i++) {
lua_rawgeti(L, 2, i + 1);
if (!lua_isnumber(L, -1)) {
return luaL_error(L, "Mesh vertex map index #%d must be numeric", i);
}
int index = lua_tointeger(L, -1);
uint32_t index = lua_tointeger(L, -1);
if (index > vertexCount || index < 1) {
return luaL_error(L, "Invalid vertex map value: %d", index);
}
if (indexSize == sizeof(uint16_t)) {
if (size == sizeof(uint16_t)) {
indices.shorts[i] = index - 1;
} else if (indexSize == sizeof(uint32_t)) {
} else {
indices.ints[i] = index - 1;
}
lua_pop(L, 1);
}
lovrMeshSetVertexMap(mesh, indices.raw, count);
return 0;
}
@ -248,13 +248,14 @@ int l_lovrMeshSetAttributeEnabled(lua_State* L) {
int l_lovrMeshGetDrawRange(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
if (!lovrMeshIsRangeEnabled(mesh)) {
int start, count;
lovrMeshGetDrawRange(mesh, &start, &count);
if (count == 0) {
lua_pushnil(L);
return 1;
}
int start, count;
lovrMeshGetDrawRange(mesh, &start, &count);
lua_pushinteger(L, start + 1);
lua_pushinteger(L, count);
return 2;
@ -263,11 +264,10 @@ int l_lovrMeshGetDrawRange(lua_State* L) {
int l_lovrMeshSetDrawRange(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
if (lua_isnoneornil(L, 2)) {
lovrMeshSetRangeEnabled(mesh, 0);
lovrMeshSetDrawRange(mesh, 0, 0);
return 0;
}
lovrMeshSetRangeEnabled(mesh, 1);
int rangeStart = luaL_checkinteger(L, 2) - 1;
int rangeCount = luaL_checkinteger(L, 3);
lovrMeshSetDrawRange(mesh, rangeStart, rangeCount);

View File

@ -297,7 +297,7 @@ ModelData* lovrModelDataCreate(Blob* blob) {
if (isSkinned) vertexFormatAppend(&format, "lovrBoneWeights", ATTR_FLOAT, 4);
// Allocate
modelData->vertexData = lovrVertexDataCreate(vertexCount, &format, true);
modelData->vertexData = lovrVertexDataCreate(vertexCount, &format);
modelData->indexSize = vertexCount > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
modelData->indices.raw = malloc(modelData->indexCount * modelData->indexSize);
modelData->primitiveCount = scene->mNumMeshes;

View File

@ -15,12 +15,10 @@ void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType ty
format->stride += size * count;
}
VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format, bool allocate) {
VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format) {
VertexData* vertexData = lovrAlloc(sizeof(VertexData), lovrBlobDestroy);
if (!vertexData) return NULL;
vertexData->count = count;
if (format) {
vertexData->format = *format;
} else {
@ -32,11 +30,10 @@ VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format, bool allo
vertexFormatAppend(&vertexData->format, "lovrVertexColor", ATTR_BYTE, 4);
}
if (allocate) {
size_t size = format->stride * count;
vertexData->blob.data = calloc(1, size);
vertexData->blob.size = size;
}
size_t size = format->stride * count;
vertexData->blob.data = calloc(1, size);
vertexData->blob.size = size;
vertexData->count = count;
return vertexData;
}

View File

@ -48,4 +48,4 @@ typedef struct {
void vertexFormatInit(VertexFormat* format);
void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count);
VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format, bool allocate);
VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format);

View File

@ -1,6 +1,5 @@
#include "graphics/mesh.h"
#include "graphics/graphics.h"
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
@ -45,7 +44,7 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
if (previous.mesh != current.mesh || previous.attributeIndex != current.attributeIndex) {
lovrGraphicsBindVertexBuffer(current.mesh->vbo);
VertexFormat* format = &current.mesh->vertexData->format;
VertexFormat* format = &current.mesh->format;
Attribute attribute = format->attributes[current.attributeIndex];
switch (attribute.type) {
case ATTR_FLOAT:
@ -66,26 +65,24 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
}
}
Mesh* lovrMeshCreate(VertexData* vertexData, MeshDrawMode drawMode, MeshUsage usage) {
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, MeshUsage usage) {
Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy);
if (!mesh) return NULL;
uint32_t count = vertexData->count;
mesh->vertexData = vertexData;
mesh->indexSize = count > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
mesh->count = count;
mesh->format = format;
mesh->drawMode = drawMode;
mesh->usage = usage;
glGenBuffers(1, &mesh->vbo);
glGenBuffers(1, &mesh->ibo);
lovrGraphicsBindVertexBuffer(mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, count * mesh->vertexData->format.stride, vertexData->blob.data, mesh->usage);
glBufferData(GL_ARRAY_BUFFER, count * format.stride, NULL, mesh->usage);
glGenVertexArrays(1, &mesh->vao);
map_init(&mesh->attachments);
for (int i = 0; i < vertexData->format.count; i++) {
MeshAttachment attachment = { mesh, i, 0, true };
map_set(&mesh->attachments, vertexData->format.attributes[i].name, attachment);
for (int i = 0; i < format.count; i++) {
map_set(&mesh->attachments, format.attributes[i].name, ((MeshAttachment) { mesh, i, 0, true }));
}
return mesh;
@ -94,7 +91,10 @@ Mesh* lovrMeshCreate(VertexData* vertexData, MeshDrawMode drawMode, MeshUsage us
void lovrMeshDestroy(void* ref) {
Mesh* mesh = ref;
lovrRelease(mesh->material);
lovrRelease(mesh->vertexData);
#ifdef EMSCRIPTEN
free(mesh->data.raw);
free(mesh->indices.raw);
#endif
glDeleteBuffers(1, &mesh->vbo);
glDeleteBuffers(1, &mesh->ibo);
glDeleteVertexArrays(1, &mesh->vao);
@ -107,7 +107,6 @@ void lovrMeshDestroy(void* ref) {
}
}
map_deinit(&mesh->attachments);
free(mesh->indices.raw);
free(mesh);
}
@ -133,9 +132,8 @@ void lovrMeshDetachAttribute(Mesh* mesh, const char* name) {
}
void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
if (mesh->isMapped) {
lovrMeshUnmap(mesh);
}
lovrMeshUnmapVertices(mesh);
lovrMeshUnmapIndices(mesh);
if (transform) {
lovrGraphicsPush();
@ -147,10 +145,10 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
lovrGraphicsBindVertexArray(mesh->vao);
lovrMeshBindAttributes(mesh);
size_t start = mesh->rangeStart;
size_t count = mesh->rangeCount;
size_t count = mesh->rangeCount ? mesh->rangeCount : mesh->count;
if (mesh->indexCount > 0) {
size_t offset = start * mesh->indexSize;
count = mesh->isRangeEnabled ? mesh->rangeCount : mesh->indexCount;
count = mesh->rangeCount ? mesh->rangeCount : mesh->indexCount;
lovrGraphicsDrawElements(mesh->drawMode, count, mesh->indexSize, offset, instances);
} else {
lovrGraphicsDrawArrays(mesh->drawMode, start, count, instances);
@ -162,7 +160,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
}
VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh) {
return &mesh->vertexData->format;
return &mesh->format;
}
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh) {
@ -174,32 +172,7 @@ void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode) {
}
int lovrMeshGetVertexCount(Mesh* mesh) {
return mesh->vertexData->count;
}
IndexPointer lovrMeshGetVertexMap(Mesh* mesh, size_t* count) {
if (count) {
*count = mesh->indexCount;
}
return mesh->indices;
}
void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count) {
if (!data || count == 0) {
mesh->indexCount = 0;
return;
}
if (mesh->indexCount < count) {
mesh->indices.raw = realloc(mesh->indices.raw, count * mesh->indexSize);
}
mesh->indexCount = count;
memcpy(mesh->indices.raw, data, mesh->indexCount * mesh->indexSize);
lovrGraphicsBindVertexArray(mesh->vao);
lovrGraphicsBindIndexBuffer(mesh->ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->indexCount * mesh->indexSize, mesh->indices.raw, GL_STATIC_DRAW);
return mesh->count;
}
bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
@ -214,26 +187,13 @@ void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enable) {
attachment->enabled = enable;
}
bool lovrMeshIsRangeEnabled(Mesh* mesh) {
return mesh->isRangeEnabled;
}
void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled) {
mesh->isRangeEnabled = isEnabled;
if (!isEnabled) {
mesh->rangeStart = 0;
mesh->rangeCount = mesh->vertexData->count;
}
}
void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count) {
*start = mesh->rangeStart;
*count = mesh->rangeCount;
}
void lovrMeshSetDrawRange(Mesh* mesh, int start, int count) {
size_t limit = mesh->indexCount > 0 ? mesh->indexCount : mesh->vertexData->count;
size_t limit = mesh->indexCount > 0 ? mesh->indexCount : mesh->count;
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;
@ -252,48 +212,100 @@ void lovrMeshSetMaterial(Mesh* mesh, Material* material) {
}
}
VertexPointer lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) {
VertexPointer lovrMeshMapVertices(Mesh* mesh, uint32_t start, uint32_t count, bool read, bool write) {
#ifdef EMSCRIPTEN
mesh->isMapped = true;
mesh->mappedVertices = true;
mesh->mapStart = start;
mesh->mapCount = count;
VertexPointer pointer = { .raw = mesh->vertexData->blob.data };
pointer.bytes += start * mesh->vertexData->format.stride;
return pointer;
return (VertexPointer) { .bytes = mesh->data.bytes + start * mesh->format.stride };
#else
if (mesh->isMapped) {
lovrMeshUnmap(mesh);
if (mesh->mappedVertices) {
lovrMeshUnmapVertices(mesh);
}
mesh->isMapped = true;
mesh->mappedVertices = true;
mesh->mapStart = start;
mesh->mapCount = count;
size_t stride = mesh->vertexData->format.stride;
GLbitfield access = 0;
access |= read ? GL_MAP_READ_BIT : 0;
access |= write ? GL_MAP_WRITE_BIT : 0;
size_t stride = mesh->format.stride;
GLbitfield access = (read ? GL_MAP_READ_BIT : 0) | (write ? GL_MAP_WRITE_BIT : 0);
lovrGraphicsBindVertexBuffer(mesh->vbo);
VertexPointer pointer;
pointer.raw = glMapBufferRange(GL_ARRAY_BUFFER, start * stride, count * stride, access);
return pointer;
return (VertexPointer) { .raw = glMapBufferRange(GL_ARRAY_BUFFER, start * stride, count * stride, access) };
#endif
}
void lovrMeshUnmap(Mesh* mesh) {
if (!mesh->isMapped) {
void lovrMeshUnmapVertices(Mesh* mesh) {
if (!mesh->mappedVertices) {
return;
}
mesh->isMapped = false;
mesh->mappedVertices = false;
lovrGraphicsBindVertexBuffer(mesh->vbo);
#ifdef EMSCRIPTEN
size_t stride = mesh->vertexData->format.stride;
size_t stride = mesh->format.stride;
size_t start = mesh->mapStart * stride;
size_t count = mesh->mapCount * stride;
VertexPointer vertices = { .raw = mesh->vertexData->blob.data };
glBufferSubData(GL_ARRAY_BUFFER, start, count, vertices.bytes + start);
glBufferSubData(GL_ARRAY_BUFFER, start, count, mesh->data.bytes + start);
#else
glUnmapBuffer(GL_ARRAY_BUFFER);
#endif
}
IndexPointer lovrMeshReadIndices(Mesh* mesh, uint32_t* count, size_t* size) {
if (mesh->indexCount == 0) {
return (IndexPointer) { .raw = NULL };
}
*size = mesh->indexSize;
*count = mesh->indexCount;
#ifdef EMSCRIPTEN
return mesh->indices;
#endif
lovrGraphicsBindIndexBuffer(mesh->ibo);
mesh->mappedIndices = true;
return (IndexPointer) { .raw = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->indexCount * mesh->indexSize, GL_MAP_READ_BIT) };
}
IndexPointer lovrMeshWriteIndices(Mesh* mesh, uint32_t count, size_t size) {
mesh->indexSize = size;
mesh->indexCount = count;
if (count == 0) {
return (IndexPointer) { .raw = NULL };
}
lovrGraphicsBindVertexArray(mesh->vao);
lovrGraphicsBindIndexBuffer(mesh->ibo);
mesh->mappedIndices = true;
if (mesh->indexCapacity < size * count) {
mesh->indexCapacity = nextPo2(size * count);
#ifdef EMSCRIPTEN
mesh->indices = realloc(mesh->indices.raw, mesh->indexCapacity);
#else
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->indexCapacity, NULL, mesh->usage);
#endif
}
#ifdef EMSCRIPTEN
return mesh->indices;
#else
return (IndexPointer) { .raw = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * count, GL_MAP_WRITE_BIT) };
#endif
}
void lovrMeshUnmapIndices(Mesh* mesh) {
if (!mesh->mappedIndices) {
return;
}
mesh->mappedIndices = false;
lovrGraphicsBindIndexBuffer(mesh->ibo);
#ifdef EMSCRIPTEN
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->indexCount * mesh->indexSize, mesh->indices.raw);
#else
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
#endif
}

View File

@ -37,28 +37,33 @@ typedef map_t(MeshAttachment) map_attachment_t;
struct Mesh {
Ref ref;
VertexData* vertexData;
IndexPointer indices;
size_t indexCount;
size_t indexSize;
bool isMapped;
int mapStart;
size_t mapCount;
bool isRangeEnabled;
int rangeStart;
int rangeCount;
uint32_t count;
VertexFormat format;
MeshDrawMode drawMode;
MeshUsage usage;
#ifdef EMSCRIPTEN
VertexPointer data;
IndexPointer indices;
#endif
uint32_t indexCount;
size_t indexSize;
size_t indexCapacity;
bool mappedIndices;
bool mappedVertices;
int mapStart;
size_t mapCount;
int rangeStart;
int rangeCount;
GLuint vao;
GLuint vbo;
GLuint ibo;
Material* material;
map_attachment_t attachments;
MeshAttachment layout[16];
MeshAttachment layout[MAX_ATTACHMENTS];
bool isAttachment;
};
Mesh* lovrMeshCreate(VertexData* vertexData, MeshDrawMode drawMode, MeshUsage usage);
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, MeshUsage usage);
void lovrMeshDestroy(void* ref);
void lovrMeshAttachAttribute(Mesh* mesh, Mesh* other, const char* name, int divisor);
void lovrMeshDetachAttribute(Mesh* mesh, const char* name);
@ -67,15 +72,14 @@ VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh);
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
int lovrMeshGetVertexCount(Mesh* mesh);
IndexPointer 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);
bool lovrMeshIsRangeEnabled(Mesh* mesh);
void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled);
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);
VertexPointer lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write);
void lovrMeshUnmap(Mesh* mesh);
VertexPointer lovrMeshMapVertices(Mesh* mesh, uint32_t start, uint32_t count, bool read, bool write);
void lovrMeshUnmapVertices(Mesh* mesh);
IndexPointer lovrMeshReadIndices(Mesh* mesh, uint32_t* count, size_t* size);
IndexPointer lovrMeshWriteIndices(Mesh* mesh, uint32_t count, size_t size);
void lovrMeshUnmapIndices(Mesh* mesh);

View File

@ -57,12 +57,12 @@ Model* lovrModelCreate(ModelData* modelData) {
model->modelData = modelData;
model->aabbDirty = true;
model->mesh = lovrMeshCreate(modelData->vertexData, MESH_TRIANGLES, MESH_STATIC);
VertexPointer vertices = lovrMeshMap(model->mesh, 0, modelData->vertexData->count, false, true);
model->mesh = lovrMeshCreate(modelData->vertexData->count, modelData->vertexData->format, MESH_TRIANGLES, MESH_STATIC);
VertexPointer vertices = lovrMeshMapVertices(model->mesh, 0, modelData->vertexData->count, false, true);
memcpy(vertices.raw, modelData->vertexData->blob.data, modelData->vertexData->count * modelData->vertexData->format.stride);
lovrMeshUnmap(model->mesh);
lovrMeshSetVertexMap(model->mesh, modelData->indices.raw, modelData->indexCount);
lovrMeshSetRangeEnabled(model->mesh, true);
IndexPointer indices = lovrMeshWriteIndices(model->mesh, modelData->indexCount, modelData->indexSize);
memcpy(indices.raw, modelData->indices.raw, modelData->indexCount * modelData->indexSize);
if (modelData->textures.length > 0) {
model->textures = malloc(modelData->textures.length * sizeof(Texture*));

View File

@ -595,7 +595,7 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
vertexFormatAppend(&format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrTexCoord", ATTR_FLOAT, 2);
modelData->vertexData = lovrVertexDataCreate(vrModel->unVertexCount, &format, true);
modelData->vertexData = lovrVertexDataCreate(vrModel->unVertexCount, &format);
float* vertices = (float*) modelData->vertexData->blob.data;
int vertex = 0;

View File

@ -98,3 +98,14 @@ fallback:
*pch = ch;
return 1;
}
uint32_t nextPo2(uint32_t x) {
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
return x;
}

View File

@ -28,3 +28,4 @@ void* lovrAlloc(size_t size, void (*destructor)(void* object));
void lovrRetain(void* object);
void lovrRelease(void* object);
size_t utf8_decode(const char *s, const char *e, unsigned *pch);
uint32_t nextPo2(uint32_t x);