mirror of https://github.com/bjornbytes/lovr.git
Make Mesh more lightweight;
This commit is contained in:
parent
d2e0642b59
commit
d77b139d21
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = ¤t.mesh->vertexData->format;
|
||||
VertexFormat* format = ¤t.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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*));
|
||||
|
|
|
@ -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;
|
||||
|
|
11
src/util.c
11
src/util.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue