diff --git a/src/api/types/mesh.c b/src/api/types/mesh.c index 71fe0922..4c0dc9d3 100644 --- a/src/api/types/mesh.c +++ b/src/api/types/mesh.c @@ -299,6 +299,21 @@ int l_lovrMeshSetVertexMap(lua_State* L) { return 0; } +int l_lovrMeshIsAttributeEnabled(lua_State* L) { + Mesh* mesh = luax_checktype(L, 1, Mesh); + const char* attribute = luaL_checkstring(L, 2); + lua_pushboolean(L, lovrMeshIsAttributeEnabled(mesh, attribute)); + return 1; +} + +int l_lovrMeshSetAttributeEnabled(lua_State* L) { + Mesh* mesh = luax_checktype(L, 1, Mesh); + const char* attribute = luaL_checkstring(L, 2); + int enabled = lua_toboolean(L, 3); + lovrMeshSetAttributeEnabled(mesh, attribute, enabled); + return 0; +} + int l_lovrMeshGetDrawRange(lua_State* L) { Mesh* mesh = luax_checktype(L, 1, Mesh); if (!lovrMeshIsRangeEnabled(mesh)) { @@ -361,6 +376,8 @@ const luaL_Reg lovrMesh[] = { { "setVertices", l_lovrMeshSetVertices }, { "getVertexMap", l_lovrMeshGetVertexMap }, { "setVertexMap", l_lovrMeshSetVertexMap }, + { "isAttributeEnabled", l_lovrMeshIsAttributeEnabled }, + { "setAttributeEnabled", l_lovrMeshSetAttributeEnabled }, { "getDrawMode", l_lovrMeshGetDrawMode }, { "setDrawMode", l_lovrMeshSetDrawMode }, { "getDrawRange", l_lovrMeshGetDrawRange }, diff --git a/src/graphics/mesh.c b/src/graphics/mesh.c index 54db28c3..54273442 100644 --- a/src/graphics/mesh.c +++ b/src/graphics/mesh.c @@ -36,6 +36,7 @@ Mesh* lovrMeshCreate(int size, MeshFormat* format, MeshDrawMode drawMode, MeshUs mesh->stride = stride; mesh->data = malloc(mesh->size * mesh->stride); mesh->scratchVertex = malloc(mesh->stride); + mesh->enabledAttributes = ~0; mesh->drawMode = drawMode; mesh->usage = usage; mesh->vao = 0; @@ -96,13 +97,15 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform) { int i; MeshAttribute attribute; vec_foreach(&mesh->format, attribute, i) { - int location = lovrShaderGetAttributeId(shader, attribute.name); - if (location >= 0) { - glEnableVertexAttribArray(location); - if (attribute.type == MESH_INT) { - glVertexAttribIPointer(location, attribute.count, attribute.type, mesh->stride, (void*) offset); - } else { - glVertexAttribPointer(location, attribute.count, attribute.type, GL_FALSE, mesh->stride, (void*) offset); + if (mesh->enabledAttributes & (1 << i)) { + int location = lovrShaderGetAttributeId(shader, attribute.name); + if (location >= 0) { + glEnableVertexAttribArray(location); + if (attribute.type == MESH_INT) { + glVertexAttribIPointer(location, attribute.count, attribute.type, mesh->stride, (void*) offset); + } else { + glVertexAttribPointer(location, attribute.count, attribute.type, GL_FALSE, mesh->stride, (void*) offset); + } } } offset += sizeof(attribute.type) * attribute.count; @@ -196,6 +199,34 @@ void lovrMeshSetVertexMap(Mesh* mesh, unsigned int* map, int count) { } } +int lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) { + int i; + MeshAttribute attribute; + + vec_foreach(&mesh->format, attribute, i) { + if (!strcmp(attribute.name, name)) { + return mesh->enabledAttributes & (1 << i); + } + } + + return 0; +} + +void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, int enable) { + int i; + MeshAttribute attribute; + + vec_foreach(&mesh->format, attribute, i) { + if (!strcmp(attribute.name, name)) { + if (enable) { + mesh->enabledAttributes |= 1 << i; + } else { + mesh->enabledAttributes &= ~(1 << i); + } + } + } +} + int lovrMeshIsRangeEnabled(Mesh* mesh) { return mesh->isRangeEnabled; } diff --git a/src/graphics/mesh.h b/src/graphics/mesh.h index e071ffe3..b20861c3 100644 --- a/src/graphics/mesh.h +++ b/src/graphics/mesh.h @@ -38,6 +38,7 @@ typedef struct { int stride; void* data; void* scratchVertex; + int enabledAttributes; MeshFormat format; MeshDrawMode drawMode; MeshUsage usage; @@ -65,6 +66,8 @@ void lovrMeshSetVertex(Mesh* mesh, int index, void* vertex); void lovrMeshSetVertices(Mesh* mesh, void* vertices, int size); unsigned int* lovrMeshGetVertexMap(Mesh* mesh, int* count); void lovrMeshSetVertexMap(Mesh* mesh, unsigned int* map, int count); +int lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name); +void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, int enabled); int lovrMeshIsRangeEnabled(Mesh* mesh); void lovrMeshSetRangeEnabled(Mesh* mesh, char isEnabled); void lovrMeshGetDrawRange(Mesh* mesh, int* start, int* count);