diff --git a/CMakeLists.txt b/CMakeLists.txt index a0de8a35f..d0398a9fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ cmake_dependent_option(WITH_PHYSICS "Build Physics library" OFF "NOT WITH_EVERYT cmake_dependent_option(WITH_PRIMITIVES "Builf Primitives library" OFF "NOT WITH_EVERYTHING;NOT WITH_DEBUGTOOLS" ON) cmake_dependent_option(WITH_SCENEGRAPH "Build SceneGraph library" OFF "NOT WITH_EVERYTHING;NOT WITH_DEBUGTOOLS" ON) cmake_dependent_option(WITH_SHADERS "Build Shaders library" OFF "NOT WITH_EVERYTHING;NOT WITH_DEBUGTOOLS" ON) +cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" OFF "NOT WITH_EVERYTHING" ON) cmake_dependent_option(WITH_MAGNUMINFO "Build magnum-info utility" OFF "NOT WITH_EVERYTHING" ON) diff --git a/doc/namespaces.dox b/doc/namespaces.dox index 915f3c0b2..90d800d8b 100644 --- a/doc/namespaces.dox +++ b/doc/namespaces.dox @@ -104,6 +104,15 @@ Collision detection system and rigid body objects. See @ref collision-detection for introduction. */ +/** @dir TextureTools + * @brief Namespace Magnum::TextureTools + */ +/** @namespace Magnum::TextureTools +@brief %Texture tools + +Tools for generating, compressing and optimizing textures. +*/ + /** @dir Trade * @brief Namespace Magnum::Trade */ diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index be3423bc4..ee5437f6e 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -22,6 +22,7 @@ # Primitives - Library with stock geometric primitives (static) # SceneGraph - Scene graph library # Shaders - Library with stock shaders +# TextureTools - TextureTools library # GlxApplication - GLX application (depends on X11 libraries) # XEglApplication - X/EGL application (depends on EGL and X11 libraries) # WindowlessGlxApplication - Windowless GLX application (depends on X11 @@ -197,6 +198,11 @@ foreach(component ${Magnum_FIND_COMPONENTS}) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES PhongShader.h) endif() + # TextureTools library + if(${component} STREQUAL TextureTools) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Atlas.h) + endif() + # Try to find the includes if(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES) find_path(_MAGNUM_${_COMPONENT}_INCLUDE_DIR diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed702f4f8..18619eac3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -162,6 +162,10 @@ if(WITH_SHADERS) add_subdirectory(Shaders) endif() +if(WITH_TEXTURETOOLS) + add_subdirectory(TextureTools) +endif() + if(BUILD_TESTS) enable_testing() diff --git a/src/TextureTools/Atlas.cpp b/src/TextureTools/Atlas.cpp new file mode 100644 index 000000000..336777880 --- /dev/null +++ b/src/TextureTools/Atlas.cpp @@ -0,0 +1,53 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "Atlas.h" + +#include "Math/Geometry/Rectangle.h" + +namespace Magnum { namespace TextureTools { + +std::vector atlas(const Vector2i& atlasSize, const std::vector& sizes) { + if(sizes.empty()) return {}; + + /* Size of largest texture */ + Vector2i maxSize; + for(const Vector2i& size: sizes) { + /** @todo max() for vector types */ + if(size.x() > maxSize.x()) maxSize.x() = size.x(); + if(size.y() > maxSize.y()) maxSize.y() = size.y(); + } + + std::vector atlas; + + /* Columns and rows */ + Vector2i gridSize = atlasSize/maxSize; + if(std::size_t(gridSize.product()) < sizes.size()) { + Error() << "TextureTools::Atlas::create(): requested atlas size" + << atlasSize << "is too small to fit" << sizes.size() + << maxSize << "textures. Generated atlas will be empty."; + return atlas; + } + + /** @todo actual magic implementation, not this joke */ + + 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])); + + return atlas; +} + +}} diff --git a/src/TextureTools/Atlas.h b/src/TextureTools/Atlas.h new file mode 100644 index 000000000..d91b5f1e3 --- /dev/null +++ b/src/TextureTools/Atlas.h @@ -0,0 +1,42 @@ +#ifndef Magnum_TextureTools_Atlas_h +#define Magnum_TextureTools_Atlas_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Function Magnum::TextureTools::atlas() + */ + +#include + +#include "Magnum.h" + +#include "magnumTextureToolsVisibility.h" + +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 + +Packs many small textures into one larger. If the textures cannot be packed +into required size, empty vector is returned. +*/ +std::vector MAGNUM_TEXTURETOOLS_EXPORT atlas(const Vector2i& atlasSize, const std::vector& sizes); + +}} + +#endif diff --git a/src/TextureTools/CMakeLists.txt b/src/TextureTools/CMakeLists.txt new file mode 100644 index 000000000..e7bbd4fa6 --- /dev/null +++ b/src/TextureTools/CMakeLists.txt @@ -0,0 +1,19 @@ +set(MagnumTextureTools_SRCS + Atlas.cpp) + +set(MagnumTextureTools_HEADERS + Atlas.h + + magnumTextureToolsVisibility.h) + +add_library(MagnumTextureTools SHARED ${MagnumTextureTools_SRCS}) + +target_link_libraries(MagnumTextureTools Magnum) + +install(TARGETS MagnumTextureTools DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) +install(FILES ${MagnumTextureTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/TextureTools) + +if(BUILD_TESTS) + enable_testing() + add_subdirectory(Test) +endif() diff --git a/src/TextureTools/Test/AtlasTest.cpp b/src/TextureTools/Test/AtlasTest.cpp new file mode 100644 index 000000000..01a7e53ce --- /dev/null +++ b/src/TextureTools/Test/AtlasTest.cpp @@ -0,0 +1,65 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "AtlasTest.h" + +#include + +#include "Math/Geometry/Rectangle.h" +#include "TextureTools/Atlas.h" + +CORRADE_TEST_MAIN(Magnum::TextureTools::Test::AtlasTest) + +namespace Magnum { namespace TextureTools { namespace Test { + +AtlasTest::AtlasTest() { + addTests(&AtlasTest::create, + &AtlasTest::createEmpty, + &AtlasTest::createTooSmall); +} + +void AtlasTest::create() { + std::vector atlas = TextureTools::atlas({64, 64}, { + {12, 18}, + {32, 15}, + {23, 25} + }); + + CORRADE_COMPARE(atlas.size(), 3); + CORRADE_COMPARE(atlas, (std::vector{ + Rectanglei::fromSize({0, 0}, {12, 18}), + Rectanglei::fromSize({32, 0}, {32, 15}), + Rectanglei::fromSize({0, 25}, {23, 25})})); +} + +void AtlasTest::createEmpty() { + std::vector atlas = TextureTools::atlas({}, {}); + CORRADE_VERIFY(atlas.empty()); +} + +void AtlasTest::createTooSmall() { + std::ostringstream o; + Error::setOutput(&o); + + std::vector atlas = TextureTools::atlas({64, 32}, { + {12, 18}, + {25, 15}, + {23, 31} + }); + CORRADE_VERIFY(atlas.empty()); + CORRADE_COMPARE(o.str(), "TextureTools::Atlas::create(): requested atlas size Vector(64, 32) is too small to fit 3 Vector(25, 31) textures. Generated atlas will be empty.\n"); +} + +}}} diff --git a/src/TextureTools/Test/AtlasTest.h b/src/TextureTools/Test/AtlasTest.h new file mode 100644 index 000000000..13c92aa27 --- /dev/null +++ b/src/TextureTools/Test/AtlasTest.h @@ -0,0 +1,33 @@ +#ifndef Magnum_TextureTools_Test_AtlasTest_h +#define Magnum_TextureTools_Test_AtlasTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace TextureTools { namespace Test { + +class AtlasTest: public Corrade::TestSuite::Tester { + public: + explicit AtlasTest(); + + void create(); + void createEmpty(); + void createTooSmall(); +}; + +}}} + +#endif diff --git a/src/TextureTools/Test/CMakeLists.txt b/src/TextureTools/Test/CMakeLists.txt new file mode 100644 index 000000000..4c4610b50 --- /dev/null +++ b/src/TextureTools/Test/CMakeLists.txt @@ -0,0 +1 @@ +corrade_add_test(TextureToolsAtlasTest AtlasTest.cpp LIBRARIES MagnumTextureTools) diff --git a/src/TextureTools/magnumTextureToolsVisibility.h b/src/TextureTools/magnumTextureToolsVisibility.h new file mode 100644 index 000000000..725041d71 --- /dev/null +++ b/src/TextureTools/magnumTextureToolsVisibility.h @@ -0,0 +1,28 @@ +#ifndef Magnum_TextureTools_magnumTextureToolsVisibility_h +#define Magnum_TextureTools_magnumTextureToolsVisibility_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#ifdef _WIN32 + #ifdef MagnumTextureTools_EXPORTS + #define MAGNUM_TEXTURETOOLS_EXPORT __declspec(dllexport) + #else + #define MAGNUM_TEXTURETOOLS_EXPORT __declspec(dllimport) + #endif +#else + #define MAGNUM_TEXTURETOOLS_EXPORT __attribute__ ((visibility ("default"))) +#endif + +#endif