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 {
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 {};
/* Size of largest texture */
@ -31,10 +31,11 @@ std::vector<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vecto
std::vector<Rectanglei> 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<Rectanglei> atlas(const Vector2i& atlasSize, const std::vector<Vecto
atlas.reserve(sizes.size());
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;
}

8
src/TextureTools/Atlas.h

@ -21,6 +21,7 @@
#include <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<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();
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<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() {
std::vector<Rectanglei> atlas = TextureTools::atlas({}, {});
CORRADE_VERIFY(atlas.empty());
@ -60,10 +76,10 @@ void AtlasTest::createTooSmall() {
Error::setOutput(&o);
std::vector<Rectanglei> 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");
}

Loading…
Cancel
Save