Browse Source

MaterialTools: new library.

Currently contains just one very silly Phong->PBR conversion utility,
but eventually it'll provide tools for simplifying, merging and
deduplicating materials.
pull/605/head
Vladimír Vondruš 4 years ago
parent
commit
7f24d00553
  1. 3
      CMakeLists.txt
  2. 6
      doc/building.dox
  3. 5
      doc/changelog.dox
  4. 1
      doc/cmake.dox
  5. 3
      doc/custom-buildsystems-order.dot
  6. 24
      doc/namespaces.dox
  7. 11
      modules/FindMagnum.cmake
  8. 1
      package/ci/android-x86-vulkan.sh
  9. 1
      package/ci/appveyor-desktop-gles.bat
  10. 1
      package/ci/unix-desktop-gles.sh
  11. 1
      package/ci/unix-desktop-vulkan.sh
  12. 4
      src/Magnum/CMakeLists.txt
  13. 98
      src/Magnum/MaterialTools/CMakeLists.txt
  14. 166
      src/Magnum/MaterialTools/PhongToPbrMetallicRoughness.cpp
  15. 124
      src/Magnum/MaterialTools/PhongToPbrMetallicRoughness.h
  16. 31
      src/Magnum/MaterialTools/Test/CMakeLists.txt
  17. 313
      src/Magnum/MaterialTools/Test/PhongToPbrMetallicRoughnessTest.cpp
  18. 49
      src/Magnum/MaterialTools/visibility.h

3
CMakeLists.txt

@ -205,6 +205,7 @@ cmake_dependent_option(MAGNUM_WITH_TGAIMPORTER "Build TgaImporter plugin" OFF "N
# Parts of the library
cmake_dependent_option(MAGNUM_WITH_AUDIO "Build Audio library" OFF "NOT MAGNUM_WITH_AL_INFO;NOT MAGNUM_WITH_ANYAUDIOIMPORTER;NOT MAGNUM_WITH_WAVAUDIOIMPORTER" ON)
option(MAGNUM_WITH_DEBUGTOOLS "Build DebugTools library" ON)
option(MAGNUM_WITH_MATERIALTOOLS "Build MaterialTools library" ON)
cmake_dependent_option(MAGNUM_WITH_MESHTOOLS "Build MeshTools library" ON "NOT MAGNUM_WITH_OBJIMPORTER;NOT MAGNUM_WITH_SCENECONVERTER" ON)
option(MAGNUM_WITH_SCENEGRAPH "Build SceneGraph library" ON)
cmake_dependent_option(MAGNUM_WITH_SCENETOOLS "Build SceneTools library" ON "NOT MAGNUM_WITH_SCENECONVERTER" ON)
@ -212,7 +213,7 @@ option(MAGNUM_WITH_SHADERS "Build Shaders library" ON)
cmake_dependent_option(MAGNUM_WITH_SHADERTOOLS "Build ShaderTools library" ON "NOT MAGNUM_WITH_SHADERCONVERTER" ON)
cmake_dependent_option(MAGNUM_WITH_TEXT "Build Text library" ON "NOT MAGNUM_WITH_FONTCONVERTER;NOT MAGNUM_WITH_MAGNUMFONT;NOT MAGNUM_WITH_MAGNUMFONTCONVERTER" ON)
cmake_dependent_option(MAGNUM_WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT MAGNUM_WITH_TEXT;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
cmake_dependent_option(MAGNUM_WITH_TRADE "Build Trade library" ON "NOT MAGNUM_WITH_MESHTOOLS;NOT MAGNUM_WITH_PRIMITIVES;NOT MAGNUM_WITH_SCENETOOLS;NOT MAGNUM_WITH_IMAGECONVERTER;NOT MAGNUM_WITH_ANYIMAGEIMPORTER;NOT MAGNUM_WITH_ANYIMAGECONVERTER;NOT MAGNUM_WITH_ANYSCENEIMPORTER;NOT MAGNUM_WITH_OBJIMPORTER;NOT MAGNUM_WITH_TGAIMAGECONVERTER;NOT MAGNUM_WITH_TGAIMPORTER" ON)
cmake_dependent_option(MAGNUM_WITH_TRADE "Build Trade library" ON "NOT MAGNUM_WITH_MATERIALTOOLS;NOT MAGNUM_WITH_MESHTOOLS;NOT MAGNUM_WITH_PRIMITIVES;NOT MAGNUM_WITH_SCENETOOLS;NOT MAGNUM_WITH_IMAGECONVERTER;NOT MAGNUM_WITH_ANYIMAGEIMPORTER;NOT MAGNUM_WITH_ANYIMAGECONVERTER;NOT MAGNUM_WITH_ANYSCENEIMPORTER;NOT MAGNUM_WITH_OBJIMPORTER;NOT MAGNUM_WITH_TGAIMAGECONVERTER;NOT MAGNUM_WITH_TGAIMPORTER" ON)
cmake_dependent_option(MAGNUM_WITH_GL "Build GL library" ON "NOT MAGNUM_WITH_SHADERS;NOT MAGNUM_WITH_GL_INFO;NOT MAGNUM_WITH_ANDROIDAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSIOSAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSCGLAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSGLXAPPLICATION;NOT MAGNUM_WITH_CGLCONTEXT;NOT MAGNUM_WITH_GLXAPPLICATION;NOT MAGNUM_WITH_GLXCONTEXT;NOT MAGNUM_WITH_XEGLAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSWGLAPPLICATION;NOT MAGNUM_WITH_WGLCONTEXT;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
option(MAGNUM_WITH_PRIMITIVES "Build Primitives library" ON)

6
doc/building.dox

@ -484,6 +484,8 @@ can specify which parts will be built and which not:
- `MAGNUM_WITH_DEBUGTOOLS` --- Build the @ref DebugTools library.
- `MAGNUM_WITH_GL` --- Build the @ref GL library. Enabled automatically if
`MAGNUM_WITH_SHADERS` is enabled.
- `MAGNUM_WITH_MATERIALTOOLS` --- Build the @ref MaterialTools library.
Enables also building of the @ref Trade library.
- `MAGNUM_WITH_MESHTOOLS` --- Build the @ref MeshTools library. Enables also
building of the @ref Trade library.
- `MAGNUM_WITH_PRIMITIVES` --- Build the @ref Primitives library. Enables
@ -500,8 +502,8 @@ can specify which parts will be built and which not:
automatically if `MAGNUM_WITH_TEXT` or `MAGNUM_WITH_DISTANCEFIELDCONVERTER`
is enabled.
- `MAGNUM_WITH_TRADE` --- Build the @ref Trade library. Enabled automatically
if `MAGNUM_WITH_MESHTOOLS`, `MAGNUM_WITH_PRIMITIVES`
or `MAGNUM_WITH_SCENETOOLS` is enabled.
if `MAGNUM_WITH_MATERIALTOOLS`, `MAGNUM_WITH_MESHTOOLS`,
`MAGNUM_WITH_PRIMITIVES` or `MAGNUM_WITH_SCENETOOLS` is enabled.
- `MAGNUM_WITH_VK` --- Build the @ref Vk library. Depends on Vulkan, not
enabled by default.

5
doc/changelog.dox

@ -184,6 +184,11 @@ See also:
over trivial code but easier to discover
- Added an unary @cpp operator+() @ce to all @ref Math classes
@subsubsection changelog-latest-new-materialtools MaterialTools library
- New @ref MaterialTools library providing various material conversion
utilities
@subsubsection changelog-latest-new-meshtools MeshTools library
- New @ref MeshTools::boundingSphereBouncingBubble() algorithm for

1
doc/cmake.dox

@ -193,6 +193,7 @@ the components. The optional components are:
- `Audio` --- @ref Audio library
- `DebugTools` --- @ref DebugTools library
- `GL` -- @ref GL library
- `MaterialTools` --- @ref MaterialTools library
- `MeshTools` --- @ref MeshTools library
- `Primitives` --- @ref Primitives library
- `SceneGraph` --- @ref SceneGraph library

3
doc/custom-buildsystems-order.dot

@ -40,6 +40,7 @@ digraph "Magnum library dependency order" {
MagnumDebugTools [label="Magnum\nDebugTools" class="m-info"]
MagnumGL [label="Magnum\nGL" class="m-info"]
MagnumMath [label="Magnum\nMath" class="m-primary" style=dotted]
MagnumMaterialTools [label="Magnum\nMaterialTools" class="m-info"]
MagnumMeshTools [label="Magnum\nMeshTools" class="m-info"]
MagnumOpenGLTester [label="Magnum\nOpenGLTester" class="m-info"]
MagnumPrimitives [label="Magnum\nPrimitives" class="m-info"]
@ -76,6 +77,8 @@ digraph "Magnum library dependency order" {
MagnumGL -> Magnum
MagnumMaterialTools -> MagnumTrade
MagnumMeshTools -> MagnumTrade
MagnumMeshTools -> MagnumGL [style=dotted]

24
doc/namespaces.dox

@ -351,6 +351,30 @@ See @ref building, @ref cmake and @ref opengl for more information.
requires attribution for public use.
*/
/** @dir Magnum/MaterialTools
* @brief Namespace @ref Magnum::MaterialTools
* @m_since_latest
*/
/** @namespace Magnum::MaterialTools
@brief Material tools
@m_since_latest
Tools for converting materials.
This library is built if `MAGNUM_WITH_MATERIALTOOLS` is enabled when building
Magnum. To use this library with CMake, request the `MaterialTools` component
of the `Magnum` package and link to the `Magnum::MaterialTools` target:
@code{.cmake}
find_package(Magnum REQUIRED MaterialTools)
# ...
target_link_libraries(your-app PRIVATE Magnum::MaterialTools)
@endcode
See @ref building and @ref cmake for more information.
*/
/** @dir Magnum/MeshTools
* @brief Namespace @ref Magnum::MeshTools
*/

11
modules/FindMagnum.cmake

@ -57,6 +57,7 @@
# Audio - Audio library
# DebugTools - DebugTools library
# GL - GL library
# MaterialTools - MaterialTools library
# MeshTools - MeshTools library
# Primitives - Primitives library
# SceneGraph - SceneGraph library
@ -367,8 +368,8 @@ endif()
# Component distinction (listing them explicitly to avoid mistakes with finding
# components from other repositories)
set(_MAGNUM_LIBRARY_COMPONENTS
Audio DebugTools GL MeshTools Primitives SceneGraph SceneTools Shaders
ShaderTools Text TextureTools Trade
Audio DebugTools GL MaterialTools MeshTools Primitives SceneGraph
SceneTools Shaders ShaderTools Text TextureTools Trade
WindowlessEglApplication EglContext OpenGLTester)
set(_MAGNUM_PLUGIN_COMPONENTS
AnyAudioImporter AnyImageConverter AnyImageImporter AnySceneConverter
@ -432,6 +433,8 @@ if(MAGNUM_TARGET_GL)
set(_MAGNUM_DebugTools_GL_DEPENDENCY_IS_OPTIONAL ON)
endif()
set(_MAGNUM_MaterialTools_DEPENDENCIES Trade)
set(_MAGNUM_MeshTools_DEPENDENCIES Trade)
if(MAGNUM_TARGET_GL)
list(APPEND _MAGNUM_MeshTools_DEPENDENCIES GL)
@ -883,6 +886,10 @@ foreach(_component ${Magnum_FIND_COMPONENTS})
INTERFACE_LINK_LIBRARIES OpenGLES3::OpenGLES3)
endif()
# MaterialTools library
elseif(_component STREQUAL MaterialTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES PhongToPbrMetallicRoughness.h)
# MeshTools library
elseif(_component STREQUAL MeshTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES CompressIndices.h)

1
package/ci/android-x86-vulkan.sh

@ -62,6 +62,7 @@ cmake .. \
`# Needed by VkMeshVkTest, together with TgaImporter and AnyImageImporter` \
-DMAGNUM_WITH_DEBUGTOOLS=ON \
-DMAGNUM_WITH_GL=OFF \
-DMAGNUM_WITH_MATERIALTOOLS=OFF \
-DMAGNUM_WITH_MESHTOOLS=OFF \
-DMAGNUM_WITH_PRIMITIVES=OFF \
-DMAGNUM_WITH_SCENEGRAPH=OFF \

1
package/ci/appveyor-desktop-gles.bat

@ -29,6 +29,7 @@ cmake .. ^
-DMAGNUM_TARGET_GLES2=%TARGET_GLES2% ^
-DMAGNUM_TARGET_EGL=OFF ^
-DMAGNUM_WITH_AUDIO=OFF ^
-DMAGNUM_WITH_MATERIALTOOLS=OFF ^
-DMAGNUM_WITH_SCENETOOLS=OFF ^
-DMAGNUM_WITH_SHADERTOOLS=OFF ^
-DMAGNUM_WITH_VK=OFF ^

1
package/ci/unix-desktop-gles.sh

@ -25,6 +25,7 @@ cmake .. \
-DMAGNUM_TARGET_GLES=ON \
-DMAGNUM_TARGET_GLES2=$TARGET_GLES2 \
-DMAGNUM_WITH_AUDIO=OFF \
-DMAGNUM_WITH_MATERIALTOOLS=OFF \
-DMAGNUM_WITH_SCENETOOLS=OFF \
-DMAGNUM_WITH_SHADERTOOLS=OFF \
-DMAGNUM_WITH_VK=OFF \

1
package/ci/unix-desktop-vulkan.sh

@ -35,6 +35,7 @@ cmake .. \
`# Needed by VkMeshVkTest, together with TgaImporter and AnyImageImporter` \
-DMAGNUM_WITH_DEBUGTOOLS=ON \
-DMAGNUM_WITH_GL=OFF \
-DMAGNUM_WITH_MATERIALTOOLS=OFF \
-DMAGNUM_WITH_MESHTOOLS=OFF \
-DMAGNUM_WITH_PRIMITIVES=OFF \
-DMAGNUM_WITH_SCENEGRAPH=OFF \

4
src/Magnum/CMakeLists.txt

@ -218,6 +218,10 @@ if(MAGNUM_WITH_GL)
add_subdirectory(GL)
endif()
if(MAGNUM_WITH_MATERIALTOOLS)
add_subdirectory(MaterialTools)
endif()
if(MAGNUM_WITH_MESHTOOLS)
add_subdirectory(MeshTools)
endif()

98
src/Magnum/MaterialTools/CMakeLists.txt

@ -0,0 +1,98 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
#
# 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.
#
# IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER
# property that would have to be set on each target separately.
set(CMAKE_FOLDER "Magnum/MaterialTools")
# Files shared between main library and unit test library
set(MagnumMaterialTools_SRCS
PhongToPbrMetallicRoughness.cpp)
# Files compiled with different flags for main library and unit test library
set(MagnumMaterialTools_GracefulAssert_SRCS )
set(MagnumMaterialTools_HEADERS
PhongToPbrMetallicRoughness.h
visibility.h)
set(MagnumSceneTools_PRIVATE_HEADERS )
# Objects shared between main and test library
add_library(MagnumMaterialToolsObjects OBJECT
${MagnumMaterialTools_SRCS}
${MagnumMaterialTools_HEADERS}
${MagnumMaterialTools_PRIVATE_HEADERS})
target_include_directories(MagnumMaterialToolsObjects PUBLIC $<TARGET_PROPERTY:Magnum,INTERFACE_INCLUDE_DIRECTORIES>)
if(NOT MAGNUM_BUILD_STATIC)
target_compile_definitions(MagnumMaterialToolsObjects PRIVATE "MagnumMaterialToolsObjects_EXPORTS")
endif()
if(NOT MAGNUM_BUILD_STATIC OR MAGNUM_BUILD_STATIC_PIC)
set_target_properties(MagnumMaterialToolsObjects PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
# Main MaterialTools library
add_library(MagnumMaterialTools ${SHARED_OR_STATIC}
$<TARGET_OBJECTS:MagnumMaterialToolsObjects>
${MagnumMaterialTools_GracefulAssert_SRCS}
${MagnumMaterialTools_HEADERS}
${MagnumMaterialTools_PRIVATE_HEADERS})
set_target_properties(MagnumMaterialTools PROPERTIES DEBUG_POSTFIX "-d")
if(NOT MAGNUM_BUILD_STATIC)
set_target_properties(MagnumMaterialTools PROPERTIES VERSION ${MAGNUM_LIBRARY_VERSION} SOVERSION ${MAGNUM_LIBRARY_SOVERSION})
elseif(MAGNUM_BUILD_STATIC_PIC)
set_target_properties(MagnumMaterialTools PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
target_link_libraries(MagnumMaterialTools PUBLIC
Magnum
MagnumTrade)
install(TARGETS MagnumMaterialTools
RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}
LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
install(FILES ${MagnumMaterialTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/MaterialTools)
if(MAGNUM_BUILD_TESTS)
# # Library with graceful assert for testing
# add_library(MagnumMaterialToolsTestLib ${SHARED_OR_STATIC}
# $<TARGET_OBJECTS:MagnumMaterialToolsObjects>
# ${MagnumMaterialTools_GracefulAssert_SRCS})
# set_target_properties(MagnumMaterialToolsTestLib PROPERTIES DEBUG_POSTFIX "-d")
# target_compile_definitions(MagnumMaterialToolsTestLib PRIVATE
# "CORRADE_GRACEFUL_ASSERT" "MagnumMaterialTools_EXPORTS")
# if(MAGNUM_BUILD_STATIC_PIC)
# set_target_properties(MagnumMaterialToolsTestLib PROPERTIES POSITION_INDEPENDENT_CODE ON)
# endif()
# target_link_libraries(MagnumMaterialToolsTestLib PUBLIC
# Magnum
# MagnumTrade)
add_subdirectory(Test)
endif()
# Magnum MaterialTools target alias for superprojects
add_library(Magnum::MaterialTools ALIAS MagnumMaterialTools)

166
src/Magnum/MaterialTools/PhongToPbrMetallicRoughness.cpp

@ -0,0 +1,166 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
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 "PhongToPbrMetallicRoughness.h"
#include <Corrade/Containers/BitArray.h>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/String.h>
#include "Magnum/Math/Matrix3.h"
#include "Magnum/Math/Vector4.h"
#include "Magnum/Trade/MaterialData.h"
namespace Magnum { namespace MaterialTools {
using namespace Containers::Literals;
Containers::Optional<Trade::MaterialData> phongToPbrMetallicRoughness(const Trade::MaterialData& material, const PhongToPbrMetallicRoughnessFlags flags) {
/* Output attributes, reserve assuming some input attributes will get
replaced with different */
Containers::Array<Trade::MaterialAttributeData> attributes;
arrayReserve(attributes, material.attributeData().size());
/* Attributes to skip in the base layer */
Containers::BitArray attributesToSkip{ValueInit, material.attributeCount(0)};
/* Decide about unconvertable attributes */
/** @todo conversion of these:
https://github.com/CesiumGS/obj2gltf/blob/9b018ff6968edf76c33d2a68eb51a3605b873d12/lib/loadMtl.js#L962-L989
- "textures not converted lol"
https://computergraphics.stackexchange.com/a/1517
- for shininess, expose flags for picking different approaches */
for(const Trade::MaterialAttribute attribute: {
Trade::MaterialAttribute::AmbientColor,
Trade::MaterialAttribute::SpecularColor,
Trade::MaterialAttribute::Shininess
}) {
const Containers::Optional<UnsignedInt> id = material.findAttributeId(attribute);
if(!id) continue;
if(flags >= PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes) {
Error{} << "MaterialTools::phongToPbrMetallicRoughness(): unconvertable" << attribute << "attribute";
return {};
}
Warning{} << "MaterialTools::phongToPbrMetallicRoughness(): unconvertable" << attribute << "attribute, skipping";
if(flags >= PhongToPbrMetallicRoughnessFlag::DropUnconvertableAttributes)
attributesToSkip.set(*id);
}
for(const Trade::MaterialAttribute attribute: {
Trade::MaterialAttribute::AmbientTexture,
Trade::MaterialAttribute::SpecularTexture
}) {
const Containers::Optional<UnsignedInt> id = material.findAttributeId(attribute);
if(!id) continue;
if(flags >= PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes) {
Error{} << "MaterialTools::phongToPbrMetallicRoughness(): unconvertable" << attribute << "attribute";
return {};
}
const Containers::Optional<UnsignedInt> matrixId = material.findAttributeId(Trade::materialAttributeName(attribute) + "Matrix"_s);
const Containers::Optional<UnsignedInt> coordinatesId = material.findAttributeId(Trade::materialAttributeName(attribute) + "Coordinates"_s);
const Containers::Optional<UnsignedInt> layerId = material.findAttributeId(Trade::materialAttributeName(attribute) + "Layer"_s);
Warning{} << "MaterialTools::phongToPbrMetallicRoughness(): unconvertable" << attribute << "attribute, skipping";
if(flags >= PhongToPbrMetallicRoughnessFlag::DropUnconvertableAttributes) {
attributesToSkip.set(*id);
if(matrixId)
attributesToSkip.set(*matrixId);
if(coordinatesId)
attributesToSkip.set(*coordinatesId);
if(layerId)
attributesToSkip.set(*layerId);
}
}
/* Diffuse color */
if(const Containers::Optional<UnsignedInt> id = material.findAttributeId(Trade::MaterialAttribute::DiffuseColor)) {
/* Convert only if the target attribute isn't there already */
if(!material.hasAttribute(Trade::MaterialAttribute::BaseColor))
arrayAppend(attributes, InPlaceInit, Trade::MaterialAttribute::BaseColor, material.attribute<Vector4>(*id));
/* Skip unless we're told to keep the original attributes */
if(!(flags >= PhongToPbrMetallicRoughnessFlag::KeepOriginalAttributes))
attributesToSkip.set(*id);
}
/* Diffuse texture and related attributes */
if(const Containers::Optional<UnsignedInt> id = material.findAttributeId(Trade::MaterialAttribute::DiffuseTexture)) {
const Containers::Optional<UnsignedInt> matrixId = material.findAttributeId(Trade::MaterialAttribute::DiffuseTextureMatrix);
const Containers::Optional<UnsignedInt> coordinatesId = material.findAttributeId(Trade::MaterialAttribute::DiffuseTextureCoordinates);
const Containers::Optional<UnsignedInt> layerId = material.findAttributeId(Trade::MaterialAttribute::DiffuseTextureLayer);
/* Convert only if the target attribute isn't there already */
if(!material.hasAttribute(Trade::MaterialAttribute::BaseColorTexture)) {
arrayAppend(attributes, InPlaceInit, Trade::MaterialAttribute::BaseColorTexture, material.attribute<UnsignedInt>(*id));
if(matrixId)
arrayAppend(attributes, InPlaceInit, Trade::MaterialAttribute::BaseColorTextureMatrix, material.attribute<Matrix3>(*matrixId));
if(coordinatesId)
arrayAppend(attributes, InPlaceInit, Trade::MaterialAttribute::BaseColorTextureCoordinates, material.attribute<UnsignedInt>(*coordinatesId));
if(layerId)
arrayAppend(attributes, InPlaceInit, Trade::MaterialAttribute::BaseColorTextureLayer, material.attribute<UnsignedInt>(*layerId));
}
/* Skip unless we're told to keep the original attributes */
if(!(flags >= PhongToPbrMetallicRoughnessFlag::KeepOriginalAttributes)) {
attributesToSkip.set(*id);
if(matrixId)
attributesToSkip.set(*matrixId);
if(coordinatesId)
attributesToSkip.set(*coordinatesId);
if(layerId)
attributesToSkip.set(*layerId);
}
}
/* New layer offsets. If there's no layer data in the original, the whole
attribute array is the base layer */
Containers::Array<UnsignedInt> layers;
if(material.layerData()) {
/* Calculate the difference in base layer size */
Int baseLayerSizeDifference = attributes.size();
/** @todo have popcount() on BitArray */
for(std::size_t i = 0; i != attributesToSkip.size(); ++i)
if(attributesToSkip[i]) --baseLayerSizeDifference;
/* Fill the new layer offset array */
layers = Containers::Array<UnsignedInt>{NoInit, material.layerData().size()};
for(std::size_t i = 0; i != layers.size(); ++i)
layers[i] = material.layerData()[i] + baseLayerSizeDifference;
}
/* Add the remaining attribute data including the extra layers, except ones
that are meant to be skipped in the base layer */
for(std::size_t i = 0; i != material.attributeData().size(); ++i)
if(i >= attributesToSkip.size() || !attributesToSkip[i])
arrayAppend(attributes, material.attributeData()[i]);
/* Replace Phong with PbrMetallicRoughness in the output */
return Trade::MaterialData{(material.types() & ~Trade::MaterialType::Phong)|Trade::MaterialType::PbrMetallicRoughness, std::move(attributes), std::move(layers)};
}
}}

124
src/Magnum/MaterialTools/PhongToPbrMetallicRoughness.h

@ -0,0 +1,124 @@
#ifndef Magnum_MaterialTools_PhongToPbrMetallicRoughness_h
#define Magnum_MaterialTools_PhongToPbrMetallicRoughness_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
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 Enum @ref Magnum::MaterialTools::PhongToPbrMetallicRoughnessFlag, enum set @ref Magnum::MaterialTools::PhongToPbrMetallicRoughnessFlags, Function @ref Magnum::MaterialTools::phongToPbrMetallicRoughness()
* @m_since_latest
*/
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/MaterialTools/visibility.h"
#include "Magnum/Trade/Trade.h"
namespace Magnum { namespace MaterialTools {
/**
@brief Phong to PBR metallic/roughness conversion flag
@m_since_latest
@see @ref PhongToPbrMetallicRoughnessFlags, @ref phongToPbrMetallicRoughness()
*/
enum class PhongToPbrMetallicRoughnessFlag {
/**
* Keep original attributes instead of removing all that were converted.
*/
KeepOriginalAttributes = 1 << 0,
/**
* Drop attributes that can't be converted instead of keeping them in the
* output. If
* @relativeref{PhongToPbrMetallicRoughnessFlag,FailOnUnconvertableAttributes}
* is specified as well, it has a priority.
*/
DropUnconvertableAttributes = 1 << 1,
/**
* Fail if any attributes can't be converted instead of keeping them in the
* output. Has a priority over
* @relativeref{PhongToPbrMetallicRoughnessFlag,DropUnconvertableAttributes}.
*/
FailOnUnconvertableAttributes = (1 << 2)|DropUnconvertableAttributes,
/** @todo flags to pick various shininess conversion alternatives */
};
/**
@brief Phong to PBR conversion flags
@m_since_latest
@see @ref phongToPbrMetallicRoughness()
*/
typedef Containers::EnumSet<PhongToPbrMetallicRoughnessFlag> PhongToPbrMetallicRoughnessFlags;
CORRADE_ENUMSET_OPERATORS(PhongToPbrMetallicRoughnessFlags)
/**
@brief Convert a Phong material to PBR metallic/roughness
@m_since_latest
Performs conversion of the following attributes. If the target attribute is
already present, it's passed through unchanged. The original attribute is
removed, unless @ref PhongToPbrMetallicRoughnessFlag::KeepOriginalAttributes is
set.
- The value of @ref Trade::MaterialAttribute::DiffuseColor is used unchanged
for @relativeref{Trade::MaterialAttribute,BaseColor}
- The value of @ref Trade::MaterialAttribute::DiffuseTexture and related
texture attributes is used unchanged for
@relativeref{Trade::MaterialAttribute,BaseColorTexture} and corresponding
related texture attributes
The following attributes currently aren't converted. If they are present in the
input material, a message is printed to @relativeref{Magnum,Warning}. The
attributes are passed through unchanged unless
@ref PhongToPbrMetallicRoughnessFlag::DropUnconvertableAttributes is set; if
@relativeref{PhongToPbrMetallicRoughnessFlag,FailOnUnconvertableAttributes} is
set instead, a message is printed to @relativeref{Magnum,Error} and the
function returns @relativeref{Corrade,Containers::NullOpt}.
- @ref Trade::MaterialAttribute::AmbientColor,
@relativeref{Trade::MaterialAttribute,AmbientTexture} and related texture
attributes
- @ref Trade::MaterialAttribute::SpecularColor,
@relativeref{Trade::MaterialAttribute,SpecularTexture} and related texture
attributes
- @ref Trade::MaterialAttribute::Shininess
All other attributes (including ones common for Phong and PBR such as
@ref Trade::MaterialAttribute::NormalTexture) are passed through unchanged. The
resulting material has @ref Trade::MaterialType::PbrMetallicRoughness set and
@ref Trade::MaterialType::Phong removed.
@see @ref phongToFlat(), @ref Trade::PbrMetallicRoughnessMaterialData
*/
MAGNUM_MATERIALTOOLS_EXPORT Containers::Optional<Trade::MaterialData> phongToPbrMetallicRoughness(const Trade::MaterialData& material, PhongToPbrMetallicRoughnessFlags flags = {});
}}
#endif

31
src/Magnum/MaterialTools/Test/CMakeLists.txt

@ -0,0 +1,31 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
#
# 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.
#
# IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER
# property that would have to be set on each target separately.
set(CMAKE_FOLDER "Magnum/MaterialTools/Test")
corrade_add_test(MaterialToolsPhongToPbrMetall___Test PhongToPbrMetallicRoughnessTest.cpp
LIBRARIES MagnumDebugTools MagnumMaterialTools)

313
src/Magnum/MaterialTools/Test/PhongToPbrMetallicRoughnessTest.cpp

@ -0,0 +1,313 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
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 <sstream>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h> /** @todo remove once Debug is stream-free */
#include "Magnum/DebugTools/CompareMaterial.h"
#include "Magnum/MaterialTools/PhongToPbrMetallicRoughness.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Math/Matrix3.h"
#include "Magnum/Trade/MaterialData.h"
namespace Magnum { namespace MaterialTools { namespace Test { namespace {
struct PhongToPbrMetallicRoughnessTest: TestSuite::Tester {
explicit PhongToPbrMetallicRoughnessTest();
void convert();
void warning();
void fail();
};
using namespace Math::Literals;
const struct {
const char* name;
PhongToPbrMetallicRoughnessFlags flags;
Trade::MaterialData material;
Trade::MaterialData expected;
} ConvertData[]{
{"empty with no type", {},
Trade::MaterialData{{}, {}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {}}},
{"empty with Phong and other types", {},
Trade::MaterialData{Trade::MaterialType::Phong|Trade::MaterialType::PbrClearCoat, {}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrClearCoat, {}}},
{"diffuse color", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366ff_rgbaf}
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}
}}},
{"diffuse texture + matrix", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseTexture, 5u},
{Trade::MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColorTexture, 5u},
{Trade::MaterialAttribute::BaseColorTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
}}},
{"diffuse color + texture + coordinates + layer", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::DiffuseTexture, 7u},
{Trade::MaterialAttribute::DiffuseTextureCoordinates, 2u},
{Trade::MaterialAttribute::DiffuseTextureLayer, 155u},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::BaseColorTexture, 7u},
{Trade::MaterialAttribute::BaseColorTextureCoordinates, 2u},
{Trade::MaterialAttribute::BaseColorTextureLayer, 155u},
}}},
{"both diffuse and base color", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366ff_rgbaf},
{Trade::MaterialAttribute::BaseColor, 0x3366ffff_rgbaf}
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
/* It's not overwritten as it's assumed to be more correct */
{Trade::MaterialAttribute::BaseColor, 0x3366ffff_rgbaf}
}}},
{"both diffuse and base color texture but different texture properties", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseTexture, 8u},
{Trade::MaterialAttribute::DiffuseTextureLayer, 12u},
{Trade::MaterialAttribute::DiffuseTextureMatrix, Matrix3{}},
{Trade::MaterialAttribute::BaseColorTexture, 11u},
{Trade::MaterialAttribute::BaseColorTextureCoordinates, 1u},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
/* It's not overwritten as it's assumed to be more correct;
texture-related attributes are not mixed together */
{Trade::MaterialAttribute::BaseColorTexture, 11u},
{Trade::MaterialAttribute::BaseColorTextureCoordinates, 1u},
}}},
{"keep original attributes", PhongToPbrMetallicRoughnessFlag::KeepOriginalAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::DiffuseTexture, 7u},
{Trade::MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::DiffuseTextureCoordinates, 2u},
{Trade::MaterialAttribute::DiffuseTextureLayer, 155u},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::BaseColorTexture, 7u},
{Trade::MaterialAttribute::BaseColorTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::BaseColorTextureCoordinates, 2u},
{Trade::MaterialAttribute::BaseColorTextureLayer, 155u},
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::DiffuseTexture, 7u},
{Trade::MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::DiffuseTextureCoordinates, 2u},
{Trade::MaterialAttribute::DiffuseTextureLayer, 155u},
}}},
{"extra attributes and layers", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366ff_rgbaf},
{Trade::MaterialAttribute::AlphaMask, 0.7f},
{Trade::MaterialAttribute::DiffuseTexture, 7u},
{Trade::MaterialLayer::ClearCoat},
{Trade::MaterialAttribute::LayerFactor, 0.35f},
}, {2, 3, 5}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf},
{Trade::MaterialAttribute::AlphaMask, 0.7f},
/* Shouldn't get converted because it's a different layer */
{Trade::MaterialAttribute::DiffuseTexture, 7u},
{Trade::MaterialLayer::ClearCoat},
{Trade::MaterialAttribute::LayerFactor, 0.35f},
}, {2, 3, 5}}},
{"extra attributes and layers, keep original attributes", PhongToPbrMetallicRoughnessFlag::KeepOriginalAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366ff_rgbaf},
{Trade::MaterialAttribute::DiffuseTexture, 0u},
{Trade::MaterialAttribute::AlphaMask, 0.7f},
{Trade::MaterialLayer::ClearCoat},
{Trade::MaterialAttribute::LayerFactor, 0.35f},
}, {2, 4}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf},
{Trade::MaterialAttribute::BaseColorTexture, 0u},
{Trade::MaterialAttribute::DiffuseColor, 0xff3366ff_rgbaf},
{Trade::MaterialAttribute::DiffuseTexture, 0u},
{Trade::MaterialAttribute::AlphaMask, 0.7f},
{Trade::MaterialLayer::ClearCoat},
{Trade::MaterialAttribute::LayerFactor, 0.35f},
}, {4, 6}}},
{"diffuse texture properties without texture", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::DiffuseTextureCoordinates, 2u},
{Trade::MaterialAttribute::DiffuseTextureLayer, 155u},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366cc_rgbaf},
/* Those are kept and don't produce any warning because the
texture wasn't found and thus the branch wasn't taken */
{Trade::MaterialAttribute::DiffuseTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::DiffuseTextureCoordinates, 2u},
{Trade::MaterialAttribute::DiffuseTextureLayer, 155u},
}}},
{"ambient texture properties without texture, fail on unconvertable", PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::AmbientTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::AmbientTextureLayer, 356u},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366cc_rgbaf},
/* These are kept and don't produce any failure because the
texture wasn't found and thus the branch wasn't taken */
{Trade::MaterialAttribute::AmbientTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::AmbientTextureLayer, 356u},
}}},
};
const struct {
const char* name;
PhongToPbrMetallicRoughnessFlags flags;
Trade::MaterialData material;
Trade::MaterialData expected;
const char* message;
} WarningData[]{
{"ambient color, specular texture + coordinates", {},
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::AmbientColor, 0x0f030600_rgbaf},
{Trade::MaterialAttribute::SpecularTexture, 3u},
{Trade::MaterialAttribute::SpecularTextureCoordinates, 2u},
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::AmbientColor, 0x0f030600_rgbaf},
{Trade::MaterialAttribute::SpecularTexture, 3u},
{Trade::MaterialAttribute::SpecularTextureCoordinates, 2u},
}},
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::AmbientColor attribute, skipping\n"
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::SpecularTexture attribute, skipping\n"},
{"specular color, texture + matrix + layer, ambient texture + coordinates; drop unconvertable", PhongToPbrMetallicRoughnessFlag::DropUnconvertableAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::DiffuseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::SpecularColor, 0x3366ffff_rgbaf},
{Trade::MaterialAttribute::SpecularTexture, 3u},
{Trade::MaterialAttribute::SpecularTextureMatrix, Matrix3::scaling(Vector2{0.5f})},
{Trade::MaterialAttribute::SpecularTextureLayer, 156u},
{Trade::MaterialAttribute::AmbientTexture, 1u},
{Trade::MaterialAttribute::AmbientTextureCoordinates, 2u},
{Trade::MaterialAttribute::DoubleSided, true}
}},
Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::BaseColor, 0xff3366cc_rgbaf},
{Trade::MaterialAttribute::DoubleSided, true}
}},
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::SpecularColor attribute, skipping\n"
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::AmbientTexture attribute, skipping\n"
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::SpecularTexture attribute, skipping\n"},
};
const struct {
const char* name;
PhongToPbrMetallicRoughnessFlags flags;
Trade::MaterialData material;
const char* message;
} FailData[]{
{"ambient color, fail on unconvertable", PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::AmbientColor, Color4{}},
}},
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::AmbientColor attribute\n"},
{"specular texture, fail on unconvertable", PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::SpecularTexture, 0u},
}},
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::SpecularTexture attribute\n"},
{"shininess, fail on unconvertable", PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::Shininess, 0.5f},
}},
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::Shininess attribute\n"},
{"specular color, both drop & fail on unconvertable", PhongToPbrMetallicRoughnessFlag::FailOnUnconvertableAttributes|PhongToPbrMetallicRoughnessFlag::DropUnconvertableAttributes,
Trade::MaterialData{{}, {
{Trade::MaterialAttribute::SpecularTexture, 0u},
}},
"MaterialTools::phongToPbrMetallicRoughness(): unconvertable Trade::MaterialAttribute::SpecularTexture attribute\n"},
};
PhongToPbrMetallicRoughnessTest::PhongToPbrMetallicRoughnessTest() {
addInstancedTests({&PhongToPbrMetallicRoughnessTest::convert},
Containers::arraySize(ConvertData));
addInstancedTests({&PhongToPbrMetallicRoughnessTest::warning},
Containers::arraySize(WarningData));
addInstancedTests({&PhongToPbrMetallicRoughnessTest::fail},
Containers::arraySize(FailData));
}
void PhongToPbrMetallicRoughnessTest::convert() {
auto&& data = ConvertData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::ostringstream out;
Error redirectError{&out};
Warning redirectWarning{&out};
Containers::Optional<Trade::MaterialData> actual = phongToPbrMetallicRoughness(data.material, data.flags);
CORRADE_VERIFY(actual);
CORRADE_COMPARE_AS(*actual, data.expected, DebugTools::CompareMaterial);
CORRADE_COMPARE(out.str(), "");
}
void PhongToPbrMetallicRoughnessTest::warning() {
auto&& data = WarningData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::ostringstream out;
Warning redirectWarning{&out};
Containers::Optional<Trade::MaterialData> actual = phongToPbrMetallicRoughness(data.material, data.flags);
CORRADE_VERIFY(actual);
CORRADE_COMPARE_AS(*actual, data.expected, DebugTools::CompareMaterial);
CORRADE_COMPARE(out.str(), data.message);
}
void PhongToPbrMetallicRoughnessTest::fail() {
auto&& data = FailData[testCaseInstanceId()];
setTestCaseDescription(data.name);
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!phongToPbrMetallicRoughness(data.material, data.flags));
CORRADE_COMPARE(out.str(), data.message);
}
}}}}
CORRADE_TEST_MAIN(Magnum::MaterialTools::Test::PhongToPbrMetallicRoughnessTest)

49
src/Magnum/MaterialTools/visibility.h

@ -0,0 +1,49 @@
#ifndef Magnum_MaterialTools_visibility_h
#define Magnum_MaterialTools_visibility_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
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 <Corrade/Utility/VisibilityMacros.h>
#include "Magnum/configure.h"
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_BUILD_STATIC
#if defined(MagnumMaterialTools_EXPORTS) || defined(MagnumMaterialToolsObjects_EXPORTS)
#define MAGNUM_MATERIALTOOLS_EXPORT CORRADE_VISIBILITY_EXPORT
#else
#define MAGNUM_MATERIALTOOLS_EXPORT CORRADE_VISIBILITY_IMPORT
#endif
#else
#define MAGNUM_MATERIALTOOLS_EXPORT CORRADE_VISIBILITY_STATIC
#endif
#define MAGNUM_MATERIALTOOLS_LOCAL CORRADE_VISIBILITY_LOCAL
#else
#define MAGNUM_MATERIALTOOLS_EXPORT
#define MAGNUM_MATERIALTOOLS_LOCAL
#endif
#endif
Loading…
Cancel
Save