diff --git a/src/Magnum/TextureTools/Atlas.cpp b/src/Magnum/TextureTools/Atlas.cpp index 6ae97c1fb..19bfdab9c 100644 --- a/src/Magnum/TextureTools/Atlas.cpp +++ b/src/Magnum/TextureTools/Atlas.cpp @@ -80,8 +80,8 @@ Containers::Pair> atlasArrayPowerOfTwo(const Ve Containers::Array sortedSizes{NoInit, sizes.size()}; for(std::size_t i = 0; i != sizes.size(); ++i) { const Vector2i size = sizes[i]; - CORRADE_ASSERT(size.product() && size.x() == size.y() && (size & (size - Vector2i{1})).isZero(), - "TextureTools::atlasArrayPowerOfTwo(): expected size" << i << "to be a non-zero power-of-two square, got" << Debug::packed << size, {}); + CORRADE_ASSERT(size.product() && size.x() == size.y() && (size & (size - Vector2i{1})).isZero() && size <= layerSize, + "TextureTools::atlasArrayPowerOfTwo(): expected size" << i << "to be a non-zero power-of-two square not larger than" << Debug::packed << layerSize << "but got" << Debug::packed << size, {}); sortedSizes[i].xy() = size; sortedSizes[i].z() = i; diff --git a/src/Magnum/TextureTools/Atlas.h b/src/Magnum/TextureTools/Atlas.h index 1b280b246..d1c5a9f1e 100644 --- a/src/Magnum/TextureTools/Atlas.h +++ b/src/Magnum/TextureTools/Atlas.h @@ -60,8 +60,9 @@ std::vector MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize coordinate being the layer index @m_since_latest -Both @p layerSize and all items in @p sizes are expected to be non-zero, square -and power-of-two. With such constraints the packing is optimal with no wasted +The @p layerSize is expected to be non-zero, square and power-of-two. All items +in @p sizes are expected to be non-zero, square, power-of-two and not larger +than @p layerSize. With such constraints the packing is optimal with no wasted space in all but the last layer. Setting @p layerSize to the size of the largest texture in the set will lead to the least wasted space in the last layer. diff --git a/src/Magnum/TextureTools/Test/AtlasTest.cpp b/src/Magnum/TextureTools/Test/AtlasTest.cpp index 8027c97ea..d652a38cb 100644 --- a/src/Magnum/TextureTools/Test/AtlasTest.cpp +++ b/src/Magnum/TextureTools/Test/AtlasTest.cpp @@ -70,14 +70,25 @@ const struct { {0, 2, 7, 13, 11, 3, 4, 5, 8, 14, 1, 9, 6, 12, 10}}, }; +const struct { + const char* name; + Vector2i size; + const char* message; +} ArrayPowerOfTwoWrongLayerSizeData[]{ + {"non-power-of-two", {128, 127}, "{128, 127}"}, + {"non-square", {128, 256}, "{128, 256}"}, + {"zero", {1024, 0}, "{1024, 0}"}, +}; + const struct { const char* name; Vector2i size; const char* message; } ArrayPowerOfTwoWrongSizeData[]{ + {"larger than size", {512, 512}, "{512, 512}"}, {"non-power-of-two", {128, 127}, "{128, 127}"}, {"non-square", {128, 256}, "{128, 256}"}, - {"zero", {1024, 0}, "{1024, 0}"} + {"zero", {1024, 0}, "{1024, 0}"}, }; AtlasTest::AtlasTest() { @@ -95,8 +106,10 @@ AtlasTest::AtlasTest() { addTests({&AtlasTest::arrayPowerOfTwoMoreLayers}); - addInstancedTests({&AtlasTest::arrayPowerOfTwoWrongLayerSize, - &AtlasTest::arrayPowerOfTwoWrongSize}, + addInstancedTests({&AtlasTest::arrayPowerOfTwoWrongLayerSize}, + Containers::arraySize(ArrayPowerOfTwoWrongLayerSizeData)); + + addInstancedTests({&AtlasTest::arrayPowerOfTwoWrongSize}, Containers::arraySize(ArrayPowerOfTwoWrongSizeData)); } @@ -274,7 +287,7 @@ void AtlasTest::arrayPowerOfTwoMoreLayers() { } void AtlasTest::arrayPowerOfTwoWrongLayerSize() { - auto&& data = ArrayPowerOfTwoWrongSizeData[testCaseInstanceId()]; + auto&& data = ArrayPowerOfTwoWrongLayerSizeData[testCaseInstanceId()]; setTestCaseDescription(data.name); CORRADE_SKIP_IF_NO_ASSERT(); @@ -298,7 +311,7 @@ void AtlasTest::arrayPowerOfTwoWrongSize() { {128, 128}, data.size }); - CORRADE_COMPARE(out.str(), Utility::formatString("TextureTools::atlasArrayPowerOfTwo(): expected size 2 to be a non-zero power-of-two square, got {}\n", data.message)); + CORRADE_COMPARE(out.str(), Utility::formatString("TextureTools::atlasArrayPowerOfTwo(): expected size 2 to be a non-zero power-of-two square not larger than {{256, 256}} but got {}\n", data.message)); } }}}}