From 417471b83c001825424987772bb69b550ae69949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 8 Aug 2020 18:49:45 +0200 Subject: [PATCH] Trade: add FlatMaterialData. --- doc/changelog.dox | 3 +- src/Magnum/Trade/CMakeLists.txt | 2 + src/Magnum/Trade/FlatMaterialData.cpp | 107 +++++++++ src/Magnum/Trade/FlatMaterialData.h | 152 ++++++++++++ src/Magnum/Trade/MaterialData.cpp | 2 + src/Magnum/Trade/MaterialData.h | 36 ++- .../Trade/PbrMetallicRoughnessMaterialData.h | 2 +- .../Trade/PbrSpecularGlossinessMaterialData.h | 2 +- src/Magnum/Trade/PhongMaterialData.h | 2 +- src/Magnum/Trade/Test/MaterialDataTest.cpp | 220 ++++++++++++++++++ src/Magnum/Trade/Trade.h | 2 + 11 files changed, 515 insertions(+), 15 deletions(-) create mode 100644 src/Magnum/Trade/FlatMaterialData.cpp create mode 100644 src/Magnum/Trade/FlatMaterialData.h diff --git a/doc/changelog.dox b/doc/changelog.dox index f84a8d5c9..412efeb4f 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -76,7 +76,8 @@ See also: - A new, redesigned @ref Trade::MaterialData class allowing to store custom material attributes as well as more material types together in a single - instance; plus new @ref Trade::PbrMetallicRoughnessMaterialData and + instance; plus new @ref Trade::FlatMaterialData, + @ref Trade::PbrMetallicRoughnessMaterialData and @ref Trade::PbrSpecularGlossinessMaterialData convenience accessor APIs similar to @ref Trade::PhongMaterialData. See [mosra/magnum#459](https://github.com/mosra/magnum/pull/459). diff --git a/src/Magnum/Trade/CMakeLists.txt b/src/Magnum/Trade/CMakeLists.txt index aa9a2a4a1..699bdaad8 100644 --- a/src/Magnum/Trade/CMakeLists.txt +++ b/src/Magnum/Trade/CMakeLists.txt @@ -40,6 +40,7 @@ set(MagnumTrade_GracefulAssert_SRCS AbstractSceneConverter.cpp AnimationData.cpp CameraData.cpp + FlatMaterialData.cpp ImageData.cpp MaterialData.cpp MeshData.cpp @@ -57,6 +58,7 @@ set(MagnumTrade_HEADERS ArrayAllocator.h CameraData.h Data.h + FlatMaterialData.h ImageData.h LightData.h MaterialData.h diff --git a/src/Magnum/Trade/FlatMaterialData.cpp b/src/Magnum/Trade/FlatMaterialData.cpp new file mode 100644 index 000000000..b405f5e68 --- /dev/null +++ b/src/Magnum/Trade/FlatMaterialData.cpp @@ -0,0 +1,107 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "FlatMaterialData.h" + +#include "Magnum/Math/Color.h" +#include "Magnum/Math/Matrix3.h" + +namespace Magnum { namespace Trade { + +using namespace Math::Literals; + +bool FlatMaterialData::hasTexture() const { + return hasAttribute(MaterialAttribute::BaseColorTexture) || + hasAttribute(MaterialAttribute::DiffuseTexture); +} + +bool FlatMaterialData::hasTextureTransformation() const { + return (hasAttribute(MaterialAttribute::BaseColorTexture) && hasAttribute(MaterialAttribute::BaseColorTextureMatrix)) || + (hasAttribute(MaterialAttribute::DiffuseTexture) && hasAttribute(MaterialAttribute::DiffuseTextureMatrix)) || + hasAttribute(MaterialAttribute::TextureMatrix); +} + +bool FlatMaterialData::hasTextureCoordinates() const { + return (hasAttribute(MaterialAttribute::BaseColorTexture) && hasAttribute(MaterialAttribute::BaseColorTextureCoordinates)) || + (hasAttribute(MaterialAttribute::DiffuseTexture) && hasAttribute(MaterialAttribute::DiffuseTextureCoordinates)) || + hasAttribute(MaterialAttribute::TextureCoordinates); +} + +Color4 FlatMaterialData::color() const { + /* If the material has a texture, return the color that matches it */ + if(hasAttribute(MaterialAttribute::BaseColorTexture)) + return attributeOr(MaterialAttribute::BaseColor, 0xffffffff_srgbaf); + if(hasAttribute(MaterialAttribute::DiffuseTexture)) + return attributeOr(MaterialAttribute::DiffuseColor, 0xffffffff_srgbaf); + + /* If there's no texture, return whatever is present */ + if(Containers::Optional value = tryAttribute(MaterialAttribute::BaseColor)) + return *value; + return attributeOr(MaterialAttribute::DiffuseColor, 0xffffffff_srgbaf); +} + +UnsignedInt FlatMaterialData::texture() const { + /* Explicit assertion because printing that DiffuseTexture isn't found + would be misleading as it can be also BaseColorTexture */ + CORRADE_ASSERT(hasTexture(), + "Trade::FlatMaterialData::texture(): the material doesn't have a texture", {}); + if(Containers::Optional value = tryAttribute(MaterialAttribute::BaseColorTexture)) + return *value; + return attribute(MaterialAttribute::DiffuseTexture); +} + +Matrix3 FlatMaterialData::textureMatrix() const { + if(hasAttribute(MaterialAttribute::BaseColorTexture)) { + if(Containers::Optional value = tryAttribute(MaterialAttribute::BaseColorTextureMatrix)) + return *value; + return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{}); + } + + if(hasAttribute(MaterialAttribute::DiffuseTexture)) { + if(Containers::Optional value = tryAttribute(MaterialAttribute::DiffuseTextureMatrix)) + return *value; + return attributeOr(MaterialAttribute::TextureMatrix, Matrix3{}); + } + + CORRADE_ASSERT_UNREACHABLE("Trade::FlatMaterialData::textureMatrix(): the material doesn't have a texture", {}); +} + +UnsignedInt FlatMaterialData::textureCoordinates() const { + if(hasAttribute(MaterialAttribute::BaseColorTexture)) { + if(Containers::Optional value = tryAttribute(MaterialAttribute::BaseColorTextureCoordinates)) + return *value; + return attributeOr(MaterialAttribute::TextureCoordinates, 0u); + } + + if(hasAttribute(MaterialAttribute::DiffuseTexture)) { + if(Containers::Optional value = tryAttribute(MaterialAttribute::DiffuseTextureCoordinates)) + return *value; + return attributeOr(MaterialAttribute::TextureCoordinates, 0u); + } + + CORRADE_ASSERT_UNREACHABLE("Trade::FlatMaterialData::textureCoordinates(): the material doesn't have a texture", {}); +} + +}} diff --git a/src/Magnum/Trade/FlatMaterialData.h b/src/Magnum/Trade/FlatMaterialData.h new file mode 100644 index 000000000..88be29535 --- /dev/null +++ b/src/Magnum/Trade/FlatMaterialData.h @@ -0,0 +1,152 @@ +#ifndef Magnum_Trade_FlatMaterialData_h +#define Magnum_Trade_FlatMaterialData_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Trade::FlatMaterialData + * @m_since_latest + */ + +#include "Magnum/Trade/MaterialData.h" + +namespace Magnum { namespace Trade { + +/** +@brief Flat material data +@m_since_latest + +@see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData, + @ref PbrSpecularGlossinessMaterialData, @ref PhongMaterialData +*/ +class MAGNUM_TRADE_EXPORT FlatMaterialData: public MaterialData { + public: + #ifndef DOXYGEN_GENERATING_OUTPUT + /* Allow constructing subclasses directly. While not used in the + general Importer workflow, it allows users to create instances with + desired convenience APIs easier (and simplifies testing). It's + however hidden from the docs as constructing instances this way + isn't really common and it would add a lot of noise. */ + using MaterialData::MaterialData; + #endif + + /** + * @brief Whether the material has a specular texture + * + * Returns @cpp true @ce if any of the + * @ref MaterialAttribute::BaseColorTexture or + * @ref MaterialAttribute::DiffuseTexture attributes is present, + * @cpp false @ce otherwise. + */ + bool hasTexture() const; + + /** + * @brief Whether the material has texture transformation + * + * Returns @cpp true @ce if the material is textured and a + * @ref MaterialAttribute::BaseColorTextureMatrix, + * @ref MaterialAttribute::DiffuseTextureMatrix or + * @ref MaterialAttribute::TextureMatrix attribute matching the texture + * is present, @cpp false @ce otherwise. In particular, if there's for + * example a @ref MaterialAttribute::BaseColorTexture but only a + * @ref MaterialAttribute::DiffuseTextureMatrix, + * returns @cpp false @ce. + */ + bool hasTextureTransformation() const; + + /** + * @brief Whether the material uses extra texture coordinate sets + * + * Returns @cpp true @ce if the material is textured an a + * @ref MaterialAttribute::BaseColorTextureCoordinates, + * @ref MaterialAttribute::DiffuseTextureCoordinates or + * @ref MaterialAttribute::TextureCoordinates attribute matching the + * texture is present and has a non-zero value, @cpp false @ce + * otherwise. In particular, if there's for example a + * @ref MaterialAttribute::BaseColorTexture but + * only a @ref MaterialAttribute::DiffuseTextureCoordinates, returns + * @cpp false @ce. + */ + bool hasTextureCoordinates() const; + + /** + * @brief Color + * + * Convenience access to the @ref MaterialAttribute::BaseColor / + * @ref MaterialAttribute::DiffuseColor attributes. If neither of them + * is present, the default is @cpp 0xffffffff_srgbaf @ce. + * + * If the material has a texture, the color attribute matching the + * texture is picked (instead of combining e.g. a + * @ref MaterialAttribute::BaseColor with @ref MaterialAttribute::DiffuseTexture). The color and texture is meant to + * be multiplied together. + * @see @ref hasAttribute(), @ref hasTexture() + */ + Color4 color() const; + + /** + * @brief Texture ID + * + * Available only if either @ref MaterialAttribute::BaseColorTexture or + * @ref MaterialAttribute::DiffuseTexture is present. Meant to be + * multiplied with @ref color(). + * @see @ref hasTexture(), @ref AbstractImporter::texture() + */ + UnsignedInt texture() const; + + /** + * @brief Texture coordinate transformation matrix + * + * Convenience access to the @ref MaterialAttribute::DiffuseTextureMatrix + * / @ref MaterialAttribute::BaseColorTextureMatrix / + * @ref MaterialAttribute::TextureMatrix attributes, picking the one + * matching the texture (instead of combining e.g. a + * @ref MaterialAttribute::BaseColorTexture with + * @ref MaterialAttribute::DiffuseTextureMatrix). If no matching + * attribute is present, the default is an identity matrix. Available + * only if the material has a texture. + * @see @ref hasTexture() + */ + Matrix3 textureMatrix() const; + + /** + * @brief Texture coordinate set + * + * Convenience access to the @ref MaterialAttribute::DiffuseTextureCoordinates + * / @ref MaterialAttribute::BaseColorTextureCoordinates / + * @ref MaterialAttribute::TextureCoordinates attributes, picking the + * one matching the texture (instead of combining e.g. a + * @ref MaterialAttribute::BaseColorTexture with + * @ref MaterialAttribute::DiffuseTextureCoordinates). If no matching + * attribute is present, the default is @cpp 0 @ce. Available only if + * the material has a texture. + * @see @ref hasTexture() + */ + UnsignedInt textureCoordinates() const; +}; + +}} + +#endif diff --git a/src/Magnum/Trade/MaterialData.cpp b/src/Magnum/Trade/MaterialData.cpp index 5fc4ed97d..919a68e76 100644 --- a/src/Magnum/Trade/MaterialData.cpp +++ b/src/Magnum/Trade/MaterialData.cpp @@ -648,6 +648,7 @@ Debug& operator<<(Debug& debug, const MaterialType value) { switch(value) { /* LCOV_EXCL_START */ #define _c(value) case MaterialType::value: return debug << "::" #value; + _c(Flat) _c(Phong) _c(PbrMetallicRoughness) _c(PbrSpecularGlossiness) @@ -660,6 +661,7 @@ Debug& operator<<(Debug& debug, const MaterialType value) { Debug& operator<<(Debug& debug, const MaterialTypes value) { return Containers::enumSetDebugOutput(debug, value, "Trade::MaterialTypes{}", { + MaterialType::Flat, MaterialType::Phong, MaterialType::PbrMetallicRoughness, MaterialType::PbrSpecularGlossiness diff --git a/src/Magnum/Trade/MaterialData.h b/src/Magnum/Trade/MaterialData.h index ba560ed56..14376cbe1 100644 --- a/src/Magnum/Trade/MaterialData.h +++ b/src/Magnum/Trade/MaterialData.h @@ -149,7 +149,8 @@ enum class MaterialAttribute: UnsignedInt { * * If @ref MaterialAttribute::DiffuseTexture is present as well, these two * are multiplied together. - * @see @ref PhongMaterialData::diffuseColor(), + * @see @ref FlatMaterialData::color(), + * @ref PhongMaterialData::diffuseColor(), * @ref PbrSpecularGlossinessMaterialData::diffuseColor() */ DiffuseColor, @@ -160,7 +161,8 @@ enum class MaterialAttribute: UnsignedInt { * * If @ref MaterialAttribute::DiffuseColor is present as well, these two * are multiplied together. - * @see @ref PhongMaterialData::diffuseTexture(), + * @see @ref FlatMaterialData::texture(), + * @ref PhongMaterialData::diffuseTexture(), * @ref PbrSpecularGlossinessMaterialData::diffuseTexture() */ DiffuseTexture, @@ -171,7 +173,8 @@ enum class MaterialAttribute: UnsignedInt { * * Has a precedence over @ref MaterialAttribute::TextureMatrix if both are * present. - * @see @ref PhongMaterialData::diffuseTextureMatrix(), + * @see @ref FlatMaterialData::textureMatrix(), + * @ref PhongMaterialData::diffuseTextureMatrix(), * @ref PbrSpecularGlossinessMaterialData::diffuseTextureMatrix() */ DiffuseTextureMatrix, @@ -182,7 +185,8 @@ enum class MaterialAttribute: UnsignedInt { * * Has a precedence over @ref MaterialAttribute::TextureCoordinates if both * are present. - * @see @ref PhongMaterialData::diffuseTextureCoordinates(), + * @see @ref FlatMaterialData::textureCoordinates(), + * @ref PhongMaterialData::diffuseTextureCoordinates(), * @ref PbrSpecularGlossinessMaterialData::diffuseTextureCoordinates() */ DiffuseTextureCoordinates, @@ -267,7 +271,8 @@ enum class MaterialAttribute: UnsignedInt { * * If @ref MaterialAttribute::BaseColorTexture is present as well, these * two are multiplied together. - * @see @ref PbrMetallicRoughnessMaterialData::baseColor() + * @see @ref FlatMaterialData::color(), + * @ref PbrMetallicRoughnessMaterialData::baseColor() */ BaseColor, @@ -277,7 +282,8 @@ enum class MaterialAttribute: UnsignedInt { * * If @ref MaterialAttribute::BaseColor is present as well, these two are * multiplied together. - * @see @ref PbrMetallicRoughnessMaterialData::baseColorTexture() + * @see @ref FlatMaterialData::texture(), + * @ref PbrMetallicRoughnessMaterialData::baseColorTexture() */ BaseColorTexture, @@ -287,7 +293,8 @@ enum class MaterialAttribute: UnsignedInt { * * Has a precedence over @ref MaterialAttribute::TextureMatrix if both are * present. - * @see @ref PbrMetallicRoughnessMaterialData::baseColorTextureMatrix() + * @see @ref FlatMaterialData::textureMatrix(), + * @ref PbrMetallicRoughnessMaterialData::baseColorTextureMatrix() */ BaseColorTextureMatrix, @@ -297,7 +304,8 @@ enum class MaterialAttribute: UnsignedInt { * * Has a precedence over @ref MaterialAttribute::TextureCoordinates if both * are present. - * @see @ref PbrMetallicRoughnessMaterialData::baseColorTextureCoordinates() + * @see @ref FlatMaterialData::textureCoordinates(), + * @ref PbrMetallicRoughnessMaterialData::baseColorTextureCoordinates() */ BaseColorTextureCoordinates, @@ -1147,22 +1155,28 @@ class MAGNUM_TRADE_EXPORT MaterialAttributeData { @see @ref MaterialTypes, @ref MaterialData::types() */ enum class MaterialType: UnsignedInt { + /** + * Flat. Use @ref FlatMaterialData for convenience attribute access. + * Materials of this type are generally not combined with any other types. + */ + Flat = 1 << 0, + /** * Phong. Use @ref PhongMaterialData for convenience attribute access. */ - Phong = 1 << 0, + Phong = 1 << 1, /** * PBR metallic/roughness. Use @ref PbrMetallicRoughnessMaterialData for * convenience attribute access. */ - PbrMetallicRoughness = 1 << 1, + PbrMetallicRoughness = 1 << 2, /** * PBR specular/glossiness. Use @ref PbrSpecularGlossinessMaterialData for * convenience attribute access. */ - PbrSpecularGlossiness = 1 << 2 + PbrSpecularGlossiness = 1 << 3 }; /** @debugoperatorenum{MaterialType} */ diff --git a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h index dcfb9f2de..97e7b33bf 100644 --- a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h +++ b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h @@ -39,7 +39,7 @@ namespace Magnum { namespace Trade { @m_since_latest @see @ref AbstractImporter::material(), @ref PbrSpecularGlossinessMaterialData, - @ref PhongMaterialData + @ref PhongMaterialData, @ref FlatMaterialData */ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData { public: diff --git a/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h b/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h index 719d87f94..420c02e4b 100644 --- a/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h +++ b/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h @@ -39,7 +39,7 @@ namespace Magnum { namespace Trade { @m_since_latest @see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData, - @ref PhongMaterialData + @ref PhongMaterialData, @ref FlatMaterialData */ class MAGNUM_TRADE_EXPORT PbrSpecularGlossinessMaterialData: public MaterialData { public: diff --git a/src/Magnum/Trade/PhongMaterialData.h b/src/Magnum/Trade/PhongMaterialData.h index 646047556..c436b88a2 100644 --- a/src/Magnum/Trade/PhongMaterialData.h +++ b/src/Magnum/Trade/PhongMaterialData.h @@ -38,7 +38,7 @@ namespace Magnum { namespace Trade { @brief Phong material data @see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData, - @ref PbrSpecularGlossinessMaterialData + @ref PbrSpecularGlossinessMaterialData, @ref FlatMaterialData */ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData { public: diff --git a/src/Magnum/Trade/Test/MaterialDataTest.cpp b/src/Magnum/Trade/Test/MaterialDataTest.cpp index 05e614cc7..47cb7b585 100644 --- a/src/Magnum/Trade/Test/MaterialDataTest.cpp +++ b/src/Magnum/Trade/Test/MaterialDataTest.cpp @@ -33,6 +33,7 @@ #include "Magnum/Math/Color.h" #include "Magnum/Math/Matrix3.h" +#include "Magnum/Trade/FlatMaterialData.h" #include "Magnum/Trade/MaterialData.h" #include "Magnum/Trade/PbrMetallicRoughnessMaterialData.h" #include "Magnum/Trade/PbrSpecularGlossinessMaterialData.h" @@ -161,6 +162,17 @@ class MaterialDataTest: public TestSuite::Tester { void phongAccessTexturedImplicitPackedSpecularGlossiness(); void phongAccessInvalidTextures(); + void flatAccessBaseColor(); + void flatAccessDiffuseColor(); + void flatAccessDefaults(); + void flatAccessTexturedBaseColor(); + void flatAccessTexturedDiffuseColor(); + void flatAccessTexturedDefaults(); + void flatAccessTexturedBaseColorSingleMatrixCoordinates(); + void flatAccessTexturedDiffuseColorSingleMatrixCoordinates(); + void flatAccessTexturedMismatchedMatrixCoordinates(); + void flatAccessInvalidTextures(); + void debugAttribute(); void debugTextureSwizzle(); void debugAttributeType(); @@ -323,6 +335,17 @@ MaterialDataTest::MaterialDataTest() { &MaterialDataTest::phongAccessTexturedImplicitPackedSpecularGlossiness, &MaterialDataTest::phongAccessInvalidTextures, + &MaterialDataTest::flatAccessBaseColor, + &MaterialDataTest::flatAccessDiffuseColor, + &MaterialDataTest::flatAccessDefaults, + &MaterialDataTest::flatAccessTexturedBaseColor, + &MaterialDataTest::flatAccessTexturedDiffuseColor, + &MaterialDataTest::flatAccessTexturedDefaults, + &MaterialDataTest::flatAccessTexturedBaseColorSingleMatrixCoordinates, + &MaterialDataTest::flatAccessTexturedDiffuseColorSingleMatrixCoordinates, + &MaterialDataTest::flatAccessTexturedMismatchedMatrixCoordinates, + &MaterialDataTest::flatAccessInvalidTextures, + &MaterialDataTest::debugAttribute, &MaterialDataTest::debugTextureSwizzle, &MaterialDataTest::debugAttributeType, @@ -3389,6 +3412,203 @@ void MaterialDataTest::phongAccessInvalidTextures() { "Trade::PhongMaterialData::normalTextureCoordinates(): the material doesn't have a normal texture\n"); } +void MaterialDataTest::flatAccessBaseColor() { + MaterialData base{MaterialType::Flat, { + {MaterialAttribute::BaseColor, 0xccffbbff_rgbaf}, + {MaterialAttribute::DiffuseColor, 0x33556600_rgbaf}, /* Ignored */ + }}; + + CORRADE_COMPARE(base.types(), MaterialType::Flat); + const auto& data = base.as(); + + CORRADE_VERIFY(!data.hasTexture()); + CORRADE_VERIFY(!data.hasTextureTransformation()); + CORRADE_VERIFY(!data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xccffbb_rgbf); +} + +void MaterialDataTest::flatAccessDiffuseColor() { + MaterialData base{MaterialType::Flat, { + {MaterialAttribute::DiffuseColor, 0xccffbbff_rgbaf}, + }}; + + CORRADE_COMPARE(base.types(), MaterialType::Flat); + const auto& data = base.as(); + + CORRADE_VERIFY(!data.hasTexture()); + CORRADE_VERIFY(!data.hasTextureTransformation()); + CORRADE_VERIFY(!data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xccffbb_rgbf); +} + +void MaterialDataTest::flatAccessDefaults() { + MaterialData base{{}, {}}; + + CORRADE_COMPARE(base.types(), MaterialTypes{}); + /* Casting is fine even if the type doesn't include Flat */ + const auto& data = base.as(); + + CORRADE_VERIFY(!data.hasTexture()); + CORRADE_VERIFY(!data.hasTextureTransformation()); + CORRADE_VERIFY(!data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xffffff_rgbf); +} + +void MaterialDataTest::flatAccessTexturedBaseColor() { + FlatMaterialData data{{}, { + {MaterialAttribute::BaseColor, 0xccffbbff_rgbaf}, + {MaterialAttribute::BaseColorTexture, 5u}, + {MaterialAttribute::BaseColorTextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::BaseColorTextureCoordinates, 2u}, + + /* All this is ignored */ + {MaterialAttribute::DiffuseColor, 0x33556600_rgbaf}, + {MaterialAttribute::DiffuseTexture, 6u}, + {MaterialAttribute::DiffuseTextureMatrix, Matrix3::translation({0.5f, 1.0f})}, + {MaterialAttribute::DiffuseTextureCoordinates, 3u} + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(data.hasTextureTransformation()); + CORRADE_VERIFY(data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xccffbb_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3::scaling({0.5f, 1.0f})); + CORRADE_COMPARE(data.textureCoordinates(), 2); +} + +void MaterialDataTest::flatAccessTexturedDiffuseColor() { + FlatMaterialData data{{}, { + {MaterialAttribute::DiffuseColor, 0xccffbbff_rgbaf}, + {MaterialAttribute::DiffuseTexture, 5u}, + {MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::DiffuseTextureCoordinates, 2u}, + + /* Ignored, as we have a diffuse texture */ + {MaterialAttribute::BaseColor, 0x33556600_rgbaf} + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(data.hasTextureTransformation()); + CORRADE_VERIFY(data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xccffbb_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3::scaling({0.5f, 1.0f})); + CORRADE_COMPARE(data.textureCoordinates(), 2); +} + +void MaterialDataTest::flatAccessTexturedDefaults() { + FlatMaterialData data{{}, { + {MaterialAttribute::DiffuseTexture, 5u} + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(!data.hasTextureTransformation()); + CORRADE_VERIFY(!data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xffffff_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3{}); + CORRADE_COMPARE(data.textureCoordinates(), 0); +} + +void MaterialDataTest::flatAccessTexturedBaseColorSingleMatrixCoordinates() { + FlatMaterialData data{{}, { + {MaterialAttribute::BaseColor, 0xccffbbff_rgbaf}, + {MaterialAttribute::BaseColorTexture, 5u}, + {MaterialAttribute::TextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::TextureCoordinates, 2u}, + + /* This is ignored because it doesn't match the texture */ + {MaterialAttribute::DiffuseTextureMatrix, Matrix3::translation({0.5f, 1.0f})}, + {MaterialAttribute::DiffuseTextureCoordinates, 3u} + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(data.hasTextureTransformation()); + CORRADE_VERIFY(data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xccffbb_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3::scaling({0.5f, 1.0f})); + CORRADE_COMPARE(data.textureCoordinates(), 2); +} + +void MaterialDataTest::flatAccessTexturedDiffuseColorSingleMatrixCoordinates() { + FlatMaterialData data{{}, { + {MaterialAttribute::DiffuseColor, 0xccffbbff_rgbaf}, + {MaterialAttribute::DiffuseTexture, 5u}, + {MaterialAttribute::TextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::TextureCoordinates, 2u}, + + /* This is ignored because it doesn't match the texture */ + {MaterialAttribute::BaseColorTextureMatrix, Matrix3::translation({0.5f, 1.0f})}, + {MaterialAttribute::BaseColorTextureCoordinates, 3u} + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(data.hasTextureTransformation()); + CORRADE_VERIFY(data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xccffbb_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3::scaling({0.5f, 1.0f})); + CORRADE_COMPARE(data.textureCoordinates(), 2); +} + +void MaterialDataTest::flatAccessTexturedMismatchedMatrixCoordinates() { + { + FlatMaterialData data{{}, { + {MaterialAttribute::BaseColorTexture, 5u}, + + /* This is ignored because it doesn't match the texture */ + {MaterialAttribute::DiffuseColor, 0x33556600_rgbaf}, + {MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::DiffuseTextureCoordinates, 2u}, + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(!data.hasTextureTransformation()); + CORRADE_VERIFY(!data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xffffff_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3{}); + CORRADE_COMPARE(data.textureCoordinates(), 0); + } { + FlatMaterialData data{{}, { + {MaterialAttribute::DiffuseTexture, 5u}, + + /* This is ignored because it doesn't match the texture */ + {MaterialAttribute::BaseColor, 0x33556600_rgbaf}, + {MaterialAttribute::BaseColorTextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {MaterialAttribute::BaseColorTextureCoordinates, 2u}, + }}; + + CORRADE_VERIFY(data.hasTexture()); + CORRADE_VERIFY(!data.hasTextureTransformation()); + CORRADE_VERIFY(!data.hasTextureCoordinates()); + CORRADE_COMPARE(data.color(), 0xffffff_rgbf); + CORRADE_COMPARE(data.texture(), 5); + CORRADE_COMPARE(data.textureMatrix(), Matrix3{}); + CORRADE_COMPARE(data.textureCoordinates(), 0); + } +} + +void MaterialDataTest::flatAccessInvalidTextures() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + FlatMaterialData data{{}, {}}; + + std::ostringstream out; + Error redirectError{&out}; + data.texture(); + data.textureMatrix(); + data.textureCoordinates(); + CORRADE_COMPARE(out.str(), + "Trade::FlatMaterialData::texture(): the material doesn't have a texture\n" + "Trade::FlatMaterialData::textureMatrix(): the material doesn't have a texture\n" + "Trade::FlatMaterialData::textureCoordinates(): the material doesn't have a texture\n"); +} + void MaterialDataTest::debugAttribute() { std::ostringstream out; diff --git a/src/Magnum/Trade/Trade.h b/src/Magnum/Trade/Trade.h index 9d7fc246b..0b0e07cdd 100644 --- a/src/Magnum/Trade/Trade.h +++ b/src/Magnum/Trade/Trade.h @@ -70,6 +70,8 @@ class CameraData; enum class DataFlag: UnsignedByte; typedef Containers::EnumSet DataFlags; +class FlatMaterialData; + template class ImageData; typedef ImageData<1> ImageData1D; typedef ImageData<2> ImageData2D;