mirror of https://github.com/mosra/magnum.git
5 changed files with 360 additions and 0 deletions
@ -0,0 +1,67 @@
|
||||
/*
|
||||
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 "Copy.h" |
||||
|
||||
#include <Corrade/Utility/Algorithms.h> |
||||
|
||||
#include "Magnum/Trade/MaterialData.h" |
||||
|
||||
namespace Magnum { namespace MaterialTools { |
||||
|
||||
Trade::MaterialData copy(const Trade::MaterialData& material) { |
||||
return copy(Trade::MaterialData{material.types(), |
||||
{}, material.attributeData(), |
||||
{}, material.layerData(), |
||||
material.importerState()}); |
||||
} |
||||
|
||||
Trade::MaterialData copy(Trade::MaterialData&& material) { |
||||
/* Transfer attributes if they're owned & mutable, allocate a copy
|
||||
otherwise */ |
||||
Containers::Array<Trade::MaterialAttributeData> attributes; |
||||
if(material.attributeDataFlags() >= (Trade::DataFlag::Mutable|Trade::DataFlag::Owned)) |
||||
attributes = material.releaseAttributeData(); |
||||
else { |
||||
/* DefaultInit so we don't use a non-default deleter which could cause
|
||||
problems in plugins */ |
||||
attributes = Containers::Array<Trade::MaterialAttributeData>{DefaultInit, material.attributeData().size()}; |
||||
Utility::copy(material.attributeData(), attributes); |
||||
} |
||||
|
||||
/* Same for layers, here it can be NoInit; if the original has implicit
|
||||
single layer (and empty data), this makes no allocation either */ |
||||
Containers::Array<UnsignedInt> layers; |
||||
if(material.attributeDataFlags() >= (Trade::DataFlag::Mutable|Trade::DataFlag::Owned)) |
||||
layers = material.releaseLayerData(); |
||||
else { |
||||
layers = Containers::Array<UnsignedInt>{NoInit, material.layerData().size()}; |
||||
Utility::copy(material.layerData(), layers); |
||||
} |
||||
|
||||
return Trade::MaterialData{material.types(), std::move(attributes), std::move(layers), material.importerState()}; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,67 @@
|
||||
#ifndef Magnum_MaterialTools_Copy_h |
||||
#define Magnum_MaterialTools_Copy_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 Function @ref Magnum::MaterialTools::copy() |
||||
* @m_since_latest |
||||
*/ |
||||
|
||||
#include "Magnum/MaterialTools/visibility.h" |
||||
#include "Magnum/Trade/Trade.h" |
||||
|
||||
namespace Magnum { namespace MaterialTools { |
||||
|
||||
/**
|
||||
@brief Make an owned copy of the material |
||||
@m_since_latest |
||||
|
||||
Allocates a copy of @ref Trade::MaterialData::attributeData() and |
||||
@relativeref{Trade::MaterialData,layerData()} and returns a new material with |
||||
those. All other properties such as material types or importer state are passed |
||||
through unchanged. The resulting @ref Trade::MaterialData::attributeDataFlags() |
||||
and @relativeref{Trade::MaterialData,layerDataFlags()} are always |
||||
@ref Trade::DataFlag::Owned and @ref Trade::DataFlag::Mutable. |
||||
@see @ref copy(Trade::MaterialData&&) |
||||
*/ |
||||
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData copy(const Trade::MaterialData& material); |
||||
|
||||
/**
|
||||
@brief Make a material with owned data |
||||
@m_since_latest |
||||
|
||||
If either @ref Trade::MaterialData::attributeDataFlags() or |
||||
@relativeref{Trade::MaterialData,layerDataFlags()} are not |
||||
@ref Trade::DataFlag::Owned and @ref Trade::DataFlag::Mutable, allocates a copy |
||||
of @ref Trade::MaterialData::attributeData() or |
||||
@relativeref{Trade::MaterialData,layerData()}, otherwise transfers their |
||||
ownership. The resulting data are always owned and mutable. |
||||
*/ |
||||
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData copy(Trade::MaterialData&& material); |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,223 @@
|
||||
/*
|
||||
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/TestSuite/Tester.h> |
||||
|
||||
#include "Magnum/MaterialTools/Copy.h" |
||||
#include "Magnum/Math/Color.h" |
||||
#include "Magnum/Trade/MaterialData.h" |
||||
|
||||
namespace Magnum { namespace MaterialTools { namespace Test { namespace { |
||||
|
||||
struct CopyTest: TestSuite::Tester { |
||||
explicit CopyTest(); |
||||
|
||||
void singleLayer(); |
||||
void singleLayerNoLayerData(); |
||||
|
||||
void multipleLayers(); |
||||
|
||||
void rvalueNotOwned(); |
||||
void rvalueOwnedAttributesLayers(); |
||||
/* There's currently no constructor (and no use case) that would need owned
|
||||
attributes but not layers or vice versa, it's either all or none */ |
||||
void rvalueOwnedAttributesNoLayerData(); |
||||
}; |
||||
|
||||
CopyTest::CopyTest() { |
||||
addTests({&CopyTest::singleLayer, |
||||
&CopyTest::singleLayerNoLayerData, |
||||
|
||||
&CopyTest::multipleLayers, |
||||
|
||||
&CopyTest::rvalueNotOwned, |
||||
&CopyTest::rvalueOwnedAttributesLayers, |
||||
&CopyTest::rvalueOwnedAttributesNoLayerData}); |
||||
} |
||||
|
||||
using namespace Math::Literals; |
||||
|
||||
void CopyTest::singleLayer() { |
||||
Trade::MaterialData material{Trade::MaterialType::PbrMetallicRoughness, { |
||||
{Trade::MaterialAttribute::AlphaBlend, true}, |
||||
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}, |
||||
{"baseColorTextureName", "yesss.png"}, |
||||
}, {3}, reinterpret_cast<void*>(0xdeadbeef)}; |
||||
|
||||
Trade::MaterialData copy = MaterialTools::copy(material); |
||||
CORRADE_COMPARE(copy.types(), Trade::MaterialType::PbrMetallicRoughness); |
||||
CORRADE_COMPARE(copy.importerState(), reinterpret_cast<void*>(0xdeadbeef)); |
||||
|
||||
CORRADE_COMPARE(copy.layerDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.layerCount(), 1); |
||||
CORRADE_COMPARE(copy.layerData().size(), 1); |
||||
CORRADE_COMPARE(copy.layerData()[0], 3); |
||||
|
||||
CORRADE_COMPARE(copy.attributeDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.attributeCount(), 3); |
||||
CORRADE_COMPARE(copy.attribute<bool>(Trade::MaterialAttribute::AlphaBlend), true); |
||||
CORRADE_COMPARE(copy.attribute<Color4>(Trade::MaterialAttribute::BaseColor), 0xff3366ff_rgbaf); |
||||
CORRADE_COMPARE(copy.attribute<Containers::StringView>("baseColorTextureName"), "yesss.png"); |
||||
|
||||
/* The data should have a default deleter to make this usable in plugins */ |
||||
Containers::Array<Trade::MaterialAttributeData> attributeData = copy.releaseAttributeData(); |
||||
Containers::Array<UnsignedInt> layerData = copy.releaseLayerData(); |
||||
CORRADE_VERIFY(!attributeData.deleter()); |
||||
CORRADE_VERIFY(!layerData.deleter()); |
||||
} |
||||
|
||||
void CopyTest::singleLayerNoLayerData() { |
||||
Trade::MaterialData material{Trade::MaterialType::PbrMetallicRoughness, { |
||||
{Trade::MaterialAttribute::AlphaBlend, true}, |
||||
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}, |
||||
{"baseColorTextureName", "yesss.png"}, |
||||
}, reinterpret_cast<void*>(0xdeadbeef)}; |
||||
|
||||
Trade::MaterialData copy = MaterialTools::copy(material); |
||||
CORRADE_COMPARE(copy.types(), Trade::MaterialType::PbrMetallicRoughness); |
||||
CORRADE_COMPARE(copy.importerState(), reinterpret_cast<void*>(0xdeadbeef)); |
||||
|
||||
CORRADE_COMPARE(copy.layerDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.layerCount(), 1); |
||||
CORRADE_COMPARE(copy.layerData().size(), 0); |
||||
CORRADE_COMPARE(copy.layerData(), nullptr); |
||||
|
||||
CORRADE_COMPARE(copy.attributeDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.attributeCount(), 3); |
||||
CORRADE_COMPARE(copy.attribute<bool>(Trade::MaterialAttribute::AlphaBlend), true); |
||||
CORRADE_COMPARE(copy.attribute<Color4>(Trade::MaterialAttribute::BaseColor), 0xff3366ff_rgbaf); |
||||
CORRADE_COMPARE(copy.attribute<Containers::StringView>("baseColorTextureName"), "yesss.png"); |
||||
} |
||||
|
||||
void CopyTest::multipleLayers() { |
||||
Trade::MaterialData material{Trade::MaterialType::PbrMetallicRoughness, { |
||||
{Trade::MaterialAttribute::AlphaBlend, true}, |
||||
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}, |
||||
{"baseColorTextureName", "yesss.png"}, |
||||
}, {2, 3}, reinterpret_cast<void*>(0xdeadbeef)}; |
||||
|
||||
Trade::MaterialData copy = MaterialTools::copy(material); |
||||
CORRADE_COMPARE(copy.types(), Trade::MaterialType::PbrMetallicRoughness); |
||||
CORRADE_COMPARE(copy.importerState(), reinterpret_cast<void*>(0xdeadbeef)); |
||||
|
||||
CORRADE_COMPARE(copy.layerDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.layerCount(), 2); |
||||
|
||||
CORRADE_COMPARE(copy.attributeDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.attributeCount(0), 2); |
||||
CORRADE_COMPARE(copy.attributeCount(1), 1); |
||||
CORRADE_COMPARE(copy.attribute<bool>(0, Trade::MaterialAttribute::AlphaBlend), true); |
||||
CORRADE_COMPARE(copy.attribute<Color4>(0, Trade::MaterialAttribute::BaseColor), 0xff3366ff_rgbaf); |
||||
CORRADE_COMPARE(copy.attribute<Containers::StringView>(1, "baseColorTextureName"), "yesss.png"); |
||||
|
||||
/* The data should have a default deleter to make this usable in plugins */ |
||||
Containers::Array<Trade::MaterialAttributeData> attributeData = copy.releaseAttributeData(); |
||||
Containers::Array<UnsignedInt> layerData = copy.releaseLayerData(); |
||||
CORRADE_VERIFY(!attributeData.deleter()); |
||||
CORRADE_VERIFY(!layerData.deleter()); |
||||
} |
||||
|
||||
void CopyTest::rvalueNotOwned() { |
||||
Trade::MaterialAttributeData attributes[]{ |
||||
{Trade::MaterialAttribute::AlphaBlend, true}, |
||||
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}, |
||||
{"baseColorTextureName", "yesss.png"}, |
||||
}; |
||||
UnsignedInt layers[]{2, 3}; |
||||
|
||||
Trade::MaterialData copy = MaterialTools::copy(Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, |
||||
Trade::DataFlag::Mutable, attributes, |
||||
Trade::DataFlag::Mutable|Trade::DataFlag::ExternallyOwned, layers, |
||||
reinterpret_cast<void*>(0xdeadbeef)}); |
||||
CORRADE_COMPARE(copy.types(), Trade::MaterialType::PbrMetallicRoughness); |
||||
CORRADE_COMPARE(copy.importerState(), reinterpret_cast<void*>(0xdeadbeef)); |
||||
|
||||
CORRADE_COMPARE(copy.layerDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.layerCount(), 2); |
||||
|
||||
CORRADE_COMPARE(copy.attributeDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.attributeCount(0), 2); |
||||
CORRADE_COMPARE(copy.attributeCount(1), 1); |
||||
CORRADE_COMPARE(copy.attribute<bool>(0, Trade::MaterialAttribute::AlphaBlend), true); |
||||
CORRADE_COMPARE(copy.attribute<Color4>(0, Trade::MaterialAttribute::BaseColor), 0xff3366ff_rgbaf); |
||||
CORRADE_COMPARE(copy.attribute<Containers::StringView>(1, "baseColorTextureName"), "yesss.png"); |
||||
} |
||||
|
||||
void CopyTest::rvalueOwnedAttributesLayers() { |
||||
Containers::Array<Trade::MaterialAttributeData> attributes{InPlaceInit, { |
||||
{Trade::MaterialAttribute::AlphaBlend, true}, |
||||
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}, |
||||
{"baseColorTextureName", "yesss.png"}, |
||||
}}; |
||||
Containers::Array<UnsignedInt> layers{InPlaceInit, {2, 3}}; |
||||
const void* originalAttributes = attributes.data(); |
||||
const void* originalLayers = layers.data(); |
||||
|
||||
Trade::MaterialData copy = MaterialTools::copy(Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, std::move(attributes), std::move(layers), reinterpret_cast<void*>(0xdeadbeef)}); |
||||
CORRADE_COMPARE(copy.types(), Trade::MaterialType::PbrMetallicRoughness); |
||||
CORRADE_COMPARE(copy.importerState(), reinterpret_cast<void*>(0xdeadbeef)); |
||||
|
||||
CORRADE_COMPARE(copy.layerDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.layerData().data(), originalLayers); |
||||
CORRADE_COMPARE(copy.layerCount(), 2); |
||||
|
||||
CORRADE_COMPARE(copy.attributeDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.attributeData().data(), originalAttributes); |
||||
CORRADE_COMPARE(copy.attributeCount(0), 2); |
||||
CORRADE_COMPARE(copy.attributeCount(1), 1); |
||||
CORRADE_COMPARE(copy.attribute<bool>(0, Trade::MaterialAttribute::AlphaBlend), true); |
||||
CORRADE_COMPARE(copy.attribute<Color4>(0, Trade::MaterialAttribute::BaseColor), 0xff3366ff_rgbaf); |
||||
CORRADE_COMPARE(copy.attribute<Containers::StringView>(1, "baseColorTextureName"), "yesss.png"); |
||||
} |
||||
|
||||
void CopyTest::rvalueOwnedAttributesNoLayerData() { |
||||
Containers::Array<Trade::MaterialAttributeData> attributes{InPlaceInit, { |
||||
{Trade::MaterialAttribute::AlphaBlend, true}, |
||||
{Trade::MaterialAttribute::BaseColor, 0xff3366ff_rgbaf}, |
||||
{"baseColorTextureName", "yesss.png"}, |
||||
}}; |
||||
Containers::Array<UnsignedInt> layers{InPlaceInit, {2, 3}}; |
||||
const void* originalAttributes = attributes.data(); |
||||
|
||||
Trade::MaterialData copy = MaterialTools::copy(Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, std::move(attributes), reinterpret_cast<void*>(0xdeadbeef)}); |
||||
CORRADE_COMPARE(copy.types(), Trade::MaterialType::PbrMetallicRoughness); |
||||
CORRADE_COMPARE(copy.importerState(), reinterpret_cast<void*>(0xdeadbeef)); |
||||
|
||||
CORRADE_COMPARE(copy.layerDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.layerCount(), 1); |
||||
CORRADE_COMPARE(copy.layerData().size(), 0); |
||||
CORRADE_COMPARE(copy.layerData(), nullptr); |
||||
|
||||
CORRADE_COMPARE(copy.attributeDataFlags(), Trade::DataFlag::Owned|Trade::DataFlag::Mutable); |
||||
CORRADE_COMPARE(copy.attributeData().data(), originalAttributes); |
||||
CORRADE_COMPARE(copy.attributeCount(), 3); |
||||
CORRADE_COMPARE(copy.attribute<bool>(Trade::MaterialAttribute::AlphaBlend), true); |
||||
CORRADE_COMPARE(copy.attribute<Color4>(Trade::MaterialAttribute::BaseColor), 0xff3366ff_rgbaf); |
||||
CORRADE_COMPARE(copy.attribute<Containers::StringView>("baseColorTextureName"), "yesss.png"); |
||||
} |
||||
|
||||
}}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::MaterialTools::Test::CopyTest) |
||||
Loading…
Reference in new issue