Add VertexData object;

This commit is contained in:
bjorn 2018-02-10 17:27:29 -08:00
parent 1d0ca6b763
commit 8ad882e7a4
16 changed files with 437 additions and 310 deletions

View File

@ -57,6 +57,7 @@ extern const luaL_Reg lovrSphereShape[];
extern const luaL_Reg lovrTexture[];
extern const luaL_Reg lovrTextureData[];
extern const luaL_Reg lovrTransform[];
extern const luaL_Reg lovrVertexData[];
extern const luaL_Reg lovrWorld[];
// Enums
@ -90,8 +91,12 @@ extern map_int_t VerticalAligns;
extern map_int_t WrapModes;
// Shared helpers
void luax_checkvertexformat(lua_State* L, int index, VertexFormat* format);
int luax_pushvertexformat(lua_State* L, VertexFormat* format);
int luax_pushvertex(lua_State* L, VertexData* vertex, VertexFormat* format);
int luax_pushvertexattribute(lua_State* L, VertexPointer* vertex, Attribute attribute);
int luax_pushvertex(lua_State* L, VertexPointer* vertex, VertexFormat* format);
void luax_setvertexattribute(lua_State* L, int index, VertexPointer* vertex, Attribute attribute);
void luax_setvertex(lua_State* L, int index, VertexPointer* vertex, VertexFormat* format);
int luax_readtransform(lua_State* L, int index, mat4 transform, bool uniformScale);
Blob* luax_readblob(lua_State* L, int index, const char* debug);
int luax_pushshape(lua_State* L, Shape* shape);

View File

@ -12,6 +12,7 @@ int l_lovrDataInit(lua_State* L) {
luax_registertype(L, "ModelData", lovrModelData);
luax_registertype(L, "Rasterizer", lovrRasterizer);
luax_registertype(L, "TextureData", lovrTextureData);
luax_registertype(L, "VertexData", lovrVertexData);
return 1;
}
@ -34,23 +35,6 @@ int l_lovrDataNewModelData(lua_State* L) {
return 1;
}
int l_lovrDataNewTextureData(lua_State* L) {
TextureData* textureData = NULL;
if (lua_type(L, 1) == LUA_TNUMBER) {
int width = luaL_checknumber(L, 1);
int height = luaL_checknumber(L, 2);
textureData = lovrTextureDataGetBlank(width, height, 0x0, FORMAT_RGBA);
} else {
Blob* blob = luax_readblob(L, 1, "Texture");
textureData = lovrTextureDataFromBlob(blob);
lovrRelease(&blob->ref);
}
luax_pushtype(L, TextureData, textureData);
lovrRelease(&textureData->ref);
return 1;
}
int l_lovrDataNewRasterizer(lua_State* L) {
Blob* blob = NULL;
float size;
@ -73,10 +57,39 @@ int l_lovrDataNewRasterizer(lua_State* L) {
return 1;
}
int l_lovrDataNewTextureData(lua_State* L) {
TextureData* textureData = NULL;
if (lua_type(L, 1) == LUA_TNUMBER) {
int width = luaL_checknumber(L, 1);
int height = luaL_checknumber(L, 2);
textureData = lovrTextureDataGetBlank(width, height, 0x0, FORMAT_RGBA);
} else {
Blob* blob = luax_readblob(L, 1, "Texture");
textureData = lovrTextureDataFromBlob(blob);
lovrRelease(&blob->ref);
}
luax_pushtype(L, TextureData, textureData);
lovrRelease(&textureData->ref);
return 1;
}
int l_lovrDataNewVertexData(lua_State* L) {
uint32_t count = luaL_checkinteger(L, 1);
VertexFormat format;
vertexFormatInit(&format);
luax_checkvertexformat(L, 2, &format);
VertexData* vertexData = lovrVertexDataCreate(count, format.count > 0 ? &format : NULL, true);
luax_pushtype(L, VertexData, vertexData);
lovrRelease(&vertexData->ref);
return 1;
}
const luaL_Reg lovrData[] = {
{ "newAudioStream", l_lovrDataNewAudioStream },
{ "newModelData", l_lovrDataNewModelData },
{ "newRasterizer", l_lovrDataNewRasterizer },
{ "newTextureData", l_lovrDataNewTextureData },
{ "newVertexData", l_lovrDataNewVertexData },
{ NULL, NULL }
};

View File

@ -8,8 +8,8 @@
#include "data/model.h"
#include "data/rasterizer.h"
#include "data/texture.h"
#include "data/vertexData.h"
#include "filesystem/filesystem.h"
#include "lib/vertex.h"
#include <math.h>
#include <stdbool.h>
@ -79,33 +79,6 @@ static void stencilCallback(void* userdata) {
lua_call(L, 0, 0);
}
static void luax_checkvertexformat(lua_State* L, int index, VertexFormat* format) {
if (!lua_istable(L, index)) {
return;
}
int length = lua_objlen(L, index);
lovrAssert(length <= 8, "Only 8 vertex attributes are supported");
for (int i = 0; i < length; i++) {
lua_rawgeti(L, index, i + 1);
if (!lua_istable(L, -1) || lua_objlen(L, -1) != 3) {
luaL_error(L, "Expected vertex format specified as tables containing name, data type, and size");
return;
}
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
lua_rawgeti(L, -3, 3);
const char* name = lua_tostring(L, -3);
AttributeType* type = (AttributeType*) luax_checkenum(L, -2, &AttributeTypes, "mesh attribute type");
int count = lua_tointeger(L, -1);
vertexFormatAppend(format, name, *type, count);
lua_pop(L, 4);
}
}
static TextureData* luax_checktexturedata(lua_State* L, int index) {
void** type;
if ((type = luax_totype(L, index, TextureData)) != NULL) {
@ -978,7 +951,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
if (dataIndex) {
int count = lua_objlen(L, dataIndex);
format = *lovrMeshGetVertexFormat(mesh);
VertexData vertices = lovrMeshMap(mesh, 0, count, false, true);
VertexPointer vertices = lovrMeshMap(mesh, 0, count, false, true);
for (int i = 0; i < count; i++) {
lua_rawgeti(L, dataIndex, i + 1);

View File

@ -1,46 +1,5 @@
#include "api.h"
int luax_pushvertexformat(lua_State* L, VertexFormat* format) {
lua_newtable(L);
for (int i = 0; i < format->count; i++) {
Attribute attribute = format->attributes[i];
lua_newtable(L);
// Name
lua_pushstring(L, attribute.name);
lua_rawseti(L, -2, 1);
// Type
luax_pushenum(L, &AttributeTypes, attribute.type);
lua_rawseti(L, -2, 2);
// Count
lua_pushinteger(L, attribute.count);
lua_rawseti(L, -2, 3);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
int luax_pushvertex(lua_State* L, VertexData* vertex, VertexFormat* format) {
int count = 0;
for (int i = 0; i < format->count; i++) {
Attribute attribute = format->attributes[i];
count += attribute.count;
for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) {
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;
}
}
}
return count;
}
int l_lovrMeshDrawInstanced(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int instances = luaL_checkinteger(L, 2);
@ -56,12 +15,6 @@ int l_lovrMeshDraw(lua_State* L) {
return l_lovrMeshDrawInstanced(L);
}
int l_lovrMeshGetVertexFormat(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
return luax_pushvertexformat(L, format);
}
int l_lovrMeshGetDrawMode(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
luax_pushenum(L, &MeshDrawModes, lovrMeshGetDrawMode(mesh));
@ -75,16 +28,22 @@ int l_lovrMeshSetDrawMode(lua_State* L) {
return 0;
}
int l_lovrMeshGetVertexFormat(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
return luax_pushvertexformat(L, format);
}
int l_lovrMeshGetVertexCount(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
lua_pushnumber(L, lovrMeshGetVertexCount(mesh));
lua_pushinteger(L, lovrMeshGetVertexCount(mesh));
return 1;
}
int l_lovrMeshGetVertex(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int index = luaL_checkint(L, 2) - 1;
VertexData vertex = lovrMeshMap(mesh, index, 1, true, false);
VertexPointer vertex = lovrMeshMap(mesh, index, 1, true, false);
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
return luax_pushvertex(L, &vertex, format);
}
@ -92,34 +51,10 @@ int l_lovrMeshGetVertex(lua_State* L) {
int l_lovrMeshSetVertex(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int index = luaL_checkint(L, 2) - 1;
if (index < 0 || index >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", index + 1);
}
lovrAssert(index >= 0 && index < lovrMeshGetVertexCount(mesh), "Invalid mesh vertex index: %d", index + 1);
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
VertexData vertex = lovrMeshMap(mesh, index, 1, false, true);
// Unwrap table
int arg = 3;
if (lua_istable(L, 3)) {
arg++;
for (size_t i = 0; i < lua_objlen(L, 3); i++) {
lua_rawgeti(L, 3, i + 1);
}
}
for (int i = 0; i < format->count; i++) {
Attribute attribute = format->attributes[i];
for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) {
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;
}
}
}
VertexPointer vertex = lovrMeshMap(mesh, index, 1, false, true);
luax_setvertex(L, 3, &vertex, format);
return 0;
}
@ -128,25 +63,12 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
int vertexIndex = luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1;
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1);
} else if (attributeIndex < 0 || attributeIndex >= format->count) {
return luaL_error(L, "Invalid mesh attribute index: %d", attributeIndex + 1);
}
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];
VertexData vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false);
VertexPointer 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, *vertex.floats++); break;
case ATTR_BYTE: lua_pushinteger(L, *vertex.bytes++); break;
case ATTR_INT: lua_pushinteger(L, *vertex.ints++); break;
}
}
return attribute.count;
return luax_pushvertexattribute(L, &vertex, attribute);
}
int l_lovrMeshSetVertexAttribute(lua_State* L) {
@ -154,25 +76,12 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
int vertexIndex = luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1;
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1);
} else if (attributeIndex < 0 || attributeIndex >= format->count) {
return luaL_error(L, "Invalid mesh attribute index: %d", attributeIndex + 1);
}
int arg = 4;
VertexData vertex = lovrMeshMap(mesh, vertexIndex, 1, false, true);
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);
vertex.bytes += attribute.offset;
for (int i = 0; i < attribute.count; i++) {
switch (attribute.type) {
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;
}
}
luax_setvertexattribute(L, 4, &vertex, attribute);
return 0;
}
@ -183,28 +92,13 @@ int l_lovrMeshSetVertices(lua_State* L) {
int vertexCount = lua_objlen(L, 2);
int start = luaL_optnumber(L, 3, 1) - 1;
int maxVertices = lovrMeshGetVertexCount(mesh);
if (start + vertexCount > maxVertices) {
return luaL_error(L, "Mesh can only hold %d vertices", maxVertices);
}
VertexData vertices = lovrMeshMap(mesh, start, vertexCount, false, true);
lovrAssert(start + vertexCount <= maxVertices, "Overflow in Mesh:setVertices: Mesh can only hold %d vertices", maxVertices);
VertexPointer vertices = lovrMeshMap(mesh, start, vertexCount, false, true);
for (int i = 0; i < vertexCount; i++) {
lua_rawgeti(L, 2, i + 1);
int component = 0;
for (int j = 0; j < format->count; j++) {
Attribute attribute = format->attributes[j];
for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component);
switch (attribute.type) {
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;
}
lua_pop(L, 1);
}
}
luaL_checktype(L, -1, LUA_TTABLE);
luax_setvertex(L, -1, &vertices, format);
lua_pop(L, 1);
}
@ -214,7 +108,7 @@ int l_lovrMeshSetVertices(lua_State* L) {
int l_lovrMeshGetVertexMap(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
size_t count;
IndexData indices = lovrMeshGetVertexMap(mesh, &count);
IndexPointer indices = lovrMeshGetVertexMap(mesh, &count);
if (count == 0) {
lua_pushnil(L);
@ -243,8 +137,8 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
int count = lua_objlen(L, 2);
int vertexCount = lovrMeshGetVertexCount(mesh);
int indexSize = mesh->indexSize;
IndexData indices = lovrMeshGetVertexMap(mesh, NULL);
indices.data = realloc(indices.data, indexSize * count);
IndexPointer indices = lovrMeshGetVertexMap(mesh, NULL);
indices.raw = realloc(indices.raw, indexSize * count);
for (int i = 0; i < count; i++) {
lua_rawgeti(L, 2, i + 1);
@ -266,7 +160,7 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
lua_pop(L, 1);
}
lovrMeshSetVertexMap(mesh, indices.data, count);
lovrMeshSetVertexMap(mesh, indices.raw, count);
return 0;
}

View File

@ -21,21 +21,13 @@ int l_lovrModelDataGetMaterialCount(lua_State* L) {
int l_lovrModelDataGetVertexCount(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, modelData->vertexCount);
lua_pushinteger(L, modelData->vertexData->count);
return 1;
}
int l_lovrModelDataGetVertexFormat(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
return luax_pushvertexformat(L, &modelData->format);
}
int l_lovrModelDataGetVertex(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
VertexData vertex = modelData->vertices;
vertex.bytes += index * modelData->format.stride;
return luax_pushvertex(L, &vertex, &modelData->format);
return luax_pushvertexformat(L, &modelData->vertexData->format);
}
int l_lovrModelDataGetTriangleCount(lua_State* L) {

214
src/api/types/vertexData.c Normal file
View File

@ -0,0 +1,214 @@
#include "api.h"
void luax_checkvertexformat(lua_State* L, int index, VertexFormat* format) {
if (!lua_istable(L, index)) {
return;
}
int length = lua_objlen(L, index);
lovrAssert(length <= 8, "Only 8 vertex attributes are supported");
for (int i = 0; i < length; i++) {
lua_rawgeti(L, index, i + 1);
if (!lua_istable(L, -1) || lua_objlen(L, -1) != 3) {
luaL_error(L, "Expected vertex format specified as tables containing name, data type, and size");
return;
}
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
lua_rawgeti(L, -3, 3);
const char* name = lua_tostring(L, -3);
AttributeType* type = (AttributeType*) luax_checkenum(L, -2, &AttributeTypes, "mesh attribute type");
int count = lua_tointeger(L, -1);
vertexFormatAppend(format, name, *type, count);
lua_pop(L, 4);
}
}
int luax_pushvertexformat(lua_State* L, VertexFormat* format) {
lua_newtable(L);
for (int i = 0; i < format->count; i++) {
Attribute attribute = format->attributes[i];
lua_newtable(L);
// Name
lua_pushstring(L, attribute.name);
lua_rawseti(L, -2, 1);
// Type
luax_pushenum(L, &AttributeTypes, attribute.type);
lua_rawseti(L, -2, 2);
// Count
lua_pushinteger(L, attribute.count);
lua_rawseti(L, -2, 3);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
int luax_pushvertexattribute(lua_State* L, VertexPointer* vertex, Attribute attribute) {
for (int i = 0; i < attribute.count; i++) {
switch (attribute.type) {
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;
}
}
return attribute.count;
}
int luax_pushvertex(lua_State* L, VertexPointer* vertex, VertexFormat* format) {
int count = 0;
for (int i = 0; i < format->count; i++) {
count += luax_pushvertexattribute(L, vertex, format->attributes[i]);
}
return count;
}
void luax_setvertexattribute(lua_State* L, int index, VertexPointer* vertex, Attribute attribute) {
for (int i = 0; i < attribute.count; i++) {
switch (attribute.type) {
case ATTR_FLOAT: *vertex->floats++ = luaL_optnumber(L, index++, 0.f); break;
case ATTR_BYTE: *vertex->bytes++ = luaL_optint(L, index++, 255); break;
case ATTR_INT: *vertex->ints++ = luaL_optint(L, index++, 0); break;
}
}
}
void luax_setvertex(lua_State* L, int index, VertexPointer* vertex, VertexFormat* format) {
if (lua_istable(L, index)) {
int component = 0;
for (int i = 0; i < format->count; i++) {
Attribute attribute = format->attributes[i];
for (int j = 0; j < attribute.count; j++) {
lua_rawgeti(L, index, ++component);
switch (attribute.type) {
case ATTR_FLOAT: *vertex->floats++ = luaL_optnumber(L, -1, 0.f); break;
case ATTR_BYTE: *vertex->bytes++ = luaL_optint(L, -1, 255); break;
case ATTR_INT: *vertex->ints++ = luaL_optint(L, -1, 0); break;
}
lua_pop(L, 1);
}
}
} else {
for (int i = 0; i < format->count; i++) {
luax_setvertexattribute(L, index, vertex, format->attributes[i]);
index += format->attributes[i].count;
}
}
}
//
int l_lovrVertexDataGetPointer(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
lua_pushlightuserdata(L, vertexData->data.raw);
return 1;
}
int l_lovrVertexDataGetSize(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
lua_pushinteger(L, vertexData->count * vertexData->format.stride);
return 1;
}
int l_lovrVertexDataGetString(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
lua_pushlstring(L, vertexData->data.raw, vertexData->count * vertexData->format.stride);
return 1;
}
int l_lovrVertexDataGetCount(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
uint32_t count = vertexData->count;
lua_pushinteger(L, count);
return 1;
}
int l_lovrVertexDataGetFormat(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
return luax_pushvertexformat(L, &vertexData->format);
}
int l_lovrVertexDataGetVertex(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
uint32_t index = (uint32_t) luaL_checkint(L, 2) - 1;
VertexPointer vertex = { .raw = vertexData->data.bytes + index * vertexData->format.stride };
return luax_pushvertex(L, &vertex, &vertexData->format);
}
int l_lovrVertexDataSetVertex(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
uint32_t index = (uint32_t) luaL_checkint(L, 2) - 1;
lovrAssert(index < vertexData->count, "Invalid vertex index: %d", index + 1);
VertexFormat* format = &vertexData->format;
VertexPointer* vertex = &vertexData->data;
vertex->bytes += index * format->stride;
luax_setvertex(L, 3, vertex, format);
return 0;
}
int l_lovrVertexDataGetVertexAttribute(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
uint32_t vertexIndex = (uint32_t) luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1;
VertexFormat* format = &vertexData->format;
lovrAssert(vertexIndex < vertexData->count, "Invalid vertex index: %d", vertexIndex + 1);
lovrAssert(attributeIndex >= 0 && attributeIndex < format->count, "Invalid attribute index: %d", attributeIndex + 1);
Attribute attribute = format->attributes[attributeIndex];
VertexPointer vertex = vertexData->data;
vertex.bytes += vertexIndex * format->stride + attribute.offset;
return luax_pushvertexattribute(L, &vertex, attribute);
}
int l_lovrVertexDataSetVertexAttribute(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
uint32_t vertexIndex = (uint32_t) luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1;
VertexFormat* format = &vertexData->format;
lovrAssert(vertexIndex < vertexData->count, "Invalid vertex index: %d", vertexIndex + 1);
lovrAssert(attributeIndex >= 0 && attributeIndex < format->count, "Invalid attribute index: %d", attributeIndex + 1);
Attribute attribute = format->attributes[attributeIndex];
VertexPointer vertex = vertexData->data;
vertex.bytes += vertexIndex * format->stride + attribute.offset;
luax_setvertexattribute(L, 4, &vertex, attribute);
return 0;
}
int l_lovrVertexDataSetVertices(lua_State* L) {
VertexData* vertexData = luax_checktype(L, 1, VertexData);
VertexFormat* format = &vertexData->format;
luaL_checktype(L, 2, LUA_TTABLE);
uint32_t vertexCount = lua_objlen(L, 2);
int start = luaL_optnumber(L, 3, 1) - 1;
lovrAssert(start + vertexCount <= vertexData->count, "VertexData can only hold %d vertices", vertexData->count);
VertexPointer vertices = vertexData->data;
vertices.bytes += start * format->stride;
for (uint32_t i = 0; i < vertexCount; i++) {
lua_rawgeti(L, 2, i + 1);
luaL_checktype(L, -1, LUA_TTABLE);
luax_setvertex(L, -1, &vertices, format);
lua_pop(L, 1);
}
return 0;
}
const luaL_Reg lovrVertexData[] = {
{ "getPointer", l_lovrVertexDataGetPointer },
{ "getSize", l_lovrVertexDataGetSize },
{ "getString", l_lovrVertexDataGetString },
{ "getCount", l_lovrVertexDataGetCount },
{ "getFormat", l_lovrVertexDataGetFormat },
{ "getVertex", l_lovrVertexDataGetVertex },
{ "setVertex", l_lovrVertexDataSetVertex },
{ "getVertexAttribute", l_lovrVertexDataGetVertexAttribute },
{ "setVertexAttribute", l_lovrVertexDataSetVertexAttribute },
{ "setVertices", l_lovrVertexDataSetVertices },
{ NULL, NULL }
};

View File

@ -255,9 +255,9 @@ ModelData* lovrModelDataCreate(Blob* blob) {
}
modelData->nodeCount = 0;
modelData->vertexCount = 0;
modelData->indexCount = 0;
uint32_t vertexCount = 0;
bool hasNormals = false;
bool hasUVs = false;
bool hasVertexColors = false;
@ -265,7 +265,7 @@ ModelData* lovrModelDataCreate(Blob* blob) {
for (unsigned int m = 0; m < scene->mNumMeshes; m++) {
struct aiMesh* assimpMesh = scene->mMeshes[m];
modelData->vertexCount += assimpMesh->mNumVertices;
vertexCount += assimpMesh->mNumVertices;
modelData->indexCount += assimpMesh->mNumFaces * 3;
hasNormals |= assimpMesh->mNormals != NULL;
hasUVs |= assimpMesh->mTextureCoords[0] != NULL;
@ -273,26 +273,26 @@ ModelData* lovrModelDataCreate(Blob* blob) {
isSkinned |= assimpMesh->mNumBones > 0;
}
vertexFormatInit(&modelData->format);
vertexFormatAppend(&modelData->format, "lovrPosition", ATTR_FLOAT, 3);
VertexFormat format;
vertexFormatInit(&format);
vertexFormatAppend(&format, "lovrPosition", ATTR_FLOAT, 3);
if (hasNormals) vertexFormatAppend(&modelData->format, "lovrNormal", ATTR_FLOAT, 3);
if (hasUVs) vertexFormatAppend(&modelData->format, "lovrTexCoord", ATTR_FLOAT, 2);
if (hasVertexColors) vertexFormatAppend(&modelData->format, "lovrVertexColor", ATTR_BYTE, 4);
size_t boneByteOffset = modelData->format.stride;
if (isSkinned) vertexFormatAppend(&modelData->format, "lovrBones", ATTR_INT, 4);
if (isSkinned) vertexFormatAppend(&modelData->format, "lovrBoneWeights", ATTR_FLOAT, 4);
if (hasNormals) vertexFormatAppend(&format, "lovrNormal", ATTR_FLOAT, 3);
if (hasUVs) vertexFormatAppend(&format, "lovrTexCoord", ATTR_FLOAT, 2);
if (hasVertexColors) vertexFormatAppend(&format, "lovrVertexColor", ATTR_BYTE, 4);
size_t boneByteOffset = format.stride;
if (isSkinned) vertexFormatAppend(&format, "lovrBones", ATTR_INT, 4);
if (isSkinned) vertexFormatAppend(&format, "lovrBoneWeights", ATTR_FLOAT, 4);
// Allocate
modelData->vertexData = lovrVertexDataCreate(vertexCount, &format, true);
modelData->indexSize = vertexCount > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
modelData->indices.raw = malloc(modelData->indexCount * modelData->indexSize);
modelData->primitiveCount = scene->mNumMeshes;
modelData->primitives = malloc(modelData->primitiveCount * sizeof(ModelPrimitive));
modelData->indexSize = modelData->vertexCount > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
modelData->vertices.data = malloc(modelData->format.stride * modelData->vertexCount);
modelData->indices.data = malloc(modelData->indexCount * modelData->indexSize);
memset(modelData->vertices.data, 0, modelData->format.stride * modelData->vertexCount);
// Load vertices
IndexData indices = modelData->indices;
IndexPointer indices = modelData->indices;
uint32_t vertex = 0;
uint32_t index = 0;
for (unsigned int m = 0; m < scene->mNumMeshes; m++) {
@ -323,8 +323,8 @@ ModelData* lovrModelDataCreate(Blob* blob) {
// Vertices
for (unsigned int v = 0; v < assimpMesh->mNumVertices; v++) {
VertexData vertices = modelData->vertices;
vertices.bytes += vertex * modelData->format.stride;
VertexPointer vertices = modelData->vertexData->data;
vertices.bytes += vertex * modelData->vertexData->format.stride;
*vertices.floats++ = assimpMesh->mVertices[v].x;
*vertices.floats++ = assimpMesh->mVertices[v].y;
@ -384,8 +384,8 @@ 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;
VertexData vertices = modelData->vertices;
vertices.bytes += vertexIndex * modelData->format.stride;
VertexPointer vertices = modelData->vertexData->data;
vertices.bytes += vertexIndex * modelData->vertexData->format.stride;
uint32_t* bones = (uint32_t*) (vertices.bytes + boneByteOffset);
float* weights = (float*) (bones + MAX_BONES_PER_VERTEX);
@ -515,12 +515,13 @@ void lovrModelDataDestroy(const Ref* ref) {
vec_deinit(&modelData->textures);
map_deinit(&modelData->nodeMap);
lovrRelease(&modelData->vertexData->ref);
free(modelData->nodes);
free(modelData->primitives);
free(modelData->animations);
free(modelData->materials);
free(modelData->vertices.data);
free(modelData->indices.data);
free(modelData->indices.raw);
free(modelData);
}
@ -537,7 +538,7 @@ static void aabbIterator(ModelData* modelData, ModelNode* node, float aabb[6], m
} else {
index = modelData->indices.ints[primitive->drawStart + j];
}
vec3_init(vertex, (float*) (modelData->vertices.bytes + index * modelData->format.stride));
vec3_init(vertex, (float*) (modelData->vertexData->data.bytes + index * modelData->vertexData->format.stride));
mat4_transform(transform, vertex);
aabb[0] = MIN(aabb[0], vertex[0]);
aabb[1] = MAX(aabb[1], vertex[0]);

View File

@ -1,6 +1,6 @@
#include "filesystem/blob.h"
#include "data/vertexData.h"
#include "util.h"
#include "lib/vertex.h"
#include "lib/map/map.h"
#include "lib/vec/vec.h"
@ -61,22 +61,20 @@ typedef struct {
typedef struct {
Ref ref;
VertexData* vertexData;
IndexPointer indices;
int indexCount;
size_t indexSize;
ModelNode* nodes;
map_int_t nodeMap;
ModelPrimitive* primitives;
Animation* animations;
ModelMaterial* materials;
vec_void_t textures;
VertexFormat format;
VertexData vertices;
IndexData indices;
int nodeCount;
int primitiveCount;
int animationCount;
int materialCount;
int vertexCount;
int indexCount;
size_t indexSize;
} ModelData;
ModelData* lovrModelDataCreate(Blob* blob);

50
src/data/vertexData.c Normal file
View File

@ -0,0 +1,50 @@
#include "data/vertexData.h"
#include <string.h>
#include <stdio.h>
static size_t attributeTypeSizes[3] = { 4, 1, 4 };
void vertexFormatInit(VertexFormat* format) {
memset(format, 0, sizeof(*format));
}
void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count) {
size_t size = attributeTypeSizes[type];
Attribute attribute = { name, type, count, size, format->stride };
format->attributes[format->count++] = attribute;
format->stride += size * count;
}
VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format, bool allocate) {
VertexData* vertexData = lovrAlloc(sizeof(VertexData), lovrVertexDataDestroy);
if (!vertexData) return NULL;
if (format) {
vertexData->format = *format;
} else {
format = &vertexData->format;
vertexFormatInit(&vertexData->format);
vertexFormatAppend(&vertexData->format, "lovrPosition", ATTR_FLOAT, 3);
vertexFormatAppend(&vertexData->format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&vertexData->format, "lovrTexCoord", ATTR_FLOAT, 2);
vertexFormatAppend(&vertexData->format, "lovrVertexColor", ATTR_BYTE, 4);
}
vertexData->count = count;
vertexData->data.raw = NULL;
if (allocate) {
vertexData->data.raw = malloc(format->stride * count);
memset(vertexData->data.raw, 0, format->stride * count);
}
return vertexData;
}
void lovrVertexDataDestroy(const Ref* ref) {
VertexData* vertexData = containerof(ref, VertexData);
if (vertexData->data.raw) {
free(vertexData->data.raw);
}
free(vertexData);
}

View File

@ -1,5 +1,7 @@
#include "util.h"
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#pragma once
@ -24,17 +26,27 @@ typedef struct {
} VertexFormat;
typedef union {
void* data;
void* raw;
float* floats;
uint8_t* bytes;
int* ints;
} VertexData;
} VertexPointer;
typedef union {
void* data;
void* raw;
uint16_t* shorts;
uint32_t* ints;
} IndexData;
} IndexPointer;
typedef struct {
Ref ref;
VertexFormat format;
VertexPointer data;
uint32_t count;
} VertexData;
void vertexFormatInit(VertexFormat* format);
void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count);
VertexData* lovrVertexDataCreate(uint32_t count, VertexFormat* format, bool allocate);
void lovrVertexDataDestroy(const Ref* ref);

View File

@ -12,8 +12,9 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
lovrGraphicsBindVertexBuffer(mesh->vbo);
for (int i = 0; i < mesh->format.count; i++) {
Attribute attribute = mesh->format.attributes[i];
VertexFormat* format = &mesh->vertexData->format;
for (int i = 0; i < format->count; i++) {
Attribute attribute = format->attributes[i];
int location = lovrShaderGetAttributeId(shader, attribute.name);
if (location >= 0) {
@ -28,9 +29,9 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
}
if (attribute.type == ATTR_INT) {
glVertexAttribIPointer(location, attribute.count, glType, mesh->format.stride, (void*) attribute.offset);
glVertexAttribIPointer(location, attribute.count, glType, format->stride, (void*) attribute.offset);
} else {
glVertexAttribPointer(location, attribute.count, glType, GL_TRUE, mesh->format.stride, (void*) attribute.offset);
glVertexAttribPointer(location, attribute.count, glType, GL_TRUE, format->stride, (void*) attribute.offset);
}
} else {
glDisableVertexAttribArray(location);
@ -42,23 +43,17 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
mesh->attributesDirty = false;
}
Mesh* lovrMeshCreate(size_t count, VertexFormat* format, 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;
if (format) {
mesh->format = *format;
} else {
vertexFormatInit(&mesh->format);
vertexFormatAppend(&mesh->format, "lovrPosition", ATTR_FLOAT, 3);
vertexFormatAppend(&mesh->format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&mesh->format, "lovrTexCoord", ATTR_FLOAT, 2);
vertexFormatAppend(&mesh->format, "lovrVertexColor", ATTR_BYTE, 4);
}
#ifdef EMSCRIPTEN
mesh->vertexData = lovrVertexDataCreate(count, format, false);
#else
mesh->vertexData = lovrVertexDataCreate(count, format, true);
#endif
mesh->vertexCount = count;
mesh->vertices.data = NULL;
mesh->indices.data = NULL;
mesh->indices.raw = NULL;
mesh->indexCount = 0;
mesh->indexSize = count > USHRT_MAX ? sizeof(uint32_t) : sizeof(uint16_t);
mesh->enabledAttributes = ~0;
@ -80,13 +75,9 @@ Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode,
glGenBuffers(1, &mesh->vbo);
glGenBuffers(1, &mesh->ibo);
lovrGraphicsBindVertexBuffer(mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount * mesh->format.stride, NULL, mesh->usage);
glBufferData(GL_ARRAY_BUFFER, count * mesh->vertexData->format.stride, NULL, mesh->usage);
glGenVertexArrays(1, &mesh->vao);
#ifdef EMSCRIPTEN
mesh->vertices.data = malloc(mesh->vertexCount * mesh->format.stride);
#endif
return mesh;
}
@ -95,13 +86,11 @@ void lovrMeshDestroy(const Ref* ref) {
if (mesh->material) {
lovrRelease(&mesh->material->ref);
}
lovrRelease(&mesh->vertexData->ref);
glDeleteBuffers(1, &mesh->vbo);
glDeleteBuffers(1, &mesh->ibo);
glDeleteVertexArrays(1, &mesh->vao);
free(mesh->indices.data);
#ifdef EMSCRIPTEN
free(mesh->vertices.data);
#endif
free(mesh->indices.raw);
free(mesh);
}
@ -135,7 +124,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
}
VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh) {
return &mesh->format;
return &mesh->vertexData->format;
}
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh) {
@ -147,10 +136,10 @@ void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode) {
}
int lovrMeshGetVertexCount(Mesh* mesh) {
return mesh->vertexCount;
return mesh->vertexData->count;
}
IndexData lovrMeshGetVertexMap(Mesh* mesh, size_t* count) {
IndexPointer lovrMeshGetVertexMap(Mesh* mesh, size_t* count) {
if (count) {
*count = mesh->indexCount;
}
@ -165,19 +154,19 @@ void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count) {
}
if (mesh->indexCount < count) {
mesh->indices.data = realloc(mesh->indices.data, count * mesh->indexSize);
mesh->indices.raw = realloc(mesh->indices.raw, count * mesh->indexSize);
}
mesh->indexCount = count;
memcpy(mesh->indices.data, data, mesh->indexCount * mesh->indexSize);
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.data, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->indexCount * mesh->indexSize, mesh->indices.raw, GL_STATIC_DRAW);
}
bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
for (int i = 0; i < mesh->format.count; i++) {
if (!strcmp(mesh->format.attributes[i].name, name)) {
for (int i = 0; i < mesh->vertexData->format.count; i++) {
if (!strcmp(mesh->vertexData->format.attributes[i].name, name)) {
return mesh->enabledAttributes & (1 << i);
}
}
@ -186,8 +175,8 @@ bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
}
void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enable) {
for (int i = 0; i < mesh->format.count; i++) {
if (!strcmp(mesh->format.attributes[i].name, name)) {
for (int i = 0; i < mesh->vertexData->format.count; i++) {
if (!strcmp(mesh->vertexData->format.attributes[i].name, name)) {
int mask = 1 << i;
if (enable && !(mesh->enabledAttributes & mask)) {
mesh->enabledAttributes |= mask;
@ -209,7 +198,7 @@ void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled) {
if (!isEnabled) {
mesh->rangeStart = 0;
mesh->rangeCount = mesh->vertexCount;
mesh->rangeCount = mesh->vertexData->count;
}
}
@ -219,7 +208,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->vertexCount;
size_t limit = mesh->indexCount > 0 ? mesh->indexCount : mesh->vertexData->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;
@ -244,12 +233,13 @@ void lovrMeshSetMaterial(Mesh* mesh, Material* material) {
}
}
VertexData lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) {
VertexPointer lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write) {
#ifdef EMSCRIPTEN
mesh->isMapped = true;
mesh->mapStart = start;
mesh->mapCount = count;
return (VertexData) { .data = mesh->vertices.bytes + start * mesh->format.stride };
void* p = mesh->vertexData->data.bytes + start * mesh->vertexData->format.stride;
return (VertexPointer) { .raw = p };
#else
if (mesh->isMapped) {
lovrMeshUnmap(mesh);
@ -258,12 +248,14 @@ VertexData lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool writ
mesh->isMapped = 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;
access |= (write && start == 0 && count == mesh->vertexCount) ? GL_MAP_INVALIDATE_BUFFER_BIT : 0;
access |= (write && start == 0 && count == mesh->vertexData->count) ? GL_MAP_INVALIDATE_BUFFER_BIT : 0;
lovrGraphicsBindVertexBuffer(mesh->vbo);
return (VertexData) { .data = glMapBufferRange(GL_ARRAY_BUFFER, start * mesh->format.stride, count * mesh->format.stride, access) };
mesh->vertexData->data.raw = glMapBufferRange(GL_ARRAY_BUFFER, start * stride, count * stride, access);
return mesh->vertexData->data;
#endif
}
@ -276,9 +268,10 @@ void lovrMeshUnmap(Mesh* mesh) {
lovrGraphicsBindVertexBuffer(mesh->vbo);
#ifdef EMSCRIPTEN
size_t start = mesh->mapStart * mesh->format.stride;
size_t count = mesh->mapCount * mesh->format.stride;
glBufferSubData(GL_ARRAY_BUFFER, start, count, mesh->vertices.bytes + start);
size_t stride = mesh->vertexData->format.stride;
size_t start = mesh->mapStart * stride;
size_t count = mesh->mapCount * stride;
glBufferSubData(GL_ARRAY_BUFFER, start, count, mesh->vertexData->data.bytes + start);
#else
glUnmapBuffer(GL_ARRAY_BUFFER);
#endif

View File

@ -1,9 +1,9 @@
#include "util.h"
#include "graphics/shader.h"
#include "graphics/material.h"
#include "data/vertexData.h"
#include "math/math.h"
#include "lib/glfw.h"
#include "lib/vertex.h"
#include "util.h"
#pragma once
@ -24,10 +24,8 @@ typedef enum {
typedef struct {
Ref ref;
size_t vertexCount;
VertexFormat format;
VertexData vertices;
IndexData indices;
VertexData* vertexData;
IndexPointer indices;
size_t indexCount;
size_t indexSize;
int enabledAttributes;
@ -47,14 +45,14 @@ typedef struct {
Shader* lastShader;
} Mesh;
Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode, MeshUsage usage);
Mesh* lovrMeshCreate(uint32_t count, VertexFormat* format, MeshDrawMode drawMode, MeshUsage usage);
void lovrMeshDestroy(const Ref* ref);
void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances);
VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh);
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
int lovrMeshGetVertexCount(Mesh* mesh);
IndexData lovrMeshGetVertexMap(Mesh* mesh, size_t* count);
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);
@ -64,5 +62,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);
VertexData lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write);
VertexPointer lovrMeshMap(Mesh* mesh, int start, size_t count, bool read, bool write);
void lovrMeshUnmap(Mesh* mesh);

View File

@ -59,11 +59,11 @@ Model* lovrModelCreate(ModelData* modelData) {
model->animator = NULL;
model->material = NULL;
model->mesh = lovrMeshCreate(modelData->vertexCount, &modelData->format, MESH_TRIANGLES, MESH_STATIC);
VertexData vertices = lovrMeshMap(model->mesh, 0, modelData->vertexCount, false, true);
memcpy(vertices.data, modelData->vertices.data, modelData->vertexCount * modelData->format.stride);
model->mesh = lovrMeshCreate(modelData->vertexData->count, &modelData->vertexData->format, MESH_TRIANGLES, MESH_STATIC);
VertexPointer vertices = lovrMeshMap(model->mesh, 0, modelData->vertexData->count, false, true);
memcpy(vertices.raw, modelData->vertexData->data.raw, modelData->vertexData->count * modelData->vertexData->format.stride);
lovrMeshUnmap(model->mesh);
lovrMeshSetVertexMap(model->mesh, modelData->indices.data, modelData->indexCount);
lovrMeshSetVertexMap(model->mesh, modelData->indices.raw, modelData->indexCount);
lovrMeshSetRangeEnabled(model->mesh, true);
if (modelData->textures.length > 0) {

View File

@ -639,20 +639,15 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
ModelData* modelData = malloc(sizeof(ModelData));
if (!modelData) return NULL;
vertexFormatInit(&modelData->format);
vertexFormatAppend(&modelData->format, "lovrPosition", ATTR_FLOAT, 3);
vertexFormatAppend(&modelData->format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&modelData->format, "lovrTexCoord", ATTR_FLOAT, 2);
VertexFormat format;
vertexFormatInit(&format);
vertexFormatAppend(&format, "lovrPosition", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrTexCoord", ATTR_FLOAT, 2);
modelData->vertexCount = vrModel->unVertexCount;
modelData->vertices.data = malloc(modelData->vertexCount * modelData->format.stride);
modelData->vertexData = lovrVertexDataCreate(vrModel->unVertexCount, &format, true);
modelData->indexCount = vrModel->unTriangleCount * 3;
modelData->indexSize = sizeof(uint16_t);
modelData->indices.data = malloc(modelData->indexCount * modelData->indexSize);
memcpy(modelData->indices.data, vrModel->rIndexData, modelData->indexCount * modelData->indexSize);
float* vertices = modelData->vertices.floats;
float* vertices = modelData->vertexData->data.floats;
int vertex = 0;
for (size_t i = 0; i < vrModel->unVertexCount; i++) {
float* position = vrModel->rVertexData[i].vPosition.v;
@ -671,6 +666,11 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
vertices[vertex++] = texCoords[1];
}
modelData->indexCount = vrModel->unTriangleCount * 3;
modelData->indexSize = sizeof(uint16_t);
modelData->indices.raw = malloc(modelData->indexCount * modelData->indexSize);
memcpy(modelData->indices.raw, vrModel->rIndexData, modelData->indexCount * modelData->indexSize);
modelData->nodeCount = 1;
modelData->primitiveCount = 1;
modelData->animationCount = 0;
@ -681,7 +681,7 @@ static ModelData* openvrControllerNewModelData(Controller* controller) {
modelData->animations = NULL;
modelData->materials = malloc(1 * sizeof(ModelMaterial));
// Geometry
// Nodes
map_init(&modelData->nodeMap);
ModelNode* root = &modelData->nodes[0];
root->parent = -1;

View File

@ -1,15 +0,0 @@
#include "lib/vertex.h"
#include <string.h>
static size_t attributeTypeSizes[3] = { 4, 1, 4 };
void vertexFormatInit(VertexFormat* format) {
memset(format, 0, sizeof(*format));
}
void vertexFormatAppend(VertexFormat* format, const char* name, AttributeType type, int count) {
size_t size = attributeTypeSizes[type];
Attribute attribute = { name, type, count, size, format->stride };
format->attributes[format->count++] = attribute;
format->stride += size * count;
}

View File

@ -2,7 +2,6 @@
#include <lauxlib.h>
#include <lualib.h>
#include "lib/map/map.h"
#include "lib/vertex.h"
#include "util.h"
#pragma once