diff --git a/doc/changelog.dox b/doc/changelog.dox index 54a0affc2b..3a44ef10a6 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -99,6 +99,9 @@ See also: destroyed could fail with an error saying "cannot make the previous context current" on certain system. This was due to EGL not destroying the context if it's still made current. +- For meshes with multiple sets of vertex attributes (such as texture + coordinates), @ref MeshTools::compile() should be using only the first set + but it wasn't. @subsection changelog-latest-compatibility Potential compatibility breakages, removed APIs diff --git a/src/Magnum/MeshTools/Compile.cpp b/src/Magnum/MeshTools/Compile.cpp index d7da902166..5e1e997206 100644 --- a/src/Magnum/MeshTools/Compile.cpp +++ b/src/Magnum/MeshTools/Compile.cpp @@ -66,6 +66,11 @@ GL::Mesh compileInternal(const Trade::MeshData& meshData, GL::Buffer&& indices, /* Vertex data */ GL::Buffer verticesRef = GL::Buffer::wrap(vertices.id(), GL::Buffer::TargetHint::Array); + + /* Ensure each known attribute gets bound only once. There's 16 generic + attribs at most. */ + Math::BoolVector<16> boundAttributes; + for(UnsignedInt i = 0; i != meshData.attributeCount(); ++i) { Containers::Optional attribute; @@ -131,6 +136,14 @@ GL::Mesh compileInternal(const Trade::MeshData& meshData, GL::Buffer&& indices, continue; } + /* Ensure each attribute gets bound only once -- so for example when + there are two texture coordinate sets, we don't bind them both to + the same slot, effectively ignoring the first one */ + /** @todo revisit when there are secondary generic texture coordinates */ + if(boundAttributes[attribute->location()]) + continue; + boundAttributes.set(attribute->location(), true); + /* For the first attribute move the buffer in, for all others use the reference */ if(vertices.id()) mesh.addVertexBuffer(std::move(vertices),