Browse Source

TextureTools: support padding in atlas().

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
a9f62e3f1c
  1. 9
      src/TextureTools/Atlas.cpp
  2. 8
      src/TextureTools/Atlas.h
  3. 24
      src/TextureTools/Test/AtlasTest.cpp

9
src/TextureTools/Atlas.cpp

@ -20,7 +20,7 @@
namespace Magnum { namespace TextureTools { namespace Magnum { namespace TextureTools {
std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes) { std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes, const Vector2i& padding) {
if(sizes.empty()) return {}; if(sizes.empty()) return {};
/* Size of largest texture */ /* Size of largest texture */
@ -31,10 +31,11 @@ std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vecto
std::vector<Rectanglei> atlas; std::vector<Rectanglei> atlas;
/* Columns and rows */ /* 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()) { if(std::size_t(gridSize.product()) < sizes.size()) {
Error() << "TextureTools::atlas(): requested atlas size" << atlasSize 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."; << "textures. Generated atlas will be empty.";
return atlas; return atlas;
} }
@ -43,7 +44,7 @@ std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vecto
atlas.reserve(sizes.size()); atlas.reserve(sizes.size());
for(std::size_t i = 0; i != sizes.size(); ++i) for(std::size_t i = 0; i != sizes.size(); ++i)
atlas.push_back(Rectanglei::fromSize(Vector2i(i%gridSize.x(), i/gridSize.x())*maxSize, sizes[i])); atlas.push_back(Rectanglei::fromSize(Vector2i(i%gridSize.x(), i/gridSize.x())*paddedSize+padding, sizes[i]));
return atlas; return atlas;
} }

8
src/TextureTools/Atlas.h

@ -21,6 +21,7 @@
#include <vector> #include <vector>
#include "Math/Vector2.h"
#include "Magnum.h" #include "Magnum.h"
#include "magnumTextureToolsVisibility.h" #include "magnumTextureToolsVisibility.h"
@ -31,11 +32,16 @@ namespace Magnum { namespace TextureTools {
@brief Pack textures into texture atlas @brief Pack textures into texture atlas
@param atlasSize Size of resulting atlas @param atlasSize Size of resulting atlas
@param sizes Sizes of all textures in the 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 Packs many small textures into one larger. If the textures cannot be packed
into required size, empty vector is returned. 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<Rectanglei> MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes); std::vector<Rectanglei> MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector<Vector2i>& sizes, const Vector2i& padding = Vector2i());
}} }}

24
src/TextureTools/Test/AtlasTest.cpp

@ -26,12 +26,14 @@ class AtlasTest: public Corrade::TestSuite::Tester {
explicit AtlasTest(); explicit AtlasTest();
void create(); void create();
void createPadding();
void createEmpty(); void createEmpty();
void createTooSmall(); void createTooSmall();
}; };
AtlasTest::AtlasTest() { AtlasTest::AtlasTest() {
addTests(&AtlasTest::create, addTests(&AtlasTest::create,
&AtlasTest::createPadding,
&AtlasTest::createEmpty, &AtlasTest::createEmpty,
&AtlasTest::createTooSmall); &AtlasTest::createTooSmall);
} }
@ -50,6 +52,20 @@ void AtlasTest::create() {
Rectanglei::fromSize({0, 25}, {23, 25})})); Rectanglei::fromSize({0, 25}, {23, 25})}));
} }
void AtlasTest::createPadding() {
std::vector<Rectanglei> atlas = TextureTools::atlas({64, 64}, {
{8, 16},
{28, 13},
{19, 23}
}, {2, 1});
CORRADE_COMPARE(atlas.size(), 3);
CORRADE_COMPARE(atlas, (std::vector<Rectanglei>{
Rectanglei::fromSize({2, 1}, {8, 16}),
Rectanglei::fromSize({34, 1}, {28, 13}),
Rectanglei::fromSize({2, 26}, {19, 23})}));
}
void AtlasTest::createEmpty() { void AtlasTest::createEmpty() {
std::vector<Rectanglei> atlas = TextureTools::atlas({}, {}); std::vector<Rectanglei> atlas = TextureTools::atlas({}, {});
CORRADE_VERIFY(atlas.empty()); CORRADE_VERIFY(atlas.empty());
@ -60,10 +76,10 @@ void AtlasTest::createTooSmall() {
Error::setOutput(&o); Error::setOutput(&o);
std::vector<Rectanglei> atlas = TextureTools::atlas({64, 32}, { std::vector<Rectanglei> atlas = TextureTools::atlas({64, 32}, {
{12, 18}, {8, 16},
{25, 15}, {21, 13},
{23, 31} {19, 29}
}); }, {2, 1});
CORRADE_VERIFY(atlas.empty()); 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"); 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");
} }

Loading…
Cancel
Save