From c6c8dcb4564ff4c9d38aeaec090b40b0682a9183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 16 Sep 2019 11:32:54 +0200 Subject: [PATCH] GL: make DynamicAttribute constructible directly from an Attribute. Otherwise trying to mirror all the properties is quite error-prone. --- doc/changelog.dox | 2 + src/Magnum/GL/Attribute.h | 22 +++++ src/Magnum/GL/Mesh.h | 6 +- src/Magnum/GL/Test/AttributeTest.cpp | 128 ++++++++++++++++++++++++++- 4 files changed, 154 insertions(+), 4 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 7143a8c9f..eacce5dcb 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -359,6 +359,8 @@ See also: easier debugging, users are encouraged to use the new `--magnum-gpu-validation` @ref GL-Context-command-line "command line option" instead. +- Added an ability to create @ref GL::DynamicAttribute directly from a + @ref GL::Attribute @subsubsection changelog-latest-changes-math Math library diff --git a/src/Magnum/GL/Attribute.h b/src/Magnum/GL/Attribute.h index 207dfd583..d4963bb43 100644 --- a/src/Magnum/GL/Attribute.h +++ b/src/Magnum/GL/Attribute.h @@ -515,6 +515,9 @@ class DynamicAttribute { */ constexpr DynamicAttribute(Kind kind, UnsignedInt location, Components components, DataType dataType): _kind{kind}, _location{location}, _components{components}, _dataType{dataType} {} + /** @brief Construct from a compile-time attribute */ + template constexpr DynamicAttribute(const Attribute& attribute); + /** @brief Attribute kind */ constexpr Kind kind() const { return _kind; } @@ -545,6 +548,23 @@ MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, DynamicAttribute::DataType); namespace Implementation { +template constexpr DynamicAttribute::Kind kindFor(typename std::enable_if::ScalarType, Float>::value, typename GL::Attribute::DataOptions>::type options) { + return options & GL::Attribute::DataOption::Normalized ? + DynamicAttribute::Kind::GenericNormalized : DynamicAttribute::Kind::Generic; +} + +#ifndef MAGNUM_TARGET_GLES2 +template constexpr DynamicAttribute::Kind kindFor(typename std::enable_if::ScalarType>::value, typename GL::Attribute::DataOptions>::type) { + return DynamicAttribute::Kind::Integral; +} + +#ifndef MAGNUM_TARGET_GLES +template constexpr DynamicAttribute::Kind kindFor(typename std::enable_if::ScalarType, Double>::value, typename GL::Attribute::DataOptions>::type) { + return DynamicAttribute::Kind::Long; +} +#endif +#endif + /* Base for sized attributes */ template struct SizedAttribute; @@ -836,6 +856,8 @@ template struct Attribute>: Attribute constexpr DynamicAttribute::DynamicAttribute(const Attribute& attribute): _kind{Implementation::kindFor(attribute.dataOptions())}, _location{location_}, _components{Components(GLint(attribute.components()))}, _dataType{DataType(GLenum(attribute.dataType()))} {} + }} #endif diff --git a/src/Magnum/GL/Mesh.h b/src/Magnum/GL/Mesh.h index 66c7f4485..db0382491 100644 --- a/src/Magnum/GL/Mesh.h +++ b/src/Magnum/GL/Mesh.h @@ -1017,7 +1017,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { location+i, GLint(attribute.components()), GLenum(attribute.dataType()), - attribute.dataOptions() & Attribute::DataOption::Normalized ? DynamicAttribute::Kind::GenericNormalized : DynamicAttribute::Kind::Generic, + Implementation::kindFor(attribute.dataOptions()), GLintptr(offset+i*attribute.vectorSize()), stride, divisor); @@ -1029,7 +1029,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { location, GLint(attribute.components()), GLenum(attribute.dataType()), - DynamicAttribute::Kind::Integral, + Implementation::kindFor(attribute.dataOptions()), offset, stride, divisor); @@ -1042,7 +1042,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { location+i, GLint(attribute.components()), GLenum(attribute.dataType()), - DynamicAttribute::Kind::Long, + Implementation::kindFor(attribute.dataOptions()), GLintptr(offset+i*attribute.vectorSize()), stride, divisor); diff --git a/src/Magnum/GL/Test/AttributeTest.cpp b/src/Magnum/GL/Test/AttributeTest.cpp index 9e70f404a..2d4e1d64e 100644 --- a/src/Magnum/GL/Test/AttributeTest.cpp +++ b/src/Magnum/GL/Test/AttributeTest.cpp @@ -136,15 +136,27 @@ void AttributeTest::attributeScalar() { CORRADE_COMPARE(a.vectorSize(), 4); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Float); + /* Options */ Attribute b(Attribute::DataType::UnsignedShort, Attribute::DataOption::Normalized); CORRADE_COMPARE(b.vectorSize(), 2); CORRADE_VERIFY(b.dataOptions() <= Attribute::DataOption::Normalized); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::GenericNormalized); + CORRADE_COMPARE(db.location(), 3); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::UnsignedShort); } void AttributeTest::attributeScalarInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef Attribute<3, Int> Attribute; + typedef Attribute<2, Int> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -152,9 +164,21 @@ void AttributeTest::attributeScalarInt() { Attribute a; CORRADE_COMPARE(a.vectorSize(), 4); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(da.location(), 2); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Int); + /* Options */ Attribute b(Attribute::DataType::Short); CORRADE_COMPARE(b.vectorSize(), 2); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(db.location(), 2); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::Short); #else CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2."); #endif @@ -170,9 +194,21 @@ void AttributeTest::attributeScalarUnsignedInt() { Attribute a; CORRADE_COMPARE(a.vectorSize(), 4); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::UnsignedInt); + /* Options */ Attribute b(Attribute::DataType::UnsignedByte); CORRADE_COMPARE(b.vectorSize(), 1); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(db.location(), 3); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::UnsignedByte); #else CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2."); #endif @@ -187,6 +223,12 @@ void AttributeTest::attributeScalarDouble() { /* Default constructor */ Attribute a; CORRADE_COMPARE(a.vectorSize(), 8); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Long); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Double); #else CORRADE_SKIP("Double attributes are not available in OpenGL ES."); #endif @@ -203,11 +245,23 @@ void AttributeTest::attributeVector() { CORRADE_COMPARE(a.vectorSize(), 3*4); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Three); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Float); + /* Options */ #ifndef MAGNUM_TARGET_GLES Attribute b(Attribute::Components::Two, Attribute::DataType::Double); CORRADE_COMPARE(b.components(), Attribute::Components::Two); CORRADE_COMPARE(b.vectorSize(), 2*8); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(db.location(), 3); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::Double); #else Attribute b(Attribute::Components::Two, Attribute::DataType::Float); CORRADE_COMPARE(b.components(), Attribute::Components::Two); @@ -227,9 +281,21 @@ void AttributeTest::attributeVectorInt() { CORRADE_COMPARE(a.vectorSize(), 2*4); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Int); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Int); + /* Options */ Attribute b(Attribute::Components::One, Attribute::DataType::Int); CORRADE_COMPARE(b.vectorSize(), 4); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(db.location(), 3); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::Int); #else CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2."); #endif @@ -247,9 +313,21 @@ void AttributeTest::attributeVectorUnsignedInt() { CORRADE_COMPARE(a.vectorSize(), 4*4); CORRADE_COMPARE(a.dataType(), Attribute::DataType::UnsignedInt); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Four); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::UnsignedInt); + /* Options */ Attribute b(Attribute::Components::Three, Attribute::DataType::UnsignedShort); CORRADE_COMPARE(b.vectorSize(), 3*2); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::Integral); + CORRADE_COMPARE(db.location(), 3); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::Three); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::UnsignedShort); #else CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2."); #endif @@ -267,9 +345,21 @@ void AttributeTest::attributeVectorDouble() { CORRADE_COMPARE(a.vectorSize(), 2*8); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Double); + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Long); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Double); + /* Options */ Attribute b(Attribute::Components::One); CORRADE_COMPARE(b.vectorSize(), 8); + + DynamicAttribute db{b}; + CORRADE_COMPARE(db.kind(), DynamicAttribute::Kind::Long); + CORRADE_COMPARE(db.location(), 3); + CORRADE_COMPARE(db.components(), DynamicAttribute::Components::One); + CORRADE_COMPARE(db.dataType(), DynamicAttribute::DataType::Double); #else CORRADE_SKIP("Double attributes are not available in OpenGL ES."); #endif @@ -284,6 +374,12 @@ void AttributeTest::attributeVector4() { #ifndef MAGNUM_TARGET_GLES Attribute a(Attribute::DataType::UnsignedInt2101010Rev); CORRADE_COMPARE(a.vectorSize(), 4); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Four); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::UnsignedInt2101010Rev); #elif !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) Attribute a(Attribute::DataType::HalfFloat); CORRADE_COMPARE(a.vectorSize(), 8); @@ -302,6 +398,12 @@ void AttributeTest::attributeVectorBGRA() { /* BGRA */ Attribute a(Attribute::Components::BGRA); CORRADE_COMPARE(a.vectorSize(), 4*4); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::BGRA); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Float); #else CORRADE_SKIP("BGRA attribute component ordering is not available in OpenGL ES."); #endif @@ -317,6 +419,12 @@ void AttributeTest::attributeMatrixNxN() { CORRADE_COMPARE(a.components(), Attribute::Components::Three); CORRADE_COMPARE(a.vectorSize(), 3*4); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Three); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Float); } #ifndef MAGNUM_TARGET_GLES2 @@ -330,6 +438,12 @@ void AttributeTest::attributeMatrixMxN() { CORRADE_COMPARE(a.components(), Attribute::Components::Four); CORRADE_COMPARE(a.vectorSize(), 4*4); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Generic); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Four); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Float); } #endif @@ -344,6 +458,12 @@ void AttributeTest::attributeMatrixNxNd() { CORRADE_COMPARE(a.components(), Attribute::Components::Four); CORRADE_COMPARE(a.vectorSize(), 4*8); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Double); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Long); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Four); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Double); #else CORRADE_SKIP("Double attributes are not available in OpenGL ES."); #endif @@ -360,6 +480,12 @@ void AttributeTest::attributeMatrixMxNd() { CORRADE_COMPARE(a.components(), Attribute::Components::Two); CORRADE_COMPARE(a.vectorSize(), 2*8); CORRADE_COMPARE(a.dataType(), Attribute::DataType::Double); + + DynamicAttribute da{a}; + CORRADE_COMPARE(da.kind(), DynamicAttribute::Kind::Long); + CORRADE_COMPARE(da.location(), 3); + CORRADE_COMPARE(da.components(), DynamicAttribute::Components::Two); + CORRADE_COMPARE(da.dataType(), DynamicAttribute::DataType::Double); #else CORRADE_SKIP("Double attributes are not available in OpenGL ES."); #endif