diff --git a/src/Magnum/MeshTools/Compile.cpp b/src/Magnum/MeshTools/Compile.cpp index 2603c4200..5a8d4ae4e 100644 --- a/src/Magnum/MeshTools/Compile.cpp +++ b/src/Magnum/MeshTools/Compile.cpp @@ -160,7 +160,9 @@ GL::Mesh compileInternal(const Trade::MeshData& meshData, GL::Buffer&& indices, } if(meshData.isIndexed()) { - CORRADE_ASSERT(Short(meshIndexTypeSize(meshData.indexType())) == meshData.indexStride(), + /* If the type is implementation-specific, we have no way to know if + it's strided, so just assume it is */ + CORRADE_ASSERT(isMeshIndexTypeImplementationSpecific(meshData.indexType()) || Short(meshIndexTypeSize(meshData.indexType())) == meshData.indexStride(), "MeshTools::compile():" << meshData.indexType() << "with stride of" << meshData.indexStride() << "bytes isn't supported by OpenGL", GL::Mesh{}); mesh.setIndexBuffer(std::move(indices), meshData.indexOffset(), meshData.indexType()) diff --git a/src/Magnum/MeshTools/Compile.h b/src/Magnum/MeshTools/Compile.h index 0b694c23f..355c006c6 100644 --- a/src/Magnum/MeshTools/Compile.h +++ b/src/Magnum/MeshTools/Compile.h @@ -117,12 +117,15 @@ possibly also an index buffer, if the mesh is indexed. @ref compile(const Trade::MeshData&, GL::Buffer&, GL::Buffer&) for an example showing how to bind them manually, and @ref CompileFlag::NoWarnOnCustomAttributes to suppress the warning. -- Implementation-specific @ref Magnum::MeshPrimitive values are passed - as-is with @ref meshPrimitiveUnwrap(). It's the user responsibility to - ensure an implementation-specific value is valid in this context. +- Implementation-specific @ref Magnum::MeshPrimitive and + @ref Magnum::MeshIndexType values are passed as-is with + @ref meshPrimitiveUnwrap() and @ref meshIndexTypeUnwrap(). It's the user + responsibility to ensure an implementation-specific value is valid in this + context. - The index buffer is expected to be contiguous (size of the index type equal to @ref Trade::MeshData::indexStride()). OpenGL doesn't support interleaved - index buffers. + index buffers. In case the @ref MeshIndexType is implementation-specific, + this condition can't be checked and the buffer is assumed to be contiguous. - Stride of all attributes is expected to be positive. OpenGL doesn't support zero and negative strides. diff --git a/src/Magnum/MeshTools/Test/CompileGLTest.cpp b/src/Magnum/MeshTools/Test/CompileGLTest.cpp index 0ede0d7a7..4bc1225dd 100644 --- a/src/Magnum/MeshTools/Test/CompileGLTest.cpp +++ b/src/Magnum/MeshTools/Test/CompileGLTest.cpp @@ -147,49 +147,55 @@ struct CompileGLTest: GL::OpenGLTester { GL::Texture2D _texture; }; -constexpr struct { +const struct { const char* name; Flags flags; + Containers::Optional indexType; } Data2D[] { - {"positions", {}}, - {"positions, nonindexed", Flag::NonIndexed}, - {"positions + colors", Flag::Colors}, - {"positions + texture coordinates", Flag::TextureCoordinates2D}, - {"positions + texture coordinates + colors", Flag::TextureCoordinates2D|Flag::Colors}, - {"positions, object id, nonindexed", Flag::ObjectId|Flag::NonIndexed} + {"positions", {}, {}}, + {"positions, implementation-specific index type", {}, + meshIndexTypeWrap(GL_UNSIGNED_INT)}, + {"positions, nonindexed", Flag::NonIndexed, {}}, + {"positions + colors", Flag::Colors, {}}, + {"positions + texture coordinates", Flag::TextureCoordinates2D, {}}, + {"positions + texture coordinates + colors", Flag::TextureCoordinates2D|Flag::Colors, {}}, + {"positions, object id, nonindexed", Flag::ObjectId|Flag::NonIndexed, {}} }; -constexpr struct { +const struct { const char* name; Flags flags; + Containers::Optional indexType; } Data3D[] { - {"positions", {}}, - {"positions, nonindexed", Flag::NonIndexed}, - {"positions + colors", Flag::Colors}, - {"positions + texcoords", Flag::TextureCoordinates2D}, - {"positions + texcoords + colors", Flag::TextureCoordinates2D|Flag::Colors}, - {"positions + normals", Flag::Normals}, - {"positions + normals + colors", Flag::Normals|Flag::Colors}, - {"positions + normals + texcoords", Flag::Normals|Flag::TextureCoordinates2D}, - {"positions + normals + texcoords + colors", Flag::Normals|Flag::TextureCoordinates2D|Flag::Colors}, - {"positions + gen flat normals", Flag::GeneratedFlatNormals}, - {"positions + gen both smooth and flat normals", Flag::GeneratedSmoothNormals|Flag::GeneratedFlatNormals}, - {"positions + normals, gen flat normals", Flag::Normals|Flag::GeneratedFlatNormals}, - {"positions + gen flat normals + colors", Flag::GeneratedFlatNormals|Flag::Colors}, - {"positions + gen flat normals + texcoords", Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D}, - {"positions + gen flat normals + texcoords + colors", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D|Flag::Colors}, - {"positions, nonindexed + gen flat normals", Flag::NonIndexed|Flag::GeneratedFlatNormals}, - {"positions, nonindexed + gen flat normals + colors", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::Colors}, - {"positions, nonindexed + gen flat normals + texcoords", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D}, - {"positions, nonindexed + gen flat normals + texcoords + colors", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D|Flag::Colors}, - {"positions, gen smooth normals", Flag::GeneratedSmoothNormals}, - {"positions, gen smooth normals + colors", Flag::GeneratedSmoothNormals|Flag::Colors}, - {"positions, gen smooth normals + texcoords", Flag::GeneratedSmoothNormals|Flag::TextureCoordinates2D}, - {"positions, gen smooth normals + texcoords + colors", Flag::GeneratedSmoothNormals|Flag::TextureCoordinates2D|Flag::Colors}, - {"positions, nonindexed + gen smooth normals", Flag::NonIndexed|Flag::GeneratedSmoothNormals}, - {"positions, tangents, bitangents, normals", Flag::Tangents|Flag::Bitangents|Flag::Normals}, - {"positions, tangents, bitangents from tangents, normals", Flag::Tangents|Flag::BitangentsFromTangents|Flag::Normals}, - {"positions, object id, nonindexed", Flag::ObjectId|Flag::NonIndexed} + {"positions", {}, {}}, + {"positions, implementation-specific index type", {}, + meshIndexTypeWrap(GL_UNSIGNED_BYTE)}, + {"positions, nonindexed", Flag::NonIndexed, {}}, + {"positions + colors", Flag::Colors, {}}, + {"positions + texcoords", Flag::TextureCoordinates2D,{}}, + {"positions + texcoords + colors", Flag::TextureCoordinates2D|Flag::Colors, {}}, + {"positions + normals", Flag::Normals, {}}, + {"positions + normals + colors", Flag::Normals|Flag::Colors,{}}, + {"positions + normals + texcoords", Flag::Normals|Flag::TextureCoordinates2D, {}}, + {"positions + normals + texcoords + colors", Flag::Normals|Flag::TextureCoordinates2D|Flag::Colors, {}}, + {"positions + gen flat normals", Flag::GeneratedFlatNormals, {}}, + {"positions + gen both smooth and flat normals", Flag::GeneratedSmoothNormals|Flag::GeneratedFlatNormals, {}}, + {"positions + normals, gen flat normals", Flag::Normals|Flag::GeneratedFlatNormals, {}}, + {"positions + gen flat normals + colors", Flag::GeneratedFlatNormals|Flag::Colors, {}}, + {"positions + gen flat normals + texcoords", Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D, {}}, + {"positions + gen flat normals + texcoords + colors", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D|Flag::Colors, {}}, + {"positions, nonindexed + gen flat normals", Flag::NonIndexed|Flag::GeneratedFlatNormals, {}}, + {"positions, nonindexed + gen flat normals + colors", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::Colors, {}}, + {"positions, nonindexed + gen flat normals + texcoords", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D, {}}, + {"positions, nonindexed + gen flat normals + texcoords + colors", Flag::NonIndexed|Flag::GeneratedFlatNormals|Flag::TextureCoordinates2D|Flag::Colors, {}}, + {"positions, gen smooth normals", Flag::GeneratedSmoothNormals, {}}, + {"positions, gen smooth normals + colors", Flag::GeneratedSmoothNormals|Flag::Colors, {}}, + {"positions, gen smooth normals + texcoords", Flag::GeneratedSmoothNormals|Flag::TextureCoordinates2D, {}}, + {"positions, gen smooth normals + texcoords + colors", Flag::GeneratedSmoothNormals|Flag::TextureCoordinates2D|Flag::Colors, {}}, + {"positions, nonindexed + gen smooth normals", Flag::NonIndexed|Flag::GeneratedSmoothNormals, {}}, + {"positions, tangents, bitangents, normals", Flag::Tangents|Flag::Bitangents|Flag::Normals, {}}, + {"positions, tangents, bitangents from tangents, normals", Flag::Tangents|Flag::BitangentsFromTangents|Flag::Normals, {}}, + {"positions, object id, nonindexed", Flag::ObjectId|Flag::NonIndexed, {}} }; constexpr struct { @@ -394,7 +400,7 @@ template void CompileGLTest::twoDimensions() { #ifdef MAGNUM_BUILD_DEPRECATED CORRADE_IGNORE_DEPRECATED_PUSH /** @todo remove once MeshDataXD is gone */ - if(std::is_same::value && data.flags & Flag::ObjectId) + if(std::is_same::value && ((data.flags & Flag::ObjectId) || data.indexType)) CORRADE_SKIP("Not possible with MeshData2D."); CORRADE_IGNORE_DEPRECATED_POP #endif @@ -461,8 +467,14 @@ template void CompileGLTest::twoDimensions() { 4, 5, 8, 4, 8, 7 }; + Trade::MeshIndexData indices; + if(data.indexType) + indices = Trade::MeshIndexData{*data.indexType, Containers::stridedArrayView(Containers::arrayView(indexData).suffix(3))}; + else + indices = Trade::MeshIndexData{Containers::arrayView(indexData).suffix(3)}; + Trade::MeshData meshData{MeshPrimitive::Triangles, - {}, indexData, Trade::MeshIndexData{Containers::arrayView(indexData).suffix(3)}, + {}, indexData, indices, {}, vertexData, std::move(attributeData)}; /* Duplicate everything if data is non-indexed */ @@ -573,7 +585,7 @@ template void CompileGLTest::threeDimensions() { #ifdef MAGNUM_BUILD_DEPRECATED CORRADE_IGNORE_DEPRECATED_PUSH /** @todo remove once MeshDataXD is gone */ - if(std::is_same::value && data.flags & (Flag::Tangents|Flag::Bitangents|Flag::BitangentsFromTangents|Flag::ObjectId)) + if(std::is_same::value && ((data.flags & (Flag::Tangents|Flag::Bitangents|Flag::BitangentsFromTangents|Flag::ObjectId)) || data.indexType)) CORRADE_SKIP("Not possible with MeshData3D."); CORRADE_IGNORE_DEPRECATED_POP #endif @@ -689,8 +701,14 @@ template void CompileGLTest::threeDimensions() { 4, 5, 8, 4, 8, 7 }; + Trade::MeshIndexData indices; + if(data.indexType) + indices = Trade::MeshIndexData{*data.indexType, Containers::stridedArrayView(Containers::arrayView(indexData).suffix(3))}; + else + indices = Trade::MeshIndexData{Containers::arrayView(indexData).suffix(3)}; + Trade::MeshData meshData{MeshPrimitive::Triangles, - {}, indexData, Trade::MeshIndexData{Containers::arrayView(indexData).suffix(3)}, + {}, indexData, indices, {}, vertexData, std::move(attributeData)}; /* Duplicate everything if data is non-indexed */