From db16201fbefde06497da7345f8d8cd8446b857aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 14 Mar 2020 23:31:47 +0100 Subject: [PATCH] GL: support converting matrix VertexFormats to DynamicAttribute as well. --- src/Magnum/GL/Attribute.cpp | 12 ++++- src/Magnum/GL/Attribute.h | 6 +-- src/Magnum/GL/Test/AttributeTest.cpp | 75 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/src/Magnum/GL/Attribute.cpp b/src/Magnum/GL/Attribute.cpp index f13623d38..68fe7b33e 100644 --- a/src/Magnum/GL/Attribute.cpp +++ b/src/Magnum/GL/Attribute.cpp @@ -470,6 +470,13 @@ Debug& operator<<(Debug& debug, const Attribute>::DataTyp } bool hasVertexFormat(const VertexFormat format) { + /* Non-square matrices are not supported on ES2 */ + #ifdef MAGNUM_TARGET_GLES2 + const UnsignedInt vectorCount = vertexFormatVectorCount(format); + if(vectorCount != 1 && vectorCount != vertexFormatComponentCount(format)) + return false; + #endif + switch(vertexFormatComponentFormat(format)) { case VertexFormat::UnsignedByte: case VertexFormat::Byte: @@ -547,7 +554,7 @@ UnsignedInt attributeSize(DynamicAttribute::Components components, DynamicAttrib DynamicAttribute::DynamicAttribute(const Kind kind, const UnsignedInt location, const Components components, const UnsignedInt vectors, const DataType dataType): DynamicAttribute{kind, location, components, vectors, attributeSize(components, dataType), dataType} {} -DynamicAttribute::DynamicAttribute(const Kind kind, UnsignedInt location, const VertexFormat format, GLint maxComponents): _kind{kind}, _location{location}, _components{Components(vertexFormatComponentCount(format))}, _vectors{vertexFormatVectorCount(format)}, _vectorStride{vertexFormatVectorStride(format)} { +DynamicAttribute::DynamicAttribute(const Kind kind, UnsignedInt location, const VertexFormat format, UnsignedInt maxVectors, GLint maxComponents): _kind{kind}, _location{location}, _components{Components(vertexFormatComponentCount(format))}, _vectors{vertexFormatVectorCount(format)}, _vectorStride{vertexFormatVectorStride(format)} { CORRADE_ASSERT(hasVertexFormat(format), "GL::DynamicAttribute:" << format << "isn't available on this target", ); @@ -599,10 +606,13 @@ DynamicAttribute::DynamicAttribute(const Kind kind, UnsignedInt location, const } #ifndef CORRADE_NO_DEBUG + CORRADE_ASSERT(_vectors <= maxVectors, + "GL::DynamicAttribute: can't use" << format << "for a" << maxVectors << Debug::nospace << "-vector attribute", ); /* Should pass also if maxComponents is GL_BGRA */ CORRADE_ASSERT(GLint(_components) <= maxComponents, "GL::DynamicAttribute: can't use" << format << "for a" << maxComponents << Debug::nospace << "-component attribute", ); #else + static_cast(maxVectors); static_cast(maxComponents); #endif } diff --git a/src/Magnum/GL/Attribute.h b/src/Magnum/GL/Attribute.h index ea4af7e0d..73ef9657d 100644 --- a/src/Magnum/GL/Attribute.h +++ b/src/Magnum/GL/Attribute.h @@ -639,7 +639,7 @@ class MAGNUM_GL_EXPORT DynamicAttribute { * / @ref Kind::Long and integral for @ref Kind::Integral. * @see @ref hasVertexFormat() */ - explicit DynamicAttribute(Kind kind, UnsignedInt location, VertexFormat format): DynamicAttribute{kind, location, format, 4} {} + explicit DynamicAttribute(Kind kind, UnsignedInt location, VertexFormat format): DynamicAttribute{kind, location, format, 4, 4} {} /** * @brief Construct from a compile-time attribute with a generic mesh attribute type override @@ -684,7 +684,7 @@ class MAGNUM_GL_EXPORT DynamicAttribute { private: /* Used by the constructor taking Attribute, defined in cpp to avoid a dependency on for the assertion */ - explicit DynamicAttribute(Kind kind, UnsignedInt location, VertexFormat format, GLint maxComponents); + explicit DynamicAttribute(Kind kind, UnsignedInt location, VertexFormat format, UnsignedInt maxVectors, GLint maxComponents); Kind _kind; UnsignedInt _location; @@ -1047,7 +1047,7 @@ template struct Attribute>: Attribute constexpr DynamicAttribute::DynamicAttribute(const Attribute& attribute): _kind{Implementation::kindFor(attribute.dataOptions())}, _location{location_}, _components{Components(GLint(attribute.components()))}, _vectors{Attribute::Vectors}, _vectorStride{attribute.vectorStride()}, _dataType{DataType(GLenum(attribute.dataType()))} {} -template DynamicAttribute::DynamicAttribute(const Attribute& attribute, const VertexFormat format): DynamicAttribute{Implementation::kindFor(attribute.dataOptions()), location_, format, GLint(Implementation::Attribute::DefaultComponents)} {} +template DynamicAttribute::DynamicAttribute(const Attribute& attribute, const VertexFormat format): DynamicAttribute{Implementation::kindFor(attribute.dataOptions()), location_, format, Attribute::Vectors, GLint(Implementation::Attribute::DefaultComponents)} {} }} diff --git a/src/Magnum/GL/Test/AttributeTest.cpp b/src/Magnum/GL/Test/AttributeTest.cpp index 628cfe8e9..72751aacb 100644 --- a/src/Magnum/GL/Test/AttributeTest.cpp +++ b/src/Magnum/GL/Test/AttributeTest.cpp @@ -62,6 +62,10 @@ struct AttributeTest: TestSuite::Tester { #ifndef MAGNUM_TARGET_GLES void attributeFromGenericFormatLong(); #endif + void attributeFromGenericFormatMatrixNxN(); + #ifndef MAGNUM_TARGET_GLES2 + void attributeFromGenericFormatMatrixMxN(); + #endif void attributeFromGenericFormatEnableNormalized(); void attributeFromGenericFormatUnexpectedForNormalizedKind(); #ifndef MAGNUM_TARGET_GLES2 @@ -70,6 +74,7 @@ struct AttributeTest: TestSuite::Tester { #ifndef MAGNUM_TARGET_GLES void attributeFromGenericFormatUnexpectedForLongKind(); #endif + void attributeFromGenericFormatTooManyVectors(); void attributeFromGenericFormatTooManyComponents(); void attributeFromGenericFormatNotAvailable(); @@ -128,6 +133,10 @@ AttributeTest::AttributeTest() { #ifndef MAGNUM_TARGET_GLES &AttributeTest::attributeFromGenericFormatLong, #endif + &AttributeTest::attributeFromGenericFormatMatrixNxN, + #ifndef MAGNUM_TARGET_GLES2 + &AttributeTest::attributeFromGenericFormatMatrixMxN, + #endif &AttributeTest::attributeFromGenericFormatEnableNormalized, &AttributeTest::attributeFromGenericFormatUnexpectedForNormalizedKind, #ifndef MAGNUM_TARGET_GLES2 @@ -136,6 +145,7 @@ AttributeTest::AttributeTest() { #ifndef MAGNUM_TARGET_GLES &AttributeTest::attributeFromGenericFormatUnexpectedForLongKind, #endif + &AttributeTest::attributeFromGenericFormatTooManyVectors, &AttributeTest::attributeFromGenericFormatTooManyComponents, &AttributeTest::attributeFromGenericFormatNotAvailable, @@ -640,6 +650,8 @@ void AttributeTest::attributeFromGenericFormat() { CORRADE_COMPARE(a.kind(), DynamicAttribute::Kind::Generic); CORRADE_COMPARE(a.location(), 3); CORRADE_COMPARE(a.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(a.vectorStride(), 2); + CORRADE_COMPARE(a.vectors(), 1); CORRADE_COMPARE(a.dataType(), DynamicAttribute::DataType::UnsignedShort); /* Check that compile-time attribs work too */ @@ -648,6 +660,8 @@ void AttributeTest::attributeFromGenericFormat() { CORRADE_COMPARE(a2.kind(), DynamicAttribute::Kind::Generic); CORRADE_COMPARE(a2.location(), 7); CORRADE_COMPARE(a2.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(a2.vectorStride(), 2); + CORRADE_COMPARE(a2.vectors(), 1); CORRADE_COMPARE(a2.dataType(), DynamicAttribute::DataType::UnsignedShort); DynamicAttribute b{DynamicAttribute::Kind::GenericNormalized, 3, @@ -655,6 +669,8 @@ void AttributeTest::attributeFromGenericFormat() { CORRADE_COMPARE(b.kind(), DynamicAttribute::Kind::GenericNormalized); CORRADE_COMPARE(b.location(), 3); CORRADE_COMPARE(b.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(b.vectorStride(), 2); + CORRADE_COMPARE(b.vectors(), 1); CORRADE_COMPARE(b.dataType(), DynamicAttribute::DataType::Byte); DynamicAttribute c{DynamicAttribute::Kind::Generic, 3, @@ -705,6 +721,50 @@ void AttributeTest::attributeFromGenericFormatLong() { } #endif +void AttributeTest::attributeFromGenericFormatMatrixNxN() { + DynamicAttribute a{DynamicAttribute::Kind::Generic, 13, + VertexFormat::Matrix2x2bNormalizedAligned}; + CORRADE_COMPARE(a.kind(), DynamicAttribute::Kind::GenericNormalized); + CORRADE_COMPARE(a.location(), 13); + CORRADE_COMPARE(a.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(a.vectorStride(), 4); + CORRADE_COMPARE(a.vectors(), 2); + CORRADE_COMPARE(a.dataType(), DynamicAttribute::DataType::Byte); + + /* Check that compile-time attribs work too */ + DynamicAttribute a2{Attribute<7, Matrix3x3>{}, + VertexFormat::Matrix2x2}; + CORRADE_COMPARE(a2.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(a2.location(), 7); + CORRADE_COMPARE(a2.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(a2.vectorStride(), 8); + CORRADE_COMPARE(a2.vectors(), 2); + CORRADE_COMPARE(a2.dataType(), DynamicAttribute::DataType::Float); +} + +#ifndef MAGNUM_TARGET_GLES2 +void AttributeTest::attributeFromGenericFormatMatrixMxN() { + DynamicAttribute a{DynamicAttribute::Kind::Generic, 13, + VertexFormat::Matrix4x3h}; + CORRADE_COMPARE(a.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(a.location(), 13); + CORRADE_COMPARE(a.components(), DynamicAttribute::Components::Three); + CORRADE_COMPARE(a.vectorStride(), 6); + CORRADE_COMPARE(a.vectors(), 4); + CORRADE_COMPARE(a.dataType(), DynamicAttribute::DataType::Half); + + /* Check that compile-time attribs work too */ + DynamicAttribute a2{Attribute<7, Matrix4x4>{}, + VertexFormat::Matrix4x3sNormalizedAligned}; + CORRADE_COMPARE(a2.kind(), DynamicAttribute::Kind::GenericNormalized); + CORRADE_COMPARE(a2.location(), 7); + CORRADE_COMPARE(a2.components(), DynamicAttribute::Components::Three); + CORRADE_COMPARE(a2.vectorStride(), 8); + CORRADE_COMPARE(a2.vectors(), 4); + CORRADE_COMPARE(a2.dataType(), DynamicAttribute::DataType::Short); +} +#endif + void AttributeTest::attributeFromGenericFormatEnableNormalized() { DynamicAttribute a{DynamicAttribute::Kind::Generic, 3, VertexFormat::Vector3ubNormalized}; @@ -749,6 +809,14 @@ void AttributeTest::attributeFromGenericFormatUnexpectedForLongKind() { } #endif +void AttributeTest::attributeFromGenericFormatTooManyVectors() { + std::ostringstream out; + Error redirectError{&out}; + DynamicAttribute{Attribute<7, Vector2>{}, VertexFormat::Matrix2x2}; + CORRADE_COMPARE(out.str(), + "GL::DynamicAttribute: can't use VertexFormat::Matrix2x2 for a 1-vector attribute\n"); +} + void AttributeTest::attributeFromGenericFormatTooManyComponents() { std::ostringstream out; Error redirectError{&out}; @@ -771,8 +839,15 @@ void AttributeTest::attributeFromGenericFormatNotAvailable() { void AttributeTest::hasVertexFormat() { CORRADE_VERIFY(GL::hasVertexFormat(Magnum::VertexFormat::Vector2i)); + CORRADE_VERIFY(GL::hasVertexFormat(Magnum::VertexFormat::Matrix2x2)); #ifdef MAGNUM_TARGET_GLES CORRADE_VERIFY(!GL::hasVertexFormat(Magnum::VertexFormat::Vector3d)); + CORRADE_VERIFY(!GL::hasVertexFormat(Magnum::VertexFormat::Matrix2x3d)); + #endif + #ifndef MAGNUM_TARGET_GLES2 + CORRADE_VERIFY(GL::hasVertexFormat(Magnum::VertexFormat::Matrix2x3)); + #else + CORRADE_VERIFY(!GL::hasVertexFormat(Magnum::VertexFormat::Matrix2x3)); #endif /* Ensure all generic formats are handled by going though all and executing