diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index a248c11c9..8e37e63e1 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -360,11 +360,10 @@ void *Mesh::mapVertexData() return vbo->map(); } -void Mesh::unmapVertexData() +void Mesh::unmapVertexData(size_t modifiedoffset, size_t modifiedsize) { - // Assume the whole buffer was modified. GLBuffer::Bind bind(*vbo); - vbo->setMappedRangeModified(0, vbo->getSize()); + vbo->setMappedRangeModified(modifiedoffset, modifiedsize); vbo->unmap(); } diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h index 95c334821..4c7897fe7 100644 --- a/src/modules/graphics/opengl/Mesh.h +++ b/src/modules/graphics/opengl/Mesh.h @@ -141,7 +141,7 @@ public: void attachAttribute(const std::string &name, Mesh *mesh); void *mapVertexData(); - void unmapVertexData(); + void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1); /** * Flushes all modified data to the GPU. diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index 49e5ecdaf..b008b4078 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -109,10 +109,15 @@ int w_Mesh_setVertices(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); luaL_checktype(L, 2, LUA_TTABLE); + size_t vertoffset = (size_t) luaL_optnumber(L, 3, 1) - 1; + + if (vertoffset >= t->getVertexCount()) + return luaL_error(L, "Invalid vertex start index (must be between 1 and %d)", (int) t->getVertexCount()); size_t nvertices = luax_objlen(L, 2); - if (nvertices != t->getVertexCount()) - return luaL_error(L, "Invalid number of vertices (expected %d, got %d)", (int) t->getVertexCount(), (int) nvertices); + + if (vertoffset + nvertices > t->getVertexCount()) + return luaL_error(L, "Too many vertices (expected at most %d, got %d)", (int) t->getVertexCount() - (int) vertoffset, (int) nvertices); const std::vector &vertexformat = t->getVertexFormat(); @@ -120,7 +125,10 @@ int w_Mesh_setVertices(lua_State *L) for (const Mesh::AttribFormat &format : vertexformat) ncomponents += format.components; - char *data = (char *) t->mapVertexData(); + size_t stride = t->getVertexStride(); + size_t byteoffset = vertoffset * stride; + + char *data = (char *) t->mapVertexData() + byteoffset; for (size_t i = 0; i < nvertices; i++) { @@ -145,7 +153,7 @@ int w_Mesh_setVertices(lua_State *L) lua_pop(L, ncomponents + 1); } - t->unmapVertexData(); + t->unmapVertexData(byteoffset, nvertices * stride); return 0; }