From bf4bf9eac5f8a3ae22393fda9423ed7b066faf71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 13 Apr 2019 18:05:52 +0200 Subject: [PATCH] MeshTools: 100% code coverage for compile(). There's some bug in there, so let's test it all. --- src/Magnum/MeshTools/Test/CMakeLists.txt | 60 +++ src/Magnum/MeshTools/Test/CompileGLTest.cpp | 459 ++++++++++++++++++ .../Test/CompileTestFiles/color2D.tga | Bin 0 -> 4114 bytes .../Test/CompileTestFiles/color3D.tga | Bin 0 -> 4114 bytes .../Test/CompileTestFiles/flat2D.tga | Bin 0 -> 4114 bytes .../Test/CompileTestFiles/flat3D.tga | Bin 0 -> 4114 bytes .../MeshTools/Test/CompileTestFiles/phong.tga | Bin 0 -> 4114 bytes .../Test/CompileTestFiles/textured2D.tga | Bin 0 -> 4114 bytes .../Test/CompileTestFiles/textured3D.tga | Bin 0 -> 4114 bytes src/Magnum/MeshTools/Test/configure.h.cmake | 28 ++ 10 files changed, 547 insertions(+) create mode 100644 src/Magnum/MeshTools/Test/CompileGLTest.cpp create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/color2D.tga create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/color3D.tga create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/flat2D.tga create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/flat3D.tga create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/phong.tga create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/textured2D.tga create mode 100644 src/Magnum/MeshTools/Test/CompileTestFiles/textured3D.tga create mode 100644 src/Magnum/MeshTools/Test/configure.h.cmake diff --git a/src/Magnum/MeshTools/Test/CMakeLists.txt b/src/Magnum/MeshTools/Test/CMakeLists.txt index 82e45b6ce..103552150 100644 --- a/src/Magnum/MeshTools/Test/CMakeLists.txt +++ b/src/Magnum/MeshTools/Test/CMakeLists.txt @@ -61,10 +61,70 @@ if(WITH_PRIMITIVES) endif() if(BUILD_GL_TESTS) + # Otherwise CMake complains that Corrade::PluginManager is not found + find_package(Corrade REQUIRED PluginManager) + corrade_add_resource(FullScreenTriangleGLTest_RESOURCES resources.conf) set_target_properties(FullScreenTriangleGLTest_RESOURCES-dependencies PROPERTIES FOLDER "Magnum/MeshTools/Test") corrade_add_test(MeshToolsFullScreenTriangleGLTest FullScreenTriangleGLTest.cpp ${FullScreenTriangleGLTest_RESOURCES} LIBRARIES MagnumMeshTools MagnumGL MagnumOpenGLTester) + + if(CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_ANDROID) + set(COMPILEGLTEST_TEST_DIR ".") + else() + set(COMPILEGLTEST_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/CompileTestFiles) + endif() + + # CMake before 3.8 has broken $ expressions for iOS (see + # https://gitlab.kitware.com/cmake/cmake/merge_requests/404) and since + # Corrade doesn't support dynamic plugins on iOS, this sorta works around + # that. Should be revisited when updating Travis to newer Xcode (current + # has CMake 3.6). + if(NOT BUILD_PLUGINS_STATIC) + if(WITH_ANYIMAGEIMPORTER) + set(ANYIMAGEIMPORTER_PLUGIN_FILENAME $) + endif() + if(WITH_TGAIMPORTER) + set(TGAIMPORTER_PLUGIN_FILENAME $) + endif() + + # First replace ${} variables, then $<> generator expressions + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h.in) + file(GENERATE OUTPUT $/configure.h + INPUT ${CMAKE_CURRENT_BINARY_DIR}/configure.h.in) + else() + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + endif() + + corrade_add_test(MeshToolsCompileGLTest CompileGLTest.cpp + LIBRARIES + MagnumDebugTools + MagnumGL + MagnumOpenGLTester + MagnumMeshTools + MagnumShaders + FILES + CompileTestFiles/color2D.tga + CompileTestFiles/color3D.tga + CompileTestFiles/flat2D.tga + CompileTestFiles/flat3D.tga + CompileTestFiles/phong.tga + CompileTestFiles/textured2D.tga + CompileTestFiles/textured3D.tga) + set_target_properties(MeshToolsCompileGLTest PROPERTIES FOLDER "Magnum/MeshTools/Test") + if(NOT BUILD_PLUGINS_STATIC) + target_include_directories(MeshToolsCompileGLTest PRIVATE $) + else() + target_include_directories(MeshToolsCompileGLTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + if(WITH_ANYIMAGEIMPORTER) + target_link_libraries(MeshToolsCompileGLTest PRIVATE AnyImageImporter) + endif() + if(WITH_TGAIMPORTER) + target_link_libraries(MeshToolsCompileGLTest PRIVATE TgaImporter) + endif() + endif() endif() diff --git a/src/Magnum/MeshTools/Test/CompileGLTest.cpp b/src/Magnum/MeshTools/Test/CompileGLTest.cpp new file mode 100644 index 000000000..af1e1c94c --- /dev/null +++ b/src/Magnum/MeshTools/Test/CompileGLTest.cpp @@ -0,0 +1,459 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include + +#include "Magnum/Image.h" +#include "Magnum/Mesh.h" +#include "Magnum/PixelFormat.h" +#include "Magnum/DebugTools/CompareImage.h" +#include "Magnum/GL/Mesh.h" +#include "Magnum/GL/OpenGLTester.h" +#include "Magnum/GL/Framebuffer.h" +#include "Magnum/GL/Renderbuffer.h" +#include "Magnum/GL/RenderbufferFormat.h" +#include "Magnum/GL/Texture.h" +#include "Magnum/GL/TextureFormat.h" +#include "Magnum/Math/Matrix4.h" +#include "Magnum/MeshTools/Compile.h" +#include "Magnum/MeshTools/Duplicate.h" +#include "Magnum/Shaders/Flat.h" +#include "Magnum/Shaders/Phong.h" +#include "Magnum/Shaders/VertexColor.h" +#include "Magnum/Trade/AbstractImporter.h" +#include "Magnum/Trade/MeshData2D.h" +#include "Magnum/Trade/MeshData3D.h" + +#include "configure.h" + +namespace Magnum { namespace MeshTools { namespace Test { namespace { + +enum class Flag { + NonIndexed = 1 << 0, + Normals = 1 << 1, + TextureCoordinates2D = 1 << 2, + Colors = 1 << 3 +}; + +typedef Containers::EnumSet Flags; +CORRADE_ENUMSET_OPERATORS(Flags) + +struct CompileGLTest: GL::OpenGLTester { + public: + explicit CompileGLTest(); + + void twoDimensions(); + void threeDimensions(); + + private: + PluginManager::Manager _manager{"nonexistent"}; + + Shaders::Flat2D _flat2D; + Shaders::Flat2D _flatTextured2D{Shaders::Flat2D::Flag::Textured}; + Shaders::Flat3D _flat3D; + Shaders::Flat3D _flatTextured3D{Shaders::Flat3D::Flag::Textured}; + Shaders::VertexColor2D _color2D; + Shaders::VertexColor3D _color3D; + Shaders::Phong _phong; + + GL::Renderbuffer _color; + GL::Framebuffer _framebuffer{{{}, {32, 32}}}; + GL::Texture2D _texture; +}; + +constexpr struct { + const char* name; + Flags flags; +} Data2D[] { + {"positions", {}}, + {"positions, nonindexed", Flag::NonIndexed}, + {"positions + colors", Flag::Colors}, + {"positions + texture coordinates", Flag::TextureCoordinates2D}, + {"positions + texture coordinates + colors", Flag::TextureCoordinates2D|Flag::Colors} +}; + +constexpr struct { + const char* name; + Flags flags; +} Data3D[] { + {"positions", {}}, + {"positions, nonindexed", Flag::NonIndexed}, + {"positions + colors", Flag::Colors}, + {"positions + texcoords", Flag::TextureCoordinates2D}, + {"positions + texcoords + colors", Flag::TextureCoordinates2D|Flag::Colors}, + {"positions + normals", Flag::Normals}, + {"positions + normals + colors", Flag::Normals|Flag::Colors}, + {"positions + normals + texcoords", Flag::Normals|Flag::TextureCoordinates2D}, + {"positions + normals + texcoords + colors", Flag::Normals|Flag::TextureCoordinates2D|Flag::Colors} +}; + +using namespace Math::Literals; + +constexpr Color4ub ImageData[] { + 0xff000000_rgba, 0x80000000_rgba, 0x00008000_rgba, 0x0000ff00_rgba, + 0x80000000_rgba, 0xffffffff_rgba, 0xffffffff_rgba, 0x00008000_rgba, + 0x00800000_rgba, 0xffffffff_rgba, 0xffffffff_rgba, 0x00008000_rgba, + 0x00ff0000_rgba, 0x00800000_rgba, 0x00000080_rgba, 0x000000ff_rgba +}; + +CompileGLTest::CompileGLTest() { + addInstancedTests({&CompileGLTest::twoDimensions}, + Containers::arraySize(Data2D)); + + addInstancedTests({&CompileGLTest::threeDimensions}, + Containers::arraySize(Data3D)); + + /* Load the plugins directly from the build tree. Otherwise they're either + static and already loaded or not present in the build tree */ + #ifdef ANYIMAGEIMPORTER_PLUGIN_FILENAME + CORRADE_INTERNAL_ASSERT(_manager.load(ANYIMAGEIMPORTER_PLUGIN_FILENAME) & PluginManager::LoadState::Loaded); + #endif + #ifdef TGAIMPORTER_PLUGIN_FILENAME + CORRADE_INTERNAL_ASSERT(_manager.load(TGAIMPORTER_PLUGIN_FILENAME) & PluginManager::LoadState::Loaded); + #endif + + /* Set up the rendering */ + _color.setStorage( + #if !defined(MAGNUM_TARGET_GLES2) || !defined(MAGNUM_TARGET_WEBGL) + GL::RenderbufferFormat::RGBA8, + #else + GL::RenderbufferFormat::RGBA4, + #endif + {32, 32}); + _framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _color) + .bind(); + _texture + .setMinificationFilter(SamplerFilter::Linear) + .setMagnificationFilter(SamplerFilter::Linear) + .setWrapping(SamplerWrapping::ClampToEdge) + .setStorage(1, + #if !defined(MAGNUM_TARGET_GLES2) || !defined(MAGNUM_TARGET_WEBGL) + GL::TextureFormat::RGBA8, + #else + GL::TextureFormat::RGBA, + #endif + {4, 4}) + .setSubImage(0, {}, ImageView2D{PixelFormat::RGBA8Unorm, {4, 4}, ImageData}); +} + +void CompileGLTest::twoDimensions() { + auto&& data = Data2D[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + /* + 6-----7-----8 + | /| /| + | / | / | + |/ |/ | + 3-----4-----5 + | /| /| + | / | / | + |/ |/ | + 0-----1-----2 + */ + std::vector positions{ + {-0.75f, -0.75f}, + { 0.00f, -0.75f}, + { 0.75f, -0.75f}, + + {-0.75f, 0.0f}, + { 0.00f, 0.0f}, + { 0.75f, 0.0f}, + + {-0.75f, 0.75f}, + { 0.0f, 0.75f}, + { 0.75f, 0.75f} + }; + + std::vector> textureCoordinates2D; + if(data.flags & Flag::TextureCoordinates2D) textureCoordinates2D.push_back(std::vector{ + {0.0f, 0.0f}, + {0.5f, 0.0f}, + {1.0f, 0.0f}, + + {0.0f, 0.5f}, + {0.5f, 0.5f}, + {1.0f, 0.5f}, + + {0.0f, 1.0f}, + {0.5f, 1.0f}, + {1.0f, 1.0f} + }); + + std::vector> colors; + if(data.flags & Flag::Colors) colors.push_back(std::vector { + 0x00ff00_rgbf, + 0x808000_rgbf, + 0xff0000_rgbf, + + 0x00ff80_rgbf, + 0x808080_rgbf, + 0xff0080_rgbf, + + 0x00ffff_rgbf, + 0x8080ff_rgbf, + 0xff00ff_rgbf + }); + + std::vector indices{ + 0, 1, 4, 0, 4, 3, + 1, 2, 5, 1, 5, 4, + 3, 4, 7, 3, 7, 6, + 4, 5, 8, 4, 8, 7 + }; + + /* Duplicate positions if data are non-indexed. Testing only positions + alone ATM, don't bother with other attribs. */ + if(data.flags & Flag::NonIndexed) { + CORRADE_INTERNAL_ASSERT(textureCoordinates2D.empty()); + CORRADE_INTERNAL_ASSERT(colors.empty()); + positions = duplicate(indices, positions); + indices.clear(); + } + + MAGNUM_VERIFY_NO_GL_ERROR(); + + GL::Mesh mesh = compile(Trade::MeshData2D{MeshPrimitive::Triangles, indices, {positions}, textureCoordinates2D, colors}); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found."); + + /* Check with the flat shader, it should always work */ + { + _framebuffer.clear(GL::FramebufferClear::Color); + _flat2D.setColor(0xff3366_rgbf); + mesh.draw(_flat2D); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "flat2D.tga"), + (DebugTools::CompareImageToFile{_manager})); + } + + /* Check with the colored shader, if we have colors */ + if(data.flags & Flag::Colors) { + _framebuffer.clear(GL::FramebufferClear::Color); + mesh.draw(_color2D); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "color2D.tga"), + (DebugTools::CompareImageToFile{_manager})); + } + + /* Check with the textured shader, if we have texture coords */ + if(data.flags & Flag::TextureCoordinates2D) { + _framebuffer.clear(GL::FramebufferClear::Color); + _flatTextured2D.bindTexture(_texture); + mesh.draw(_flatTextured2D); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "textured2D.tga"), + /* SwiftShader has some minor off-by-one precision differences */ + (DebugTools::CompareImageToFile{_manager, 0.75f, 0.0906f})); + } +} + +void CompileGLTest::threeDimensions() { + auto&& data = Data3D[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + /* + 6-----7-----8 + | /| /| + | / | / | + |/ |/ | + 3-----4-----5 + | /| /| + | / | / | + |/ |/ | + 0-----1-----2 + */ + std::vector positions{ + {-0.75f, -0.75f, -0.35f}, + { 0.00f, -0.75f, -0.25f}, + { 0.75f, -0.75f, -0.35f}, + + {-0.75f, 0.00f, -0.25f}, + { 0.00f, 0.00f, 0.00f}, + { 0.75f, 0.00f, -0.25f}, + + {-0.75f, 0.75f, -0.35f}, + { 0.0f, 0.75f, -0.25f}, + { 0.75f, 0.75f, -0.35f} + }; + + std::vector> normals; + if(data.flags & Flag::Normals) normals.push_back(std::vector{ + Vector3{-0.5f, -0.5f, 1.0f}.normalized(), + Vector3{ 0.0f, -0.5f, 1.0f}.normalized(), + Vector3{ 0.5f, -0.5f, 1.0f}.normalized(), + + Vector3{-0.5f, 0.0f, 1.0f}.normalized(), + Vector3{ 0.0f, 0.0f, 1.0f}.normalized(), + Vector3{ 0.5f, 0.0f, 1.0f}.normalized(), + + Vector3{-0.5f, 0.5f, 1.0f}.normalized(), + Vector3{ 0.0f, 0.5f, 1.0f}.normalized(), + Vector3{ 0.5f, 0.5f, 1.0f}.normalized(), + }); + + std::vector> textureCoordinates2D; + if(data.flags & Flag::TextureCoordinates2D) textureCoordinates2D.push_back(std::vector{ + {0.0f, 0.0f}, + {0.5f, 0.0f}, + {1.0f, 0.0f}, + + {0.0f, 0.5f}, + {0.5f, 0.5f}, + {1.0f, 0.5f}, + + {0.0f, 1.0f}, + {0.5f, 1.0f}, + {1.0f, 1.0f} + }); + + std::vector> colors; + if(data.flags & Flag::Colors) colors.push_back(std::vector { + 0x00ff00_rgbf, + 0x808000_rgbf, + 0xff0000_rgbf, + + 0x00ff80_rgbf, + 0x808080_rgbf, + 0xff0080_rgbf, + + 0x00ffff_rgbf, + 0x8080ff_rgbf, + 0xff00ff_rgbf + }); + + std::vector indices{ + 0, 1, 4, 0, 4, 3, + 1, 2, 5, 1, 5, 4, + 3, 4, 7, 3, 7, 6, + 4, 5, 8, 4, 8, 7 + }; + + /* Duplicate positions if data are non-indexed. Testing only positions + alone ATM, don't bother with other attribs. */ + if(data.flags & Flag::NonIndexed) { + CORRADE_INTERNAL_ASSERT(normals.empty()); + CORRADE_INTERNAL_ASSERT(textureCoordinates2D.empty()); + CORRADE_INTERNAL_ASSERT(colors.empty()); + positions = duplicate(indices, positions); + indices.clear(); + } + + MAGNUM_VERIFY_NO_GL_ERROR(); + + GL::Mesh mesh = compile(Trade::MeshData3D{MeshPrimitive::Triangles, indices, {positions}, normals, textureCoordinates2D, colors}); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found."); + + Matrix4 projection = Matrix4::perspectiveProjection(45.0_degf, 1.0f, 0.1f, 10.0f); + Matrix4 transformation = Matrix4::translation(Vector3::zAxis(-2.0f)); + + /* Check with the flat shader, it should always work */ + { + _framebuffer.clear(GL::FramebufferClear::Color); + _flat3D + .setTransformationProjectionMatrix(projection*transformation) + .setColor(0x6633ff_rgbf); + mesh.draw(_flat3D); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "flat3D.tga"), + (DebugTools::CompareImageToFile{_manager})); + } + + /* Check with the phong shader, if we have normals */ + if(data.flags & Flag::Normals) { + _framebuffer.clear(GL::FramebufferClear::Color); + _phong + .setDiffuseColor(0x33ff66_rgbf) + .setTransformationMatrix(transformation) + .setNormalMatrix(transformation.rotationScaling()) + .setProjectionMatrix(projection); + mesh.draw(_phong); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "phong.tga"), + /* SwiftShader has some minor off-by-one precision differences */ + (DebugTools::CompareImageToFile{_manager, 0.5f, 0.0113f})); + } + + /* Check with the colored shader, if we have colors */ + if(data.flags & Flag::Colors) { + _framebuffer.clear(GL::FramebufferClear::Color); + _color3D + .setTransformationProjectionMatrix(projection*transformation); + mesh.draw(_color3D); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "color3D.tga"), + /* SwiftShader has some minor off-by-one precision differences */ + (DebugTools::CompareImageToFile{_manager, 0.5f, 0.0162f})); + } + + /* Check with the textured shader, if we have texture coords */ + if(data.flags & Flag::TextureCoordinates2D) { + _framebuffer.clear(GL::FramebufferClear::Color); + _flatTextured3D + .setTransformationProjectionMatrix(projection*transformation) + .bindTexture(_texture); + mesh.draw(_flatTextured3D); + + MAGNUM_VERIFY_NO_GL_ERROR(); + CORRADE_COMPARE_WITH( + _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), + Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "textured3D.tga"), + /* SwiftShader has some minor off-by-one precision differences */ + (DebugTools::CompareImageToFile{_manager, 1.0f, 0.0948f})); + } +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::MeshTools::Test::CompileGLTest) diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/color2D.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/color2D.tga new file mode 100644 index 0000000000000000000000000000000000000000..66438ccdd506e27e35e270411e9beb6da8fd451c GIT binary patch literal 4114 zcmeI#AaCvot?uTnuJBf8`&LKyR(tgTPh@}F6&`8B`h*Zi7a^J{+1 zulY5<=GXk1U-N5z&9C`2zvkEcnqTv4e*M93_zl0|H~fa*@Ed-^Z}<(r;Wzw--|!oL z!*BQvzu`ChhTrfTe)GW({J;w9Ex+Zr{FdMHTYme&@Aw_R<9Gay-|;(s z$M5(ZzvFlOj^FV+e#h_l9lzsu{Epx8JAU`U@A*By=lA@c-}8HZ&+qv?zvuV-p5OC( ze$VguJ-_Go{GQ+Qdw&1HkNn7w{K${|$dCNUkNn7w{K${|$dCNUkNn7w{K${|$dCN^ z!5{bof8Y=Nfj{sE{=gsj1ApKT{DD942mZhx_yd375Bz~Y@CW|z!5{e}f8>w+kw5ZB z{>UHsBY)(N{E-2GGk@mK{Fy)VXa3Be`7?j!&-|G` z^Jo72!C&|bf8j6ug}?9@{=#4Q3xDA+{Dr^p7yiOu_zQpGFZ_kS@E88_!C(0+f90?I zmA~>={>oqZD}Uv${FT4*SN_Uh`73|rul$w2@>l-)!Qc2Bf8%fbjlc0X{>I<<8-L?( z{EffyH~z-o_#1!YZ~TqF@i+eV!B70ePyEDB{KQZE#83RhPyEDB{KQZE#83RhPyEDB z{KQZE^uf>k%+LJH&-~2K{LIh%%+LJH&-~2K{LIh%%+LJH&-~2K{QSY+`8$8-@BE#= z^LPHv-}yU#=kNTTzw>wg&fobvf9LP~oxk&U{{F!~_y_;sAN+%V@DKjMKllg#;2->h zfAA0f!9Vy1|KK0|gMaW3{_(*-`6vJ6pZt@5@=yNBKlvyB|KUIUhyU;&{`0{v{K7B%!Y};7FZ{wU{K7B%!Y};7FZ{wU{K7B% V!Y};7FZ}Ys|NRI2+5eB9@E<%~{oDWm literal 0 HcmV?d00001 diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/color3D.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/color3D.tga new file mode 100644 index 0000000000000000000000000000000000000000..005abb233b6102467e89cd0b67a9484af20e761c GIT binary patch literal 4114 zcmeI#DNtMe9>#H&nzEX*)r8Fy3KbT|G*#MSImMTDPibsYS&JyNaiKRWj~Y zNyMuX{FnG8_{I3e_(k|d_=WbQ3h@i;HdIixuL8@dUf{pTy8Eqfxy@E7e%W!E%6F?( zzFx2LrB+oWI#q#RfnOQ%sWKE$C4MD-1%A0VqH_E){4)H~mSvUVmsagzp2|{iDa#-D zRru8xMXEk7*Xy0vs#&X7&0?!+<~mh7)vH?kTKw8jP;cL z3031)TQ^jNUsZadD*RX3w<*v6R%xoc$&vNENcBhMs^6(m!)k*X7TVM}*QLg(J~fWH z)rjAO--O?U-xv(30l&dLuKM0-S@EqcOS0lytM^ogUsrgkI{de3dh$0kKc=e%zXiV) zzjeDtZTPkYn{2aPvc>vj8}q0=>{B~_JAOO94c~^}hTn$Y+L=%bev5ToE!Def!EY|S zP;<_$n$sVj^gHnF*SWHv6|3{8LY??stBvZy@1E^ecg(47{GPC1J@`HNJ^0=D-S}PZ zF?ID$sk3uVovll<RV}4-@HxEc()~iq90tyHX&9Z~S~F z<9oi0FE3@_8(VK=d}@;MpPG5JmgzVY6#LHt4dLHxmiVHy7SGVl%Oq>P@pjP`jM zO)E0qY{{rRkWungM*eph&wf66eiPrsH#xtFZ{nMr-{kxzzRCGb{2}}y{2}}y{2}}y zd=uY%Hz^a}Z2us$>61)+6W@IKMJB$P!XM%Jk8uAZ)c*+e7oz?{+<%Dr3sHX|>Mw*J z;`t8`2Q`d8j6aMY;`xX0L!3W^AL9HW&L67XQV4&9^N-|TX(Yw-AH^S~|3=S?6=D8F z=>G`wCqn;6=>IT&nEngnhpE5!)ZcsRFHHS~@x%CG{4jnPKf?V-@FSInir|lO|D!4V z3HomWe}efp!TcX*{*SLUXq@>w#{3&&{*5tzqWDq#DE$|u|DyO&{3w2u`WvJE#;CtB z{Bito>TkT{OcVGMDf({)e}?%xgFnOmn`Zw_uhnaMu}xFV|0(8w3_r&Fjp0w?PvTGF zPvXbuzZiZDKZZYrKSljd<4;rnGxXm~3O~vGP2wlnze)TAeuDju?jvvR5^Ed4)A|Ian9YL5O-R2(URpTtk5n7<$Kmv3{ljK56&SjJz% zUm|}jvHus@{|oHj1^jvZdHfIf^Z4`3-+BCb=HCMIZvlUS`Ll?>#Qa%e{w*_qKc?_E z*}t3Y|BcH+ZQyT^e>OI(TE|~c*tLeghQErxg1>_Q34aBDh5fU_{#jxEuQLBvnZK*} zYc)Gs$6v?az~4-B*ue?tB|!9ON{9+N+h z$)88$zeDoh0saC00r}?;{}BI>{eQ&%KVttL)vxQA{ddg%J7NEx{(=7u|J%10y2QUE z|6bx>EH~={{~Z4u|D61LhW{1+3;tK~-&gYA8U7jm8Tsd&{Bdqw*9H0Kg8XrTfB6Ub z@5hhly2HQwY|-uhE8T9^=@$Qn{C|Ugjem`Qh5sG@JN^~^75Vpy{CQ3Oye5C%kpFJT zpSR@STk_`}`S0!z{9kwQ_m6o0c;x-#5&r@I0skKV9{(r)PyBoQd;ACd2mHs5q#k+y U(0}p%@pt>5@Be-m|BL7G7Xt@IegFUf literal 0 HcmV?d00001 diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/flat2D.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/flat2D.tga new file mode 100644 index 0000000000000000000000000000000000000000..5bcca626ccb7be1be4d193f391f2943cefd8fd31 GIT binary patch literal 4114 zcmeH~!3jVi3`2{H^zZO@a{mn~9&*evC!bORIT)zVf>o=uzPh`+hoT2!VE;48QjXJP z_C4F>$|s-uPck6RoF=p3pZD*$lMjE)za#_V%xN;4`N#Zo+{u5PKlK59<4<@1?_@Qb literal 0 HcmV?d00001 diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/flat3D.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/flat3D.tga new file mode 100644 index 0000000000000000000000000000000000000000..15c9ca6ed355d9c0ec76b7adfb7c7bfc0abecd9c GIT binary patch literal 4114 zcmeHHTMB?M3@ct_-oZP0{~JvD(Z2>80^&y|V^H#tEG*)PT4&_9*4p0x&0t^mRyKRL zir0ku_CFI11!I5QbtPAZi|&BYP_XvzJD_CBaGk&N?>fMANWpgAIa4$luKnHrt^-Vm u6l~{RGevj8Egy7FG!zW-t+}E-;g%0NCmIR{`J%bvm0YCjdH)7}oy!9{3WQq# literal 0 HcmV?d00001 diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/phong.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/phong.tga new file mode 100644 index 0000000000000000000000000000000000000000..89dd5beecdadc784a32c0b2dae2d6aabbb8daba3 GIT binary patch literal 4114 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 literal 0 HcmV?d00001 diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/textured3D.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/textured3D.tga new file mode 100644 index 0000000000000000000000000000000000000000..fbbbe5d155c3b288a26f4e8abfa48494a2a31159 GIT binary patch literal 4114 zcmeHKZA?>V6h4K{u9ecJ3vt1q140}N6I==%MNBh88vQXA36hv{4YWc`TpT4)yJd?q zxb}k(2wOHllVwgNDwlpB%SM=d=`;(DsPrSo85837e!FY|cAi3wuoYoTmi_QHC%w1a zd!Oe$=e*B(AWERv@fzW?e*OB{7xDki0a2I>HpOMhB26L?7pW**bGTB{OV&e5gxqL{jQ1mEN zs$;68BzMv}jYG3ZTdOV6?bMZPw`yzD8`TGtYn0Aat5$W%<#H(@Az?%&lL7zHit)kt zVH8`b3@dfIpLD6I7g94b1DQEF-8uRB$MZ`HTMNsL4aPl1^+okYoAIz=hoMDp(s$+N z=AO>V%IZr?OB+r}N%>i=R^L)66ySijq83Z#f39P|dXlhiV5g^FOwY@^kY_S|Zz?T4 zUn&SbVPEyB>O)T)TEHIN*&4 z^y5-JIoCC)+%O^MSU0fE<{`7iGHkKiN9>|FCbqc-U0v?;?r%Ijo^$RK?trtyIUu%( zBS(%L8QQyd?}f6mvZ3PQVsJnnPz$^jJ&A~ygSpN{_w*3zjhtiMz;-w;JKEbP+9fF@ z_4}^-2K`t4qk$`d%l=XSxOc#NP3n^-ySux`o12?2?ccv29FPap0{wuuVqYNQW!RZ-N2rno|&HEWA>Q?*E7@8(|0Xd-TuL={>bfn zkp+N@FPPh-P$(4kdc9*#r_))GM zO^+uqdLv;dT3Z{f z?sF&H{>!8O$kd(X;RgbNiyn{1Z?oBs7Znw`bUNL#@P!N_L}do4Yc{G4hj$pNIuBMk z107E9_<%Qb_f}}B`lB5GYW?DG#hs>RU{D;bg5K4z!5UwLU3$KN95jpI%({ zr`JsGahMOE&o}0BxqQ{t)yE183y*3vnq{p&wn6xN6>pkc-aHk&iH`7Q>gG)~!JF#| zZ!&OLoCjRv=LeIMp&OFq9TG*?IYF>~k)OZ0At@>4BO=v@M5`S{>bU&}ahMkhIg3UX zi-(y-WG{ziw|I{>qp+&BMpTL&(j;$i+kHs3?wnY`1@Fw^+{Bn$2JB%FFxw z-PBaiJ97D_TZkHpSzI?09gT}08<6t@Q_aJ3Ee}y}Kps#F^n<{|wu*{Xd;B8BM2D?I*}!j9rUYt~>~I2Wh|`T;$OeW7HtrDoHmW%H$D6Q*S|reRa2=ApG( zrRscHp*X9M%YS$&F>yjJlT9TO{l;&a;h0?!KJtKCz&v1pV{c%O!fe8H!h9Fdwx}6~ zDV-ahFsU%BFs(4JFtJZpwIX~NHuMDg5_=)`KZn0PiVsshhmX6!7OcS@t5`Pv lVtxzop$}O9U-1QI#KSxKSKxy!SU + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#cmakedefine ANYIMAGEIMPORTER_PLUGIN_FILENAME "${ANYIMAGEIMPORTER_PLUGIN_FILENAME}" +#cmakedefine TGAIMPORTER_PLUGIN_FILENAME "${TGAIMPORTER_PLUGIN_FILENAME}" +#define COMPILEGLTEST_TEST_DIR "${COMPILEGLTEST_TEST_DIR}"