diff --git a/src/lovr/types/buffer.c b/src/lovr/types/buffer.c index 4a6631bf..a248e8a6 100644 --- a/src/lovr/types/buffer.c +++ b/src/lovr/types/buffer.c @@ -34,6 +34,8 @@ const luaL_Reg lovrBuffer[] = { { "getVertexCount", l_lovrBufferGetVertexCount }, { "getVertex", l_lovrBufferGetVertex }, { "setVertex", l_lovrBufferSetVertex }, + { "getVertexAttribute", l_lovrBufferGetVertexAttribute }, + { "setVertexAttribute", l_lovrBufferSetVertexAttribute }, { "setVertices", l_lovrBufferSetVertices }, { "getVertexMap", l_lovrBufferGetVertexMap }, { "setVertexMap", l_lovrBufferSetVertexMap }, @@ -132,6 +134,75 @@ int l_lovrBufferSetVertex(lua_State* L) { return 0; } +int l_lovrBufferGetVertexAttribute(lua_State* L) { + Buffer* buffer = luax_checktype(L, 1, Buffer); + int vertexIndex = luaL_checkint(L, 2) - 1; + int attributeIndex = luaL_checkint(L, 3) - 1; + char* vertex = lovrBufferGetScratchVertex(buffer); + lovrBufferGetVertex(buffer, vertexIndex, vertex); + BufferFormat format = lovrBufferGetVertexFormat(buffer); + + if (vertexIndex < 0 || vertexIndex >= buffer->size) { + return luaL_error(L, "Invalid buffer vertex index: %d", vertexIndex + 1); + } else if (attributeIndex < 0 || attributeIndex >= format.length) { + return luaL_error(L, "Invalid buffer attribute index: %d", attributeIndex + 1); + } + + BufferAttribute attribute; + for (int i = 0; i <= attributeIndex; i++) { + attribute = format.data[i]; + if (i == attributeIndex) { + for (int j = 0; j < attribute.count; j++) { + switch (attribute.type) { + case BUFFER_FLOAT: lua_pushnumber(L, *((float*) vertex)); break; + case BUFFER_BYTE: lua_pushinteger(L, *((unsigned char*) vertex)); break; + case BUFFER_INT: lua_pushinteger(L, *((int*) vertex)); break; + } + vertex += sizeof(attribute.type); + } + } else { + vertex += attribute.count * sizeof(attribute.type); + } + } + + return attribute.count; +} + +int l_lovrBufferSetVertexAttribute(lua_State* L) { + Buffer* buffer = luax_checktype(L, 1, Buffer); + int vertexIndex = luaL_checkint(L, 2) - 1; + int attributeIndex = luaL_checkint(L, 3) - 1; + char* vertex = lovrBufferGetScratchVertex(buffer); + lovrBufferGetVertex(buffer, vertexIndex, vertex); + BufferFormat format = lovrBufferGetVertexFormat(buffer); + + if (vertexIndex < 0 || vertexIndex >= buffer->size) { + return luaL_error(L, "Invalid buffer vertex index: %d", vertexIndex + 1); + } else if (attributeIndex < 0 || attributeIndex >= format.length) { + return luaL_error(L, "Invalid buffer attribute index: %d", attributeIndex + 1); + } + + int arg = 4; + for (int i = 0; i <= attributeIndex; i++) { + BufferAttribute attribute = format.data[i]; + if (i == attributeIndex) { + for (int j = 0; j < attribute.count; j++) { + switch (attribute.type) { + case BUFFER_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break; + case BUFFER_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break; + case BUFFER_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break; + } + vertex += sizeof(attribute.type); + } + } else { + vertex += attribute.count * sizeof(attribute.type); + } + } + + lovrBufferSetVertex(buffer, vertexIndex, lovrBufferGetScratchVertex(buffer)); + return 0; +} + int l_lovrBufferSetVertices(lua_State* L) { Buffer* buffer = luax_checktype(L, 1, Buffer); BufferFormat format = lovrBufferGetVertexFormat(buffer); diff --git a/src/lovr/types/buffer.h b/src/lovr/types/buffer.h index 04c9be3e..fcab7375 100644 --- a/src/lovr/types/buffer.h +++ b/src/lovr/types/buffer.h @@ -10,6 +10,8 @@ int l_lovrBufferDraw(lua_State* L); int l_lovrBufferGetVertexCount(lua_State* L); int l_lovrBufferGetVertex(lua_State* L); int l_lovrBufferSetVertex(lua_State* L); +int l_lovrBufferGetVertexAttribute(lua_State* L); +int l_lovrBufferSetVertexAttribute(lua_State* L); int l_lovrBufferSetVertices(lua_State* L); int l_lovrBufferGetVertexMap(lua_State* L); int l_lovrBufferSetVertexMap(lua_State* L);