diff --git a/src/TextureTools/Atlas.cpp b/src/TextureTools/Atlas.cpp index 101123986..2d4b87b30 100644 --- a/src/TextureTools/Atlas.cpp +++ b/src/TextureTools/Atlas.cpp @@ -20,7 +20,7 @@ namespace Magnum { namespace TextureTools { -std::vector atlas(const Vector2i& atlasSize, const std::vector& sizes) { +std::vector atlas(const Vector2i& atlasSize, const std::vector& sizes, const Vector2i& padding) { if(sizes.empty()) return {}; /* Size of largest texture */ @@ -31,10 +31,11 @@ std::vector atlas(const Vector2i& atlasSize, const std::vector atlas; /* Columns and rows */ - const Vector2i gridSize = atlasSize/maxSize; + const Vector2i paddedSize = maxSize+2*padding; + const Vector2i gridSize = atlasSize/paddedSize; if(std::size_t(gridSize.product()) < sizes.size()) { Error() << "TextureTools::atlas(): requested atlas size" << atlasSize - << "is too small to fit" << sizes.size() << maxSize + << "is too small to fit" << sizes.size() << paddedSize << "textures. Generated atlas will be empty."; return atlas; } @@ -43,7 +44,7 @@ std::vector atlas(const Vector2i& atlasSize, const std::vector +#include "Math/Vector2.h" #include "Magnum.h" #include "magnumTextureToolsVisibility.h" @@ -31,11 +32,16 @@ namespace Magnum { namespace TextureTools { @brief Pack textures into texture atlas @param atlasSize Size of resulting atlas @param sizes Sizes of all textures in the atlas +@param padding Padding around each texture Packs many small textures into one larger. If the textures cannot be packed into required size, empty vector is returned. + +Padding is added twice to each size and the atlas is laid out so the padding +don't overlap. Returned sizes are the same as original sizes, i.e. without the +padding. */ -std::vector MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector& sizes); +std::vector MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector& sizes, const Vector2i& padding = Vector2i()); }} diff --git a/src/TextureTools/Test/AtlasTest.cpp b/src/TextureTools/Test/AtlasTest.cpp index d45734b80..9525f1a0f 100644 --- a/src/TextureTools/Test/AtlasTest.cpp +++ b/src/TextureTools/Test/AtlasTest.cpp @@ -26,12 +26,14 @@ class AtlasTest: public Corrade::TestSuite::Tester { explicit AtlasTest(); void create(); + void createPadding(); void createEmpty(); void createTooSmall(); }; AtlasTest::AtlasTest() { addTests(&AtlasTest::create, + &AtlasTest::createPadding, &AtlasTest::createEmpty, &AtlasTest::createTooSmall); } @@ -50,6 +52,20 @@ void AtlasTest::create() { Rectanglei::fromSize({0, 25}, {23, 25})})); } +void AtlasTest::createPadding() { + std::vector atlas = TextureTools::atlas({64, 64}, { + {8, 16}, + {28, 13}, + {19, 23} + }, {2, 1}); + + CORRADE_COMPARE(atlas.size(), 3); + CORRADE_COMPARE(atlas, (std::vector{ + Rectanglei::fromSize({2, 1}, {8, 16}), + Rectanglei::fromSize({34, 1}, {28, 13}), + Rectanglei::fromSize({2, 26}, {19, 23})})); +} + void AtlasTest::createEmpty() { std::vector atlas = TextureTools::atlas({}, {}); CORRADE_VERIFY(atlas.empty()); @@ -60,10 +76,10 @@ void AtlasTest::createTooSmall() { Error::setOutput(&o); std::vector atlas = TextureTools::atlas({64, 32}, { - {12, 18}, - {25, 15}, - {23, 31} - }); + {8, 16}, + {21, 13}, + {19, 29} + }, {2, 1}); CORRADE_VERIFY(atlas.empty()); CORRADE_COMPARE(o.str(), "TextureTools::atlas(): requested atlas size Vector(64, 32) is too small to fit 3 Vector(25, 31) textures. Generated atlas will be empty.\n"); }