diff --git a/doc/snippets/MagnumTrade.cpp b/doc/snippets/MagnumTrade.cpp index 2e524f8de..5306b5bb5 100644 --- a/doc/snippets/MagnumTrade.cpp +++ b/doc/snippets/MagnumTrade.cpp @@ -40,9 +40,13 @@ #include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/AnimationData.h" #include "Magnum/Trade/ImageData.h" +#include "Magnum/Trade/MaterialData.h" #include "Magnum/Trade/MeshData.h" #include "Magnum/Trade/ObjectData2D.h" #include "Magnum/Trade/MeshObjectData3D.h" +#include "Magnum/Trade/PbrClearCoatMaterialData.h" +#include "Magnum/Trade/PbrSpecularGlossinessMaterialData.h" +#include "Magnum/Trade/PbrMetallicRoughnessMaterialData.h" #include "Magnum/Trade/PhongMaterialData.h" #ifdef MAGNUM_TARGET_GL #include "Magnum/GL/Texture.h" @@ -61,6 +65,8 @@ #include "Magnum/Trade/MeshData3D.h" #endif +#define DOXYGEN_IGNORE(...) __VA_ARGS__ + using namespace Magnum; using namespace Magnum::Math::Literals; @@ -248,6 +254,207 @@ for(auto&& row: data.mutablePixels()) /* [ImageData-usage-mutable] */ } +{ +/* [MaterialAttributeData-name] */ +Trade::MaterialAttributeData a{ + Trade::MaterialAttribute::DiffuseColor, 0x3bd267ff_rgbaf}; +Trade::MaterialAttributeData b{"DiffuseColor", 0x3bd267ff_rgbaf}; +/* [MaterialAttributeData-name] */ +} + +{ +/* [MaterialData-usage] */ +Trade::MaterialData data = DOXYGEN_IGNORE(Trade::MaterialData{{}, {}}); + +// Assumes the attribute exists +Float roughness = data.attribute(Trade::MaterialAttribute::Roughness); + +// Optional access +Color4 color = data.attributeOr(Trade::MaterialAttribute::BaseColor, + 0x3bd267ff_rgbaf); +if(Containers::Optional texture = + data.tryAttribute(Trade::MaterialAttribute::BaseColorTexture)) +{ + // ... +} +/* [MaterialData-usage] */ +static_cast(roughness); +static_cast(color); +} + +{ +Trade::MaterialData data{{}, {}}; +/* [MaterialData-usage-types] */ +/* Prefer a specular/roughness workflow, if present */ +if(data.types() & Trade::MaterialType::PbrSpecularGlossiness) { + const auto& pbr = data.as(); + + Color4 diffuse = pbr.diffuseColor(); + Color4 specular = pbr.specularColor(); + Float glossiness = pbr.glossiness(); + + DOXYGEN_IGNORE(static_cast(diffuse), static_cast(specular), static_cast(glossiness);) + +/* Otherwise use metallic/roughness (or defaults if no attributes present) */ +} else { + const auto& pbr = data.as(); + + Color4 base = pbr.baseColor(); + Float metalness = pbr.metalness(); + Float roughness = pbr.roughness(); + + DOXYGEN_IGNORE(static_cast(base), static_cast(metalness), static_cast(roughness);) +} +/* [MaterialData-usage-types] */ +} + +{ +/* [MaterialData-usage-packing] */ +Trade::PbrMetallicRoughnessMaterialData data = DOXYGEN_IGNORE(Trade::PbrMetallicRoughnessMaterialData{{}, {}}); + +/* Use a shader that accepts a single packed metallic/roughness texture. + Querying any texture attributes will give the same values for both metalness + and roughness. */ +if(data.hasMetallicRoughnessTexture()) { + UnsignedInt metallicRoughness = data.metalnessTexture(); + + DOXYGEN_IGNORE(static_cast(metallicRoughness);) + +/* Supply texture channels separately */ +} else { + UnsignedInt metalness = data.metalnessTexture(); + UnsignedInt roughness = data.roughnessTexture(); + Trade::MaterialTextureSwizzle metalnessSwizzle = data.metalnessTextureSwizzle(); + Trade::MaterialTextureSwizzle roughnessSwizzle = data.roughnessTextureSwizzle(); + + DOXYGEN_IGNORE(static_cast(metalness), static_cast(roughness), static_cast(metalnessSwizzle), static_cast(roughnessSwizzle);) +} +/* [MaterialData-usage-packing] */ +} + +{ +Trade::MaterialData data{{}, {}}; +/* [MaterialData-usage-layers] */ +if(data.hasLayer(Trade::MaterialLayer::ClearCoat)) { + Float clearCoatFactor = data.attributeOr(Trade::MaterialLayer::ClearCoat, + Trade::MaterialAttribute::LayerFactor, 1.0f); + Float clearCoatRoughness = data.attributeOr(Trade::MaterialLayer::ClearCoat, + Trade::MaterialAttribute::Roughness, 0.0f); + + DOXYGEN_IGNORE(static_cast(clearCoatFactor), static_cast(clearCoatRoughness);) +} +/* [MaterialData-usage-layers] */ +} + +{ +Trade::MaterialData data{{}, {}}; +/* [MaterialData-usage-layers-types] */ +if(data.types() & Trade::MaterialType::PbrClearCoat) { + const auto& clearCoat = data.as(); + + Float clearCoatFactor = clearCoat.layerFactor(); + Float clearCoatRoughness = clearCoat.roughness(); + + DOXYGEN_IGNORE(static_cast(clearCoatFactor), static_cast(clearCoatRoughness);) +} +/* [MaterialData-usage-layers-types] */ +} + +{ +/* [MaterialData-populating] */ +Trade::MaterialData data{Trade::MaterialType::PbrMetallicRoughness, { + {Trade::MaterialAttribute::DoubleSided, true}, + {Trade::MaterialAttribute::BaseColor, 0x3bd267ff_srgbaf}, + {Trade::MaterialAttribute::BaseColorTexture, 17u}, + {Trade::MaterialAttribute::TextureMatrix, Matrix3::scaling({0.5f, 1.0f})} +}}; +/* [MaterialData-populating] */ +} + +{ +/* [MaterialData-populating-non-owned] */ +using namespace Containers::Literals; + +constexpr Trade::MaterialAttributeData attributes[]{ + {"DoubleSided"_s, true}, + {"BaseColor"_s, Color4{0.043735f, 0.64448f, 0.135633f, 1.0f}}, + {"BaseColorTexture"_s, 5u}, + {"TextureMatrix"_s, Matrix3{{0.5f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}}} +}; + +Trade::MaterialData data{Trade::MaterialType::Phong, {}, attributes}; +/* [MaterialData-populating-non-owned] */ +} + +#ifdef MAGNUM_TARGET_GL +{ +GL::Texture2D baseColorTexture; +/* [MaterialData-populating-custom] */ +Trade::MaterialData data{Trade::MaterialType::PbrMetallicRoughness, { + {Trade::MaterialAttribute::BaseColor, 0x3bd267ff_srgbaf}, + {Trade::MaterialAttribute::TextureMatrix, Matrix3::scaling({0.5f, 1.0f})}, + {"baseColorTexturePointer", &baseColorTexture}, + {"highlightColor", 0x00ffff_srgbf}, + {"name", "Canary Green Plastic, really ugly"} +}}; + +// Retrieving the texture pointer +GL::Texture2D* texture = data.attribute("baseColorTexturePointer"); +/* [MaterialData-populating-custom] */ +static_cast(texture); +} +#endif + +{ +/* [MaterialData-populating-layers] */ +Trade::MaterialData data{ + Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrClearCoat, + { + {Trade::MaterialAttribute::BaseColor, 0xffcc33_srgbf}, + {Trade::MaterialAttribute::MetallicRoughnessTexture, 0u}, + + {Trade::MaterialLayer::ClearCoat}, + {Trade::MaterialAttribute::LayerFactorTexture, 1u}, + {Trade::MaterialAttribute::RoughnessTexture, 1u}, + {Trade::MaterialAttribute::RoughnessTextureSwizzle, + Trade::MaterialTextureSwizzle::G} + }, + + {2, 6} +}; +/* [MaterialData-populating-layers] */ +} + +{ +UnsignedInt a, b, c, d, sandTile, grassTile, rockTile; +/* [MaterialData-populating-layers-custom] */ +Trade::MaterialData proceduralLandscape{ + Trade::MaterialTypes{}, // Doesn't match any builtin material type + { + // Rock layer + {Trade::MaterialAttribute::LayerFactorTexture, a}, + {Trade::MaterialAttribute::BaseColorTexture, rockTile}, + + // Sand layer + {Trade::MaterialAttribute::LayerFactorTexture, b}, + {"blendType", "mix"}, + {Trade::MaterialAttribute::BaseColorTexture, sandTile}, + + // Grass layer + {Trade::MaterialAttribute::LayerFactorTexture, c}, + {"blendType", "overlay"}, + {"strandLengthTexture", d}, + {Trade::MaterialAttribute::BaseColorTexture, grassTile}, + }, + + // There's no base material, everything is in layers + {0, 2, 5, 9} +}; +/* [MaterialData-populating-layers-custom] */ +} + { /* [MeshIndexData-usage] */ Containers::ArrayView indices; diff --git a/src/Magnum/Trade/FlatMaterialData.h b/src/Magnum/Trade/FlatMaterialData.h index 88be29535..eb5b4ff18 100644 --- a/src/Magnum/Trade/FlatMaterialData.h +++ b/src/Magnum/Trade/FlatMaterialData.h @@ -38,8 +38,12 @@ namespace Magnum { namespace Trade { @brief Flat material data @m_since_latest -@see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData, - @ref PbrSpecularGlossinessMaterialData, @ref PhongMaterialData +See @ref Trade-MaterialData-usage-types for more information about how to use +this class. +@see @ref AbstractImporter::material(), @ref PhongMaterialData, + @ref PbrMetallicRoughnessMaterialData, + @ref PbrSpecularGlossinessMaterialData, @ref PbrClearCoatMaterialData, + @ref MaterialType::Flat */ class MAGNUM_TRADE_EXPORT FlatMaterialData: public MaterialData { public: diff --git a/src/Magnum/Trade/MaterialData.h b/src/Magnum/Trade/MaterialData.h index 9b5dd48d0..5f6e99148 100644 --- a/src/Magnum/Trade/MaterialData.h +++ b/src/Magnum/Trade/MaterialData.h @@ -1341,8 +1341,168 @@ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, MaterialAlphaMode value); @brief Material data @m_since_latest -Key-value store for material attributes in one of the types defined by -@ref MaterialAttributeType. +Key-value store for builtin as well as custom material attributes, with an +ability to define additional layers further affecting the base material. +Populated instances of this class are returned from +@ref AbstractImporter::material(). + +@section Trade-MaterialData-usage Usage + +The simplest usage is through templated @ref attribute() functions, which take +a string attribute name or one of the pre-defined @ref MaterialAttribute +values. You're expected to check for attribute presence first with +@ref hasAttribute(), and the requested type has to match @ref attributeType(). +To make things easier, each of the attributes defined in @ref MaterialAttribute +has a strictly defined type, so you can safely assume the type when requesting +those. In addition there's @ref tryAttribute() and @ref attributeOr() that +return a @ref Containers::NullOpt or a default value in case given attribute is +not found. + +@snippet MagnumTrade.cpp MaterialData-usage + +It's also possible to iterate through all attributes using @ref attributeName(), +@ref attributeType() and @ref attribute() taking indices instead of names, with +@ref attributeCount() returning the total attribute count. + +@subsection Trade-MaterialData-usage-types Material types and cnvenience accessors + +A material usually consists of a set of attributes for a particular rendering +workflow --- PBR metallic/roughness, Phong or for example flat-shaded +materials. To hint what the material contains, @ref types() returns a set of +@ref MaterialType values. It's not just a single value as the data can define +attributes for more than one material type (for example both metallic/roughness +and specular/glossiness PBR workflow), allowing the application to pick the +best type for a particular use case. + +Because retrieving everything through the @ref attribute() APIs can get verbose +and complex, the @ref Trade library provides a set of accessor APIs for common +material types such as @ref FlatMaterialData, @ref PhongMaterialData, +@ref PbrMetallicRoughnessMaterialData or @ref PbrSpecularGlossinessMaterialData. +Using @ref as() you can convert any @ref MaterialData instance to a reference +to one of those. These convenience APIs then take care of default values when +an attribute isn't present or handle fallbacks when an attribute can be defined +in multiple ways: + +@snippet MagnumTrade.cpp MaterialData-usage-types + +Each @ref MaterialAttribute is exposed through one or more of those convenience +APIs, see the documentation of of a particular enum value for more information. + +@subsection Trade-MaterialData-usage-packing Texture packing + +Especially for single- and two-channel texture maps it's common to have more +than one map packed into a single texture. Such packing is expressed through +various @ref MaterialTextureSwizzle attributes such as +@ref MaterialAttribute::MetalnessTextureSwizzle. While this provides an almost +endless variability, real-world textures are in just a few common packing +schemes. For convenience these have dedicated attributes such as +@ref MaterialAttribute::MetallicRoughnessTexture and can also be checked for +with for example @ref PbrMetallicRoughnessMaterialData::hasMetallicRoughnessTexture(): + +@snippet MagnumTrade.cpp MaterialData-usage-packing + +@subsection Trade-MaterialData-usage-layers Material layers + +In addition to the base material, there can be material layers. While a +material attribute can be specified only once for a particular layer, multiple +layers can use the same attribute name for different purpose. Layers are +commonly used in PBR workflows to describe lacquered wood, metallic paint or +for example a thin film on leather surfaces. You can enumerate and query layers +using @ref layerCount(), @ref layerName() and @ref hasLayer(), layer-specific +attributes are retrieved by passing layer ID or name as the first parameter to +the @ref attribute() family of APIs. + +For each layer there can be predefined @ref layerFactor(), +@ref layerFactorTexture() and other texture-related attributes which define how +much the layer affects the underlying material, but the exact semantics of how +the factor is applied is left to the layer implementation. + +Here's an example showing retrieval of a clear coat layer parameters, if +present: + +@snippet MagnumTrade.cpp MaterialData-usage-layers + +Like with base material attributes, builtin layers also have convenience +accessor APIs. The above can be written in a more compact way using +@link PbrClearCoatMaterialData @endlink: + +@snippet MagnumTrade.cpp MaterialData-usage-layers-types + +@section Trade-MaterialData-populating Populating an instance + +A @ref MaterialData instance by default takes over ownership of an +@ref Corrade::Containers::Array containing @ref MaterialAttributeData +instances, together with @ref MaterialTypes suggesting available material types +(or an empty set, in case of a fully custom material). Attribute values can be +in one of the types from @ref MaterialAttributeType, and the type is in most +cases inferred implicitly. The class internally uses strings for attribute +names, but you're encouraged to use the predefined names from +@ref MaterialAttribute --- with those, the attribute gets checked additionally +that it's in an expected type. Attribute order doesn't matter, the array gets +internally sorted by name to allow a @f$ \mathcal{O}(\log n) @f$ lookup. + +@snippet MagnumTrade.cpp MaterialData-populating + +In addition to passing ownership of an array it's also possible to have the +@ref MaterialData instance refer to external data (for example in a +memory-mapped file, constant memory etc.). The additional second argument is +@ref DataFlags that's used only for safely disambiguating from the owning +constructor, and you'll pass a @ref Corrade::Containers::ArrayView instead of +an @ref Corrade::Containers::Array. Note that in this case, since the attribute +data is treated as immutable, you *have to* ensure the list is sorted by name. + +@snippet MagnumTrade.cpp MaterialData-populating-non-owned + + + +@m_class{m-note m-info} + +@par + Additionally, as shown above, in order to create a @cpp constexpr @ce + @ref MaterialAttributeData array, you need to use + @ref Corrade::Containers::StringView literals instead of plain C strings + or the @ref MaterialAttribute enum, and be sure to call only + @cpp constexpr @ce-enabled constructors of stored data types. + +@subsection Trade-MaterialData-populating-custom Custom material attributes + +While attribute names beginning with uppercase letters are reserved for builtin +Magnum attributes, anything beginning with a lowercase letter can be a custom +attribute. For greater flexibility, custom attributes can be also strings or +pointers, allowing you to store arbitrary properties or direct texture pointers +instead of IDs: + +@snippet MagnumTrade.cpp MaterialData-populating-custom + +@subsection Trade-MaterialData-populating-layers Adding material layers + +Material layers are internally represented as ranges of the attribute array and +by default the whole attribute array is treated as a base material. The actual +split into layers can be described using an additionaly offset array passed to +@ref MaterialData(MaterialTypes, Containers::Array&&, Containers::Array&&, const void*), +where entry *i* specifies the end offset of layer *i* --- in the following +snippet we have two layers (one base material and one clear coat layer), the +base material being the first two attributes and the clear coat layer being +attributes in range @cpp 2 @ce to @cpp 6 @ce (thus four attributes): + +@snippet MagnumTrade.cpp MaterialData-populating-layers + +Like with just a base material, the attributes get sorted for a +@f$ \mathcal{O}(\log n) @f$ lookup --- but not as a whole, each layer +separately. In contrary, because layer order matters, those are not reordered +(and thus their lookup is @f$ \mathcal{O}(n) @f$, however it isn't expected to +have that many layers for this to matter). The layers can be named by supplying +a @ref MaterialAttribute::LayerName attribute (or, like shown above, by using +the convenience @ref MaterialAttributeData::MaterialAttributeData(MaterialLayer) +constructor) but don't have to --- if a layer doesn't have a name, it can be +only looked up by its index, not by a name. + +Apart from builtin layers, there's no limit in what the layers can be used for +--- the data can for example describe a completely custom landscape from a set +of authored `rockTile`, `sandTile`, `grassTile` textures and procedurally +generated blend factors `a`, `b`, `c`, `d`: + +@snippet MagnumTrade.cpp MaterialData-populating-layers-custom @section Trade-MaterialData-representation Internal representation @@ -1923,16 +2083,16 @@ class MAGNUM_TRADE_EXPORT MaterialData { * The @p layer is expected to be smaller than @ref layerCount() const * and @p id is expected to be smaller than @ref attributeCount(UnsignedInt) const * in that layer. Cast the pointer to a concrete type based on - * @ref type(). Note that in case of a - * @ref MaterialAttributeType::Pointer or a - * @ref MaterialAttributeType::MutablePointer, returns a - * *pointer to a pointer*, not the pointer value itself. + * @ref type(). * - * In case of a @ref MaterialAttributeType::String returns a - * null-terminated @cpp const char* @ce (not a pointer to - * @ref Containers::StringView). This doesn't preserve the actual - * string size in case the string data contain zero bytes, thus prefer - * to use typed access in that case. + * - In case of a @ref MaterialAttributeType::Pointer or a + * @ref MaterialAttributeType::MutablePointer, returns a + * *pointer to a pointer*, not the pointer value itself. + * - In case of a @ref MaterialAttributeType::String returns a + * null-terminated @cpp const char* @ce (not a pointer to + * @ref Containers::StringView). This doesn't preserve the actual + * string size in case the string data contain zero bytes, thus + * prefer to use typed access in that case. */ const void* attribute(UnsignedInt layer, UnsignedInt id) const; @@ -1941,16 +2101,17 @@ class MAGNUM_TRADE_EXPORT MaterialData { * * The @p layer is expected to be smaller than @ref layerCount() const * and @p name is expected to exist in that layer. Cast the pointer to - * a concrete type based on @ref attributeType(). Note that - * in case of a @ref MaterialAttributeType::Pointer or a - * @ref MaterialAttributeType::MutablePointer, returns a - * *pointer to a pointer*, not the pointer value itself. + * a concrete type based on @ref attributeType(). + * + * - In case of a @ref MaterialAttributeType::Pointer or a + * @ref MaterialAttributeType::MutablePointer, returns a + * *pointer to a pointer*, not the pointer value itself. + * - In case of a @ref MaterialAttributeType::String returns a + * null-terminated @cpp const char* @ce (not a pointer to + * @ref Containers::StringView). This doesn't preserve the actual + * string size in case the string data contain zero bytes, thus prefer + * to use typed access in that case. * - * In case of a @ref MaterialAttributeType::String returns a - * null-terminated @cpp const char* @ce (not a pointer to - * @ref Containers::StringView). This doesn't preserve the actual - * string size in case the string data contain zero bytes, thus prefer - * to use typed access in that case. * @see @ref hasAttribute(), @ref tryAttribute(), @ref attributeOr() */ const void* attribute(UnsignedInt layer, Containers::StringView name) const; @@ -1961,16 +2122,17 @@ class MAGNUM_TRADE_EXPORT MaterialData { * * The @p layer is expected to exist and the @p id is expected to be smaller than @ref attributeCount(UnsignedInt) const * in that layer. Cast the pointer to a concrete type based on - * @ref attributeType(). Note that in case of a - * @ref MaterialAttributeType::Pointer or a - * @ref MaterialAttributeType::MutablePointer, returns a - * *pointer to a pointer*, not the pointer value itself. + * @ref attributeType(). + * + * - In case of a @ref MaterialAttributeType::Pointer or a + * @ref MaterialAttributeType::MutablePointer, returns a + * *pointer to a pointer*, not the pointer value itself. + * - In case of a @ref MaterialAttributeType::String returns a + * null-terminated @cpp const char* @ce (not a pointer to + * @ref Containers::StringView). This doesn't preserve the actual + * string size in case the string data contain zero bytes, thus prefer + * to use typed access in that case. * - * In case of a @ref MaterialAttributeType::String returns a - * null-terminated @cpp const char* @ce (not a pointer to - * @ref Containers::StringView). This doesn't preserve the actual - * string size in case the string data contain zero bytes, thus prefer - * to use typed access in that case. * @see @ref hasLayer() */ const void* attribute(Containers::StringView layer, UnsignedInt id) const; @@ -1981,16 +2143,17 @@ class MAGNUM_TRADE_EXPORT MaterialData { * * The @p layer is expected to exist and @p name is expected to exist * in that layer. Cast the pointer to a concrete type based on - * @ref attributeType(). Note that in case of a - * @ref MaterialAttributeType::Pointer or a - * @ref MaterialAttributeType::MutablePointer, returns a - * *pointer to a pointer*, not the pointer value itself. + * @ref attributeType(). + * + * - In case of a @ref MaterialAttributeType::Pointer or a + * @ref MaterialAttributeType::MutablePointer, returns a + * *pointer to a pointer*, not the pointer value itself. + * - In case of a @ref MaterialAttributeType::String returns a + * null-terminated @cpp const char* @ce (not a pointer to + * @ref Containers::StringView). This doesn't preserve the actual + * string size in case the string data contain zero bytes, thus + * prefer to use typed access in that case. * - * In case of a @ref MaterialAttributeType::String returns a - * null-terminated @cpp const char* @ce (not a pointer to - * @ref Containers::StringView). This doesn't preserve the actual - * string size in case the string data contain zero bytes, thus prefer - * to use typed access in that case. * @see @ref hasLayer(), @ref hasAttribute() */ const void* attribute(Containers::StringView layer, Containers::StringView name) const; diff --git a/src/Magnum/Trade/MaterialLayerData.h b/src/Magnum/Trade/MaterialLayerData.h index b0dad741f..d2ef55b72 100644 --- a/src/Magnum/Trade/MaterialLayerData.h +++ b/src/Magnum/Trade/MaterialLayerData.h @@ -41,7 +41,8 @@ namespace Magnum { namespace Trade { Convenience wrapper that re-routes all @ref MaterialData base material layer and attribute accessors APIS from to a layer specified in the @p layer template -parameter. All APIs expect that given layer exists. +parameter. All APIs expect that given layer exists. See +@ref Trade-MaterialData-usage-layers for more information. */ template class MaterialLayerData: public MaterialData { public: diff --git a/src/Magnum/Trade/PbrClearCoatMaterialData.h b/src/Magnum/Trade/PbrClearCoatMaterialData.h index be3a0c145..0a43f179f 100644 --- a/src/Magnum/Trade/PbrClearCoatMaterialData.h +++ b/src/Magnum/Trade/PbrClearCoatMaterialData.h @@ -39,8 +39,11 @@ namespace Magnum { namespace Trade { @m_since_latest Exposes properties of a @ref MaterialLayer::ClearCoat layer. All APIs expect -that the layer is present in the material. -@see @ref AbstractImporter::material(), @ref MaterialType::PbrClearCoat +that the layer is present in the material. See @ref Trade-MaterialData-usage-types +for more information about how to use this class. +@see @ref AbstractImporter::material(), @ref FlatMaterialData, + @ref PhongMaterialData, @ref PbrMetallicRoughnessMaterialData, + @ref PbrSpecularGlossinessMaterialData, @ref MaterialType::PbrClearCoat */ class MAGNUM_TRADE_EXPORT PbrClearCoatMaterialData: public MaterialLayerData { public: diff --git a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h index 97e7b33bf..3e271a08a 100644 --- a/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h +++ b/src/Magnum/Trade/PbrMetallicRoughnessMaterialData.h @@ -38,8 +38,11 @@ namespace Magnum { namespace Trade { @brief PBR metallic/roughness material data @m_since_latest -@see @ref AbstractImporter::material(), @ref PbrSpecularGlossinessMaterialData, - @ref PhongMaterialData, @ref FlatMaterialData +See @ref Trade-MaterialData-usage-types for more information about how to use +this class. +@see @ref AbstractImporter::material(), @ref FlatMaterialData, + @ref PhongMaterialData, @ref PbrSpecularGlossinessMaterialData, + @ref PbrClearCoatMaterialData, @ref MaterialType::PbrMetallicRoughness */ class MAGNUM_TRADE_EXPORT PbrMetallicRoughnessMaterialData: public MaterialData { public: diff --git a/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h b/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h index 420c02e4b..edc5c4bad 100644 --- a/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h +++ b/src/Magnum/Trade/PbrSpecularGlossinessMaterialData.h @@ -38,8 +38,11 @@ namespace Magnum { namespace Trade { @brief PBR specular/glossiness material data @m_since_latest -@see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData, - @ref PhongMaterialData, @ref FlatMaterialData +See @ref Trade-MaterialData-usage-types for more information about how to use +this class. +@see @ref AbstractImporter::material(), @ref PhongMaterialData, + @ref FlatMaterialData, @ref PbrMetallicRoughnessMaterialData, + @ref PbrClearCoatMaterialData, @ref MaterialType::PbrSpecularGlossiness */ class MAGNUM_TRADE_EXPORT PbrSpecularGlossinessMaterialData: public MaterialData { public: diff --git a/src/Magnum/Trade/PhongMaterialData.h b/src/Magnum/Trade/PhongMaterialData.h index c436b88a2..fe24f7530 100644 --- a/src/Magnum/Trade/PhongMaterialData.h +++ b/src/Magnum/Trade/PhongMaterialData.h @@ -37,8 +37,11 @@ namespace Magnum { namespace Trade { /** @brief Phong material data -@see @ref AbstractImporter::material(), @ref PbrMetallicRoughnessMaterialData, - @ref PbrSpecularGlossinessMaterialData, @ref FlatMaterialData +See @ref Trade-MaterialData-usage-types for more information about how to use +this class. +@see @ref AbstractImporter::material(), @ref FlatMaterialData, + @ref PbrMetallicRoughnessMaterialData, + @ref PbrSpecularGlossinessMaterialData, @ref PbrClearCoatMaterialData */ class MAGNUM_TRADE_EXPORT PhongMaterialData: public MaterialData { public: