Refactor MeshFormat;

This commit is contained in:
bjorn 2018-01-25 18:31:56 -08:00
parent 031663c096
commit ea7f3d48a2
8 changed files with 133 additions and 178 deletions

View File

@ -60,6 +60,8 @@ extern const luaL_Reg lovrTransform[];
extern const luaL_Reg lovrWorld[]; extern const luaL_Reg lovrWorld[];
// Enums // Enums
extern map_int_t ArcModes;
extern map_int_t AttributeTypes;
extern map_int_t BlendAlphaModes; extern map_int_t BlendAlphaModes;
extern map_int_t BlendModes; extern map_int_t BlendModes;
extern map_int_t CanvasTypes; extern map_int_t CanvasTypes;
@ -78,7 +80,6 @@ extern map_int_t JointTypes;
extern map_int_t MaterialColors; extern map_int_t MaterialColors;
extern map_int_t MaterialTextures; extern map_int_t MaterialTextures;
extern map_int_t MatrixTypes; extern map_int_t MatrixTypes;
extern map_int_t MeshAttributeTypes;
extern map_int_t MeshDrawModes; extern map_int_t MeshDrawModes;
extern map_int_t MeshUsages; extern map_int_t MeshUsages;
extern map_int_t PolygonWindings; extern map_int_t PolygonWindings;
@ -89,7 +90,6 @@ extern map_int_t VerticalAligns;
extern map_int_t WrapModes; extern map_int_t WrapModes;
// Shared helpers // Shared helpers
void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format);
int luax_readtransform(lua_State* L, int index, mat4 transform, bool uniformScale); int luax_readtransform(lua_State* L, int index, mat4 transform, bool uniformScale);
Blob* luax_readblob(lua_State* L, int index, const char* debug); Blob* luax_readblob(lua_State* L, int index, const char* debug);
int luax_pushshape(lua_State* L, Shape* shape); int luax_pushshape(lua_State* L, Shape* shape);

View File

@ -10,10 +10,12 @@
#include "data/rasterizer.h" #include "data/rasterizer.h"
#include "data/texture.h" #include "data/texture.h"
#include "filesystem/filesystem.h" #include "filesystem/filesystem.h"
#include "lib/vertex.h"
#include <math.h> #include <math.h>
#include <stdbool.h> #include <stdbool.h>
map_int_t ArcModes; map_int_t ArcModes;
map_int_t AttributeTypes;
map_int_t BlendAlphaModes; map_int_t BlendAlphaModes;
map_int_t BlendModes; map_int_t BlendModes;
map_int_t CanvasTypes; map_int_t CanvasTypes;
@ -24,7 +26,6 @@ map_int_t HorizontalAligns;
map_int_t MaterialColors; map_int_t MaterialColors;
map_int_t MaterialTextures; map_int_t MaterialTextures;
map_int_t MatrixTypes; map_int_t MatrixTypes;
map_int_t MeshAttributeTypes;
map_int_t MeshDrawModes; map_int_t MeshDrawModes;
map_int_t MeshUsages; map_int_t MeshUsages;
map_int_t StencilActions; map_int_t StencilActions;
@ -79,6 +80,33 @@ static void stencilCallback(void* userdata) {
lua_call(L, 0, 0); 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);
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);
Attribute attribute = { .name = name, .type = *type, .count = count };
vec_push(format, attribute);
lua_pop(L, 4);
}
}
static TextureData* luax_checktexturedata(lua_State* L, int index) { static TextureData* luax_checktexturedata(lua_State* L, int index) {
void** type; void** type;
if ((type = luax_totype(L, index, TextureData)) != NULL) { if ((type = luax_totype(L, index, TextureData)) != NULL) {
@ -110,6 +138,11 @@ int l_lovrGraphicsInit(lua_State* L) {
map_set(&ArcModes, "open", ARC_MODE_OPEN); map_set(&ArcModes, "open", ARC_MODE_OPEN);
map_set(&ArcModes, "closed", ARC_MODE_CLOSED); map_set(&ArcModes, "closed", ARC_MODE_CLOSED);
map_init(&AttributeTypes);
map_set(&AttributeTypes, "float", ATTR_FLOAT);
map_set(&AttributeTypes, "byte", ATTR_BYTE);
map_set(&AttributeTypes, "int", ATTR_INT);
map_init(&BlendAlphaModes); map_init(&BlendAlphaModes);
map_set(&BlendAlphaModes, "alphamultiply", BLEND_ALPHA_MULTIPLY); map_set(&BlendAlphaModes, "alphamultiply", BLEND_ALPHA_MULTIPLY);
map_set(&BlendAlphaModes, "premultiplied", BLEND_PREMULTIPLIED); map_set(&BlendAlphaModes, "premultiplied", BLEND_PREMULTIPLIED);
@ -162,11 +195,6 @@ int l_lovrGraphicsInit(lua_State* L) {
map_set(&MatrixTypes, "model", MATRIX_MODEL); map_set(&MatrixTypes, "model", MATRIX_MODEL);
map_set(&MatrixTypes, "view", MATRIX_VIEW); map_set(&MatrixTypes, "view", MATRIX_VIEW);
map_init(&MeshAttributeTypes);
map_set(&MeshAttributeTypes, "float", MESH_FLOAT);
map_set(&MeshAttributeTypes, "byte", MESH_BYTE);
map_set(&MeshAttributeTypes, "int", MESH_INT);
map_init(&MeshDrawModes); map_init(&MeshDrawModes);
map_set(&MeshDrawModes, "points", MESH_POINTS); map_set(&MeshDrawModes, "points", MESH_POINTS);
map_set(&MeshDrawModes, "lines", MESH_LINES); map_set(&MeshDrawModes, "lines", MESH_LINES);
@ -880,7 +908,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
int size; int size;
int dataIndex = 0; int dataIndex = 0;
int drawModeIndex = 2; int drawModeIndex = 2;
MeshFormat format; VertexFormat format;
vec_init(&format); vec_init(&format);
if (lua_isnumber(L, 1)) { if (lua_isnumber(L, 1)) {
@ -888,12 +916,12 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
} else if (lua_istable(L, 1)) { } else if (lua_istable(L, 1)) {
if (lua_isnumber(L, 2)) { if (lua_isnumber(L, 2)) {
drawModeIndex++; drawModeIndex++;
luax_checkmeshformat(L, 1, &format); luax_checkvertexformat(L, 1, &format);
size = lua_tointeger(L, 2); size = lua_tointeger(L, 2);
dataIndex = 0; dataIndex = 0;
} else if (lua_istable(L, 2)) { } else if (lua_istable(L, 2)) {
drawModeIndex++; drawModeIndex++;
luax_checkmeshformat(L, 1, &format); luax_checkvertexformat(L, 1, &format);
size = lua_objlen(L, 2); size = lua_objlen(L, 2);
dataIndex = 2; dataIndex = 2;
} else { } else {
@ -911,7 +939,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
if (dataIndex) { if (dataIndex) {
int count = lua_objlen(L, dataIndex); int count = lua_objlen(L, dataIndex);
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
char* vertex = lovrMeshMap(mesh, 0, count, false, true); char* vertex = lovrMeshMap(mesh, 0, count, false, true);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
@ -922,25 +950,15 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
int component = 0; int component = 0;
for (int j = 0; j < format.length; j++) { for (int j = 0; j < format.length; j++) {
MeshAttribute attribute = format.data[j]; Attribute attribute = format.data[j];
for (int k = 0; k < attribute.count; k++) { for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component); lua_rawgeti(L, -1, ++component);
switch (attribute.type) { switch (attribute.type) {
case MESH_FLOAT: case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break;
*((float*) vertex) = luaL_optnumber(L, -1, 0.f); case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break;
vertex += sizeof(float); case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break;
break;
case MESH_BYTE:
*((uint8_t*) vertex) = luaL_optint(L, -1, 255);
vertex += sizeof(uint8_t);
break;
case MESH_INT:
*((int*) vertex) = luaL_optint(L, -1, 0);
vertex += sizeof(int);
break;
} }
vertex += AttributeSizes[attribute.type];
lua_pop(L, 1); lua_pop(L, 1);
} }
} }

View File

@ -1,32 +1,5 @@
#include "api.h" #include "api.h"
void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format) {
if (!lua_istable(L, index)) {
return;
}
int length = lua_objlen(L, index);
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);
MeshAttributeType* type = (MeshAttributeType*) luax_checkenum(L, -2, &MeshAttributeTypes, "mesh attribute type");
int count = lua_tointeger(L, -1);
MeshAttribute attribute = { .name = name, .type = *type, .count = count };
vec_push(format, attribute);
lua_pop(L, 4);
}
}
int l_lovrMeshDrawInstanced(lua_State* L) { int l_lovrMeshDrawInstanced(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
int instances = luaL_checkinteger(L, 2); int instances = luaL_checkinteger(L, 2);
@ -44,10 +17,10 @@ int l_lovrMeshDraw(lua_State* L) {
int l_lovrMeshGetVertexFormat(lua_State* L) { int l_lovrMeshGetVertexFormat(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
lua_newtable(L); lua_newtable(L);
for (int i = 0; i < format.length; i++) { for (int i = 0; i < format.length; i++) {
MeshAttribute attribute = format.data[i]; Attribute attribute = format.data[i];
lua_newtable(L); lua_newtable(L);
// Name // Name
@ -55,7 +28,7 @@ int l_lovrMeshGetVertexFormat(lua_State* L) {
lua_rawseti(L, -2, 1); lua_rawseti(L, -2, 1);
// Type // Type
luax_pushenum(L, &MeshAttributeTypes, attribute.type); luax_pushenum(L, &AttributeTypes, attribute.type);
lua_rawseti(L, -2, 2); lua_rawseti(L, -2, 2);
// Count // Count
@ -90,29 +63,19 @@ int l_lovrMeshGetVertex(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
int index = luaL_checkint(L, 2) - 1; int index = luaL_checkint(L, 2) - 1;
char* vertex = lovrMeshMap(mesh, index, 1, true, false); char* vertex = lovrMeshMap(mesh, index, 1, true, false);
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
int total = 0; int total = 0;
for (int i = 0; i < format.length; i++) { for (int i = 0; i < format.length; i++) {
MeshAttribute attribute = format.data[i]; Attribute attribute = format.data[i];
total += attribute.count; total += attribute.count;
for (int j = 0; j < attribute.count; j++) { for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) { switch (attribute.type) {
case MESH_FLOAT: case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break;
lua_pushnumber(L, *((float*) vertex)); case ATTR_BYTE: lua_pushnumber(L, *((uint8_t*) vertex)); break;
vertex += sizeof(float); case ATTR_INT: lua_pushnumber(L, *((int*) vertex)); break;
break;
case MESH_BYTE:
lua_pushnumber(L, *((uint8_t*) vertex));
vertex += sizeof(uint8_t);
break;
case MESH_INT:
lua_pushnumber(L, *((int*) vertex));
vertex += sizeof(int);
break;
} }
vertex += AttributeSizes[attribute.type];
} }
} }
@ -127,7 +90,7 @@ int l_lovrMeshSetVertex(lua_State* L) {
return luaL_error(L, "Invalid mesh vertex index: %d", index + 1); return luaL_error(L, "Invalid mesh vertex index: %d", index + 1);
} }
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
char* vertex = lovrMeshMap(mesh, index, 1, false, true); char* vertex = lovrMeshMap(mesh, index, 1, false, true);
// Unwrap table // Unwrap table
@ -140,24 +103,14 @@ int l_lovrMeshSetVertex(lua_State* L) {
} }
for (int i = 0; i < format.length; i++) { for (int i = 0; i < format.length; i++) {
MeshAttribute attribute = format.data[i]; Attribute attribute = format.data[i];
for (int j = 0; j < attribute.count; j++) { for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) { switch (attribute.type) {
case MESH_FLOAT: case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break;
*((float*) vertex) = luaL_optnumber(L, arg++, 0.f); case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, arg++, 255); break;
vertex += sizeof(float); case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break;
break;
case MESH_BYTE:
*((uint8_t*) vertex) = luaL_optint(L, arg++, 255);
vertex += sizeof(uint8_t);
break;
case MESH_INT:
*((int*) vertex) = luaL_optint(L, arg++, 0);
vertex += sizeof(int);
break;
} }
vertex += AttributeSizes[attribute.type];
} }
} }
@ -168,7 +121,7 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
int vertexIndex = luaL_checkint(L, 2) - 1; int vertexIndex = luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1; int attributeIndex = luaL_checkint(L, 3) - 1;
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) { if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1); return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1);
@ -178,24 +131,19 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
char* vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false); char* vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false);
MeshAttribute attribute; Attribute attribute;
for (int i = 0; i <= attributeIndex; i++) { for (int i = 0; i <= attributeIndex; i++) {
attribute = format.data[i]; attribute = format.data[i];
if (i == attributeIndex) { if (i == attributeIndex) {
for (int j = 0; j < attribute.count; j++) { for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) { switch (attribute.type) {
case MESH_FLOAT: lua_pushnumber(L, *((float*) vertex)); break; case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break;
case MESH_BYTE: lua_pushinteger(L, *((uint8_t*) vertex)); break; case ATTR_BYTE: lua_pushinteger(L, *((uint8_t*) vertex)); break;
case MESH_INT: lua_pushinteger(L, *((int*) vertex)); break; case ATTR_INT: lua_pushinteger(L, *((int*) vertex)); break;
} }
} }
} }
vertex += attribute.count * AttributeSizes[attribute.type];
switch (attribute.type) {
case MESH_FLOAT: vertex += attribute.count * sizeof(float); break;
case MESH_BYTE: vertex += attribute.count * sizeof(uint8_t); break;
case MESH_INT: vertex += attribute.count * sizeof(int); break;
}
} }
return attribute.count; return attribute.count;
@ -205,7 +153,7 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
int vertexIndex = luaL_checkint(L, 2) - 1; int vertexIndex = luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1; int attributeIndex = luaL_checkint(L, 3) - 1;
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) { if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1); return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1);
@ -217,22 +165,17 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
int arg = 4; int arg = 4;
for (int i = 0; i <= attributeIndex; i++) { for (int i = 0; i <= attributeIndex; i++) {
MeshAttribute attribute = format.data[i]; Attribute attribute = format.data[i];
if (i == attributeIndex) { if (i == attributeIndex) {
for (int j = 0; j < attribute.count; j++) { for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) { switch (attribute.type) {
case MESH_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break; case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break;
case MESH_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break; case ATTR_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break;
case MESH_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break; case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break;
} }
} }
} }
vertex += attribute.count * AttributeSizes[attribute.type];
switch (attribute.type) {
case MESH_FLOAT: vertex += attribute.count * sizeof(float); break;
case MESH_BYTE: vertex += attribute.count * sizeof(uint8_t); break;
case MESH_INT: vertex += attribute.count * sizeof(int); break;
}
} }
return 0; return 0;
@ -240,7 +183,7 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
int l_lovrMeshSetVertices(lua_State* L) { int l_lovrMeshSetVertices(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh); Mesh* mesh = luax_checktype(L, 1, Mesh);
MeshFormat format = lovrMeshGetVertexFormat(mesh); VertexFormat format = lovrMeshGetVertexFormat(mesh);
luaL_checktype(L, 2, LUA_TTABLE); luaL_checktype(L, 2, LUA_TTABLE);
int vertexCount = lua_objlen(L, 2); int vertexCount = lua_objlen(L, 2);
int start = luaL_optnumber(L, 3, 1) - 1; int start = luaL_optnumber(L, 3, 1) - 1;
@ -257,25 +200,15 @@ int l_lovrMeshSetVertices(lua_State* L) {
lua_rawgeti(L, 2, i + 1); lua_rawgeti(L, 2, i + 1);
int component = 0; int component = 0;
for (int j = 0; j < format.length; j++) { for (int j = 0; j < format.length; j++) {
MeshAttribute attribute = format.data[j]; Attribute attribute = format.data[j];
for (int k = 0; k < attribute.count; k++) { for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component); lua_rawgeti(L, -1, ++component);
switch (attribute.type) { switch (attribute.type) {
case MESH_FLOAT: case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break;
*((float*) vertex) = luaL_optnumber(L, -1, 0.f); case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break;
vertex += sizeof(float); case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break;
break;
case MESH_BYTE:
*((uint8_t*) vertex) = luaL_optint(L, -1, 255);
vertex += sizeof(uint8_t);
break;
case MESH_INT:
*((int*) vertex) = luaL_optint(L, -1, 0);
vertex += sizeof(int);
break;
} }
vertex += AttributeSizes[attribute.type];
lua_pop(L, 1); lua_pop(L, 1);
} }
} }

View File

@ -4,18 +4,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
static size_t getAttributeTypeSize(MeshAttributeType type) {
switch (type) {
case MESH_FLOAT:
case MESH_INT:
return 4;
case MESH_BYTE:
return 1;
default:
return 0;
}
}
static void lovrMeshBindAttributes(Mesh* mesh) { static void lovrMeshBindAttributes(Mesh* mesh) {
Shader* shader = lovrGraphicsGetActiveShader(); Shader* shader = lovrGraphicsGetActiveShader();
if (shader == mesh->lastShader && !mesh->attributesDirty) { if (shader == mesh->lastShader && !mesh->attributesDirty) {
@ -26,7 +14,7 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
size_t offset = 0; size_t offset = 0;
int i; int i;
MeshAttribute attribute; Attribute attribute;
vec_foreach(&mesh->format, attribute, i) { vec_foreach(&mesh->format, attribute, i) {
int location = lovrShaderGetAttributeId(shader, attribute.name); int location = lovrShaderGetAttributeId(shader, attribute.name);
@ -34,25 +22,26 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
if (location >= 0) { if (location >= 0) {
if (mesh->enabledAttributes & (1 << i)) { if (mesh->enabledAttributes & (1 << i)) {
glEnableVertexAttribArray(location); glEnableVertexAttribArray(location);
GLenum attributeType = AttributeConstants[attribute.type];
if (attribute.type == MESH_INT) { if (attribute.type == ATTR_INT) {
glVertexAttribIPointer(location, attribute.count, attribute.type, mesh->stride, (void*) offset); glVertexAttribIPointer(location, attribute.count, attributeType, mesh->stride, (void*) offset);
} else { } else {
glVertexAttribPointer(location, attribute.count, attribute.type, GL_TRUE, mesh->stride, (void*) offset); glVertexAttribPointer(location, attribute.count, attributeType, GL_TRUE, mesh->stride, (void*) offset);
} }
} else { } else {
glDisableVertexAttribArray(location); glDisableVertexAttribArray(location);
} }
} }
offset += getAttributeTypeSize(attribute.type) * attribute.count; offset += AttributeSizes[attribute.type] * attribute.count;
} }
mesh->lastShader = shader; mesh->lastShader = shader;
mesh->attributesDirty = false; mesh->attributesDirty = false;
} }
Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, MeshUsage usage) { Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode, MeshUsage usage) {
Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy); Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy);
if (!mesh) return NULL; if (!mesh) return NULL;
@ -61,10 +50,10 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
if (format) { if (format) {
vec_extend(&mesh->format, format); vec_extend(&mesh->format, format);
} else { } else {
MeshAttribute position = { .name = "lovrPosition", .type = MESH_FLOAT, .count = 3 }; Attribute position = { .name = "lovrPosition", .type = ATTR_FLOAT, .count = 3 };
MeshAttribute normal = { .name = "lovrNormal", .type = MESH_FLOAT, .count = 3 }; Attribute normal = { .name = "lovrNormal", .type = ATTR_FLOAT, .count = 3 };
MeshAttribute texCoord = { .name = "lovrTexCoord", .type = MESH_FLOAT, .count = 2 }; Attribute texCoord = { .name = "lovrTexCoord", .type = ATTR_FLOAT, .count = 2 };
MeshAttribute vertexColor = { .name = "lovrVertexColor", .type = MESH_BYTE, .count = 4 }; Attribute vertexColor = { .name = "lovrVertexColor", .type = ATTR_BYTE, .count = 4 };
vec_push(&mesh->format, position); vec_push(&mesh->format, position);
vec_push(&mesh->format, normal); vec_push(&mesh->format, normal);
vec_push(&mesh->format, texCoord); vec_push(&mesh->format, texCoord);
@ -73,9 +62,9 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
int stride = 0; int stride = 0;
int i; int i;
MeshAttribute attribute; Attribute attribute;
vec_foreach(&mesh->format, attribute, i) { vec_foreach(&mesh->format, attribute, i) {
stride += attribute.count * getAttributeTypeSize(attribute.type); stride += attribute.count * AttributeSizes[attribute.type];
} }
if (stride == 0) { if (stride == 0) {
@ -160,7 +149,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
} }
} }
MeshFormat lovrMeshGetVertexFormat(Mesh* mesh) { VertexFormat lovrMeshGetVertexFormat(Mesh* mesh) {
return mesh->format; return mesh->format;
} }
@ -207,7 +196,7 @@ void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count) {
bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) { bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
int i; int i;
MeshAttribute attribute; Attribute attribute;
vec_foreach(&mesh->format, attribute, i) { vec_foreach(&mesh->format, attribute, i) {
if (!strcmp(attribute.name, name)) { if (!strcmp(attribute.name, name)) {
@ -220,7 +209,7 @@ bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enable) { void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enable) {
int i; int i;
MeshAttribute attribute; Attribute attribute;
vec_foreach(&mesh->format, attribute, i) { vec_foreach(&mesh->format, attribute, i) {
if (!strcmp(attribute.name, name)) { if (!strcmp(attribute.name, name)) {

View File

@ -3,6 +3,7 @@
#include "graphics/material.h" #include "graphics/material.h"
#include "math/math.h" #include "math/math.h"
#include "lib/glfw.h" #include "lib/glfw.h"
#include "lib/vertex.h"
#pragma once #pragma once
@ -21,20 +22,6 @@ typedef enum {
MESH_STREAM = GL_STREAM_DRAW MESH_STREAM = GL_STREAM_DRAW
} MeshUsage; } MeshUsage;
typedef enum {
MESH_FLOAT = GL_FLOAT,
MESH_BYTE = GL_UNSIGNED_BYTE,
MESH_INT = GL_INT
} MeshAttributeType;
typedef struct {
const char* name;
MeshAttributeType type;
int count;
} MeshAttribute;
typedef vec_t(MeshAttribute) MeshFormat;
typedef struct { typedef struct {
Ref ref; Ref ref;
void* data; void* data;
@ -45,7 +32,7 @@ typedef struct {
bool isMapped; bool isMapped;
int mapStart; int mapStart;
size_t mapCount; size_t mapCount;
MeshFormat format; VertexFormat format;
MeshDrawMode drawMode; MeshDrawMode drawMode;
MeshUsage usage; MeshUsage usage;
GLuint vao; GLuint vao;
@ -61,10 +48,10 @@ typedef struct {
Shader* lastShader; Shader* lastShader;
} Mesh; } Mesh;
Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, MeshUsage usage); Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode, MeshUsage usage);
void lovrMeshDestroy(const Ref* ref); void lovrMeshDestroy(const Ref* ref);
void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances); void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances);
MeshFormat lovrMeshGetVertexFormat(Mesh* mesh); VertexFormat lovrMeshGetVertexFormat(Mesh* mesh);
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh); MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode); void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
int lovrMeshGetVertexCount(Mesh* mesh); int lovrMeshGetVertexCount(Mesh* mesh);

View File

@ -59,32 +59,32 @@ Model* lovrModelCreate(ModelData* modelData) {
model->animator = NULL; model->animator = NULL;
model->material = NULL; model->material = NULL;
MeshFormat format; VertexFormat format;
vec_init(&format); vec_init(&format);
MeshAttribute attribute = { .name = "lovrPosition", .type = MESH_FLOAT, .count = 3 }; Attribute attribute = { .name = "lovrPosition", .type = ATTR_FLOAT, .count = 3 };
vec_push(&format, attribute); vec_push(&format, attribute);
if (modelData->hasNormals) { if (modelData->hasNormals) {
MeshAttribute attribute = { .name = "lovrNormal", .type = MESH_FLOAT, .count = 3 }; Attribute attribute = { .name = "lovrNormal", .type = ATTR_FLOAT, .count = 3 };
vec_push(&format, attribute); vec_push(&format, attribute);
} }
if (modelData->hasUVs) { if (modelData->hasUVs) {
MeshAttribute attribute = { .name = "lovrTexCoord", .type = MESH_FLOAT, .count = 2 }; Attribute attribute = { .name = "lovrTexCoord", .type = ATTR_FLOAT, .count = 2 };
vec_push(&format, attribute); vec_push(&format, attribute);
} }
if (modelData->hasVertexColors) { if (modelData->hasVertexColors) {
MeshAttribute attribute = { .name = "lovrVertexColor", .type = MESH_BYTE, .count = 4 }; Attribute attribute = { .name = "lovrVertexColor", .type = ATTR_BYTE, .count = 4 };
vec_push(&format, attribute); vec_push(&format, attribute);
} }
if (modelData->skinned) { if (modelData->skinned) {
MeshAttribute bones = { .name = "lovrBones", .type = MESH_INT, .count = 4 }; Attribute bones = { .name = "lovrBones", .type = ATTR_INT, .count = 4 };
vec_push(&format, bones); vec_push(&format, bones);
MeshAttribute weights = { .name = "lovrBoneWeights", .type = MESH_FLOAT, .count = 4 }; Attribute weights = { .name = "lovrBoneWeights", .type = ATTR_FLOAT, .count = 4 };
vec_push(&format, weights); vec_push(&format, weights);
} }

4
src/lib/vertex.c Normal file
View File

@ -0,0 +1,4 @@
#include "lib/vertex.h"
size_t AttributeSizes[] = { sizeof(float), sizeof(uint8_t), sizeof(int) };
GLenum AttributeConstants[] = { GL_FLOAT, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT };

24
src/lib/vertex.h Normal file
View File

@ -0,0 +1,24 @@
#include <stdlib.h>
#include "lib/glfw.h"
#include "lib/vec/vec.h"
#pragma once
#define ATTRIBUTE_COUNT 3
size_t AttributeSizes[ATTRIBUTE_COUNT];
GLenum AttributeConstants[ATTRIBUTE_COUNT];
typedef enum {
ATTR_FLOAT,
ATTR_BYTE,
ATTR_INT
} AttributeType;
typedef struct {
const char* name;
AttributeType type;
int count;
} Attribute;
typedef vec_t(Attribute) VertexFormat;