diff --git a/src/Magnum/Shaders/Test/CMakeLists.txt b/src/Magnum/Shaders/Test/CMakeLists.txt index 3e468f9a2..5cd989b31 100644 --- a/src/Magnum/Shaders/Test/CMakeLists.txt +++ b/src/Magnum/Shaders/Test/CMakeLists.txt @@ -73,7 +73,40 @@ if(BUILD_GL_TESTS) endif() corrade_add_test(ShadersDistanceFieldVectorGLTest DistanceFieldVectorGLTest.cpp LIBRARIES MagnumShaders MagnumOpenGLTester) - corrade_add_test(ShadersFlatGLTest FlatGLTest.cpp LIBRARIES MagnumShadersTestLib MagnumOpenGLTester) + + corrade_add_test(ShadersFlatGLTest FlatGLTest.cpp + LIBRARIES + MagnumDebugTools + MagnumMeshTools + MagnumPrimitives + MagnumShadersTestLib + MagnumOpenGLTester + FILES + TestFiles/diffuse-alpha-texture.tga + TestFiles/diffuse-texture.tga + TestFiles/alpha-mask1.0.tga + + FlatTestFiles/colored2D.tga + FlatTestFiles/colored3D.tga + FlatTestFiles/defaults.tga + FlatTestFiles/textured2D.tga + FlatTestFiles/textured3D.tga + FlatTestFiles/textured2D-alpha.tga + FlatTestFiles/textured3D-alpha.tga + FlatTestFiles/textured2D-alpha-mask0.5.tga + FlatTestFiles/textured3D-alpha-mask0.5.tga) + if(NOT BUILD_PLUGINS_STATIC) + target_include_directories(ShadersFlatGLTest PRIVATE $) + else() + target_include_directories(ShadersFlatGLTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + if(WITH_ANYIMAGEIMPORTER) + target_link_libraries(ShadersFlatGLTest PRIVATE AnyImageImporter) + endif() + if(WITH_TGAIMPORTER) + target_link_libraries(ShadersFlatGLTest PRIVATE TgaImporter) + endif() + endif() + corrade_add_test(ShadersMeshVisualizerGLTest MeshVisualizerGLTest.cpp LIBRARIES MagnumShaders MagnumOpenGLTester) corrade_add_test(ShadersPhongGLTest PhongGLTest.cpp diff --git a/src/Magnum/Shaders/Test/FlatGLTest.cpp b/src/Magnum/Shaders/Test/FlatGLTest.cpp index 42342cfc9..85cda5f0b 100644 --- a/src/Magnum/Shaders/Test/FlatGLTest.cpp +++ b/src/Magnum/Shaders/Test/FlatGLTest.cpp @@ -24,15 +24,35 @@ */ #include +#include +#include +#include #include +#include #include +#include "Magnum/Image.h" #include "Magnum/ImageView.h" #include "Magnum/PixelFormat.h" +#include "Magnum/DebugTools/CompareImage.h" +#include "Magnum/GL/Mesh.h" +#include "Magnum/GL/Framebuffer.h" +#include "Magnum/GL/Renderer.h" +#include "Magnum/GL/Renderbuffer.h" +#include "Magnum/GL/RenderbufferFormat.h" #include "Magnum/GL/Texture.h" #include "Magnum/GL/TextureFormat.h" #include "Magnum/GL/OpenGLTester.h" +#include "Magnum/MeshTools/Compile.h" +#include "Magnum/Primitives/Circle.h" +#include "Magnum/Primitives/UVSphere.h" #include "Magnum/Shaders/Flat.h" +#include "Magnum/Trade/AbstractImporter.h" +#include "Magnum/Trade/ImageData.h" +#include "Magnum/Trade/MeshData2D.h" +#include "Magnum/Trade/MeshData3D.h" + +#include "configure.h" namespace Magnum { namespace Shaders { namespace Test { namespace { @@ -48,8 +68,34 @@ struct FlatGLTest: GL::OpenGLTester { template void setAlphaMask(); template void setAlphaMaskNotEnabled(); + + void renderSetup(); + void renderTeardown(); + + void renderDefaults2D(); + void renderDefaults3D(); + void renderColored2D(); + void renderColored3D(); + void renderSinglePixelTextured2D(); + void renderSinglePixelTextured3D(); + void renderTextured2D(); + void renderTextured3D(); + + void renderAlphaSetup(); + void renderAlphaTeardown(); + + void renderAlpha2D(); + void renderAlpha3D(); + + private: + PluginManager::Manager _manager{"nonexistent"}; + + GL::Renderbuffer _color{NoCreate}, _depth{NoCreate}; + GL::Framebuffer _framebuffer{NoCreate}; }; +using namespace Math::Literals; + constexpr struct { const char* name; Flat2D::Flags flags; @@ -58,6 +104,28 @@ constexpr struct { {"textured", Flat2D::Flag::Textured} }; +const struct { + const char* name; + const char* expected2D; + const char* expected3D; + bool blending; + Flat2D::Flags flags; + Float threshold; +} RenderAlphaData[] { + /* All those deliberately have a non-white diffuse in order to match the + expected data from textured() */ + {"none", "FlatTestFiles/textured2D.tga", "FlatTestFiles/textured3D.tga", false, + Flat2D::Flag::Textured, 0.0f}, + {"blending", "FlatTestFiles/textured2D-alpha.tga", "FlatTestFiles/textured3D-alpha.tga", true, + Flat2D::Flag::Textured, 0.0f}, + {"masking 0.0", "FlatTestFiles/textured2D.tga", "FlatTestFiles/textured3D.tga", false, + Flat2D::Flag::Textured, 0.0f}, + {"masking 0.5", "FlatTestFiles/textured2D-alpha-mask0.5.tga", "FlatTestFiles/textured3D-alpha-mask0.5.tga", false, + Flat2D::Flag::Textured|Flat2D::Flag::AlphaMask, 0.5f}, + {"masking 1.0", "TestFiles/alpha-mask1.0.tga", "TestFiles/alpha-mask1.0.tga", false, + Flat2D::Flag::Textured|Flat2D::Flag::AlphaMask, 1.0f} +}; + FlatGLTest::FlatGLTest() { addInstancedTests({ &FlatGLTest::construct<2>, @@ -77,6 +145,32 @@ FlatGLTest::FlatGLTest() { &FlatGLTest::setAlphaMask<3>, &FlatGLTest::setAlphaMaskNotEnabled<2>, &FlatGLTest::setAlphaMaskNotEnabled<3>}); + + addTests({&FlatGLTest::renderDefaults2D, + &FlatGLTest::renderDefaults3D, + &FlatGLTest::renderColored2D, + &FlatGLTest::renderColored3D, + &FlatGLTest::renderSinglePixelTextured2D, + &FlatGLTest::renderSinglePixelTextured3D, + &FlatGLTest::renderTextured2D, + &FlatGLTest::renderTextured3D}, + &FlatGLTest::renderSetup, + &FlatGLTest::renderTeardown); + + addInstancedTests({&FlatGLTest::renderAlpha2D, + &FlatGLTest::renderAlpha3D}, + Containers::arraySize(RenderAlphaData), + &FlatGLTest::renderAlphaSetup, + &FlatGLTest::renderAlphaTeardown); + + /* 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 } template void FlatGLTest::construct() { @@ -174,6 +268,390 @@ template void FlatGLTest::setAlphaMaskNotEnabled() { "Shaders::Flat::setAlphaMask(): the shader was not created with alpha mask enabled\n"); } +constexpr Vector2i RenderSize{80, 80}; + +void FlatGLTest::renderSetup() { + /* Pick a color that's directly representable on RGBA4 as well to reduce + artifacts */ + GL::Renderer::setClearColor(0x111111_rgbf); + GL::Renderer::enable(GL::Renderer::Feature::FaceCulling); + + _color = GL::Renderbuffer{}; + _color.setStorage( + #if !defined(MAGNUM_TARGET_GLES2) || !defined(MAGNUM_TARGET_WEBGL) + GL::RenderbufferFormat::RGBA8, + #else + GL::RenderbufferFormat::RGBA4, + #endif + RenderSize); + _framebuffer = GL::Framebuffer{{{}, RenderSize}}; + _framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, _color) + .clear(GL::FramebufferClear::Color) + .bind(); +} + +void FlatGLTest::renderTeardown() { + _color = GL::Renderbuffer{NoCreate}; + _framebuffer = GL::Framebuffer{NoCreate}; +} + +void FlatGLTest::renderDefaults2D() { + GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32)); + + Flat2D shader; + circle.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/defaults.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderDefaults3D() { + GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); + + Flat3D shader; + sphere.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/defaults.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderColored2D() { + GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32)); + + Flat2D shader; + shader.setColor(0x9999ff_rgbf) + .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})); + + circle.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/colored2D.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderColored3D() { + GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); + + Flat3D shader; + shader.setColor(0x9999ff_rgbf) + .setTransformationProjectionMatrix( + Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* + Matrix4::translation(Vector3::zAxis(-2.15f))* + Matrix4::rotationY(-15.0_degf)* + Matrix4::rotationX(15.0_degf)); + + sphere.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/colored3D.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +constexpr GL::TextureFormat TextureFormatRGB = + #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) + GL::TextureFormat::RGB8 + #else + GL::TextureFormat::RGB + #endif + ; +constexpr GL::TextureFormat TextureFormatRGBA = + #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) + GL::TextureFormat::RGBA8 + #else + GL::TextureFormat::RGBA + #endif + ; + +void FlatGLTest::renderSinglePixelTextured2D() { + GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32, + Primitives::CircleTextureCoords::Generate)); + + const Color4ub diffuseData[]{ 0x9999ff_rgb }; + ImageView2D diffuseImage{PixelFormat::RGBA8Unorm, Vector2i{1}, diffuseData}; + GL::Texture2D texture; + texture.setMinificationFilter(GL::SamplerFilter::Linear) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setWrapping(GL::SamplerWrapping::ClampToEdge) + .setStorage(1, TextureFormatRGBA, Vector2i{1}) + .setSubImage(0, {}, diffuseImage); + + Flat2D shader{Flat3D::Flag::Textured}; + shader.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) + .bindTexture(texture); + circle.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/colored2D.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderSinglePixelTextured3D() { + GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, + Primitives::UVSphereTextureCoords::Generate)); + + const Color4ub diffuseData[]{ 0x9999ff_rgb }; + ImageView2D diffuseImage{PixelFormat::RGBA8Unorm, Vector2i{1}, diffuseData}; + GL::Texture2D texture; + texture.setMinificationFilter(GL::SamplerFilter::Linear) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setWrapping(GL::SamplerWrapping::ClampToEdge) + .setStorage(1, TextureFormatRGBA, Vector2i{1}) + .setSubImage(0, {}, diffuseImage); + + Flat3D shader{Flat3D::Flag::Textured}; + shader.setTransformationProjectionMatrix( + Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* + Matrix4::translation(Vector3::zAxis(-2.15f))* + Matrix4::rotationY(-15.0_degf)* + Matrix4::rotationX(15.0_degf)) + .bindTexture(texture); + sphere.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/colored3D.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderTextured2D() { + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32, + Primitives::CircleTextureCoords::Generate)); + + Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); + CORRADE_VERIFY(importer); + + GL::Texture2D texture; + Containers::Optional image; + CORRADE_VERIFY(importer->openFile(Utility::Directory::join(SHADERS_TEST_DIR, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0))); + texture.setMinificationFilter(GL::SamplerFilter::Linear) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setWrapping(GL::SamplerWrapping::ClampToEdge) + .setStorage(1, TextureFormatRGB, image->size()) + .setSubImage(0, {}, *image); + + Flat2D shader{Flat2D::Flag::Textured}; + shader.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) + /* Colorized. Case without a color (where it should be white) is tested + in renderSinglePixelTextured() */ + .setColor(0x9999ff_rgbf) + .bindTexture(texture); + circle.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/textured2D.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderTextured3D() { + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, + Primitives::UVSphereTextureCoords::Generate)); + + Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); + CORRADE_VERIFY(importer); + + GL::Texture2D texture; + Containers::Optional image; + CORRADE_VERIFY(importer->openFile(Utility::Directory::join(SHADERS_TEST_DIR, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0))); + texture.setMinificationFilter(GL::SamplerFilter::Linear) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setWrapping(GL::SamplerWrapping::ClampToEdge) + .setStorage(1, TextureFormatRGB, image->size()) + .setSubImage(0, {}, *image); + + Flat3D shader{Flat3D::Flag::Textured}; + shader.setTransformationProjectionMatrix( + Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* + Matrix4::translation(Vector3::zAxis(-2.15f))* + Matrix4::rotationY(-15.0_degf)* + Matrix4::rotationX(15.0_degf)) + /* Colorized. Case without a color (where it should be white) is tested + in renderSinglePixelTextured() */ + .setColor(0x9999ff_rgbf) + .bindTexture(texture); + sphere.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/textured3D.tga"), + (DebugTools::CompareImageToFile{_manager, 0.0f, 0.0f})); +} + +void FlatGLTest::renderAlphaSetup() { + renderSetup(); + if(RenderAlphaData[testCaseInstanceId()].blending) + GL::Renderer::enable(GL::Renderer::Feature::Blending); + GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha, GL::Renderer::BlendFunction::OneMinusSourceAlpha); + GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add); +} + +void FlatGLTest::renderAlphaTeardown() { + if(RenderAlphaData[testCaseInstanceId()].blending) + GL::Renderer::disable(GL::Renderer::Feature::Blending); + renderTeardown(); +} + +void FlatGLTest::renderAlpha2D() { + auto&& data = RenderAlphaData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + Containers::Optional image; + Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); + CORRADE_VERIFY(importer); + + GL::Texture2D texture; + CORRADE_VERIFY(importer->openFile(Utility::Directory::join({SHADERS_TEST_DIR, "TestFiles", "diffuse-alpha-texture.tga"})) && (image = importer->image2D(0))); + texture.setMinificationFilter(GL::SamplerFilter::Linear) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setWrapping(GL::SamplerWrapping::ClampToEdge) + .setStorage(1, TextureFormatRGBA, image->size()) + .setSubImage(0, {}, *image); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32, + Primitives::CircleTextureCoords::Generate)); + + Flat2D shader{data.flags}; + shader.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) + .setColor(0x9999ff_rgbf) + .bindTexture(texture); + + if(data.flags & Flat3D::Flag::AlphaMask) + shader.setAlphaMask(data.threshold); + + circle.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(SHADERS_TEST_DIR, data.expected2D), + /* Minor differences between opaque and diffuse, not sure why */ + (DebugTools::CompareImageToFile{_manager, 24.34f, 0.290f})); +} + +void FlatGLTest::renderAlpha3D() { + auto&& data = RenderAlphaData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + Containers::Optional image; + Containers::Pointer importer = _manager.loadAndInstantiate("AnyImageImporter"); + CORRADE_VERIFY(importer); + + GL::Texture2D texture; + CORRADE_VERIFY(importer->openFile(Utility::Directory::join({SHADERS_TEST_DIR, "TestFiles", "diffuse-alpha-texture.tga"})) && (image = importer->image2D(0))); + texture.setMinificationFilter(GL::SamplerFilter::Linear) + .setMagnificationFilter(GL::SamplerFilter::Linear) + .setWrapping(GL::SamplerWrapping::ClampToEdge) + .setStorage(1, TextureFormatRGBA, image->size()) + .setSubImage(0, {}, *image); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, + Primitives::UVSphereTextureCoords::Generate)); + + Flat3D shader{data.flags}; + shader.setTransformationProjectionMatrix( + Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* + Matrix4::translation(Vector3::zAxis(-2.15f))* + Matrix4::rotationY(-15.0_degf)* + Matrix4::rotationX(15.0_degf)) + .setColor(0x9999ff_rgbf) + .bindTexture(texture); + + if(data.flags & Flat3D::Flag::AlphaMask) + shader.setAlphaMask(data.threshold); + + /* For proper Z order draw back faces first and then front faces */ + GL::Renderer::setFaceCullingMode(GL::Renderer::PolygonFacing::Front); + sphere.draw(shader); + GL::Renderer::setFaceCullingMode(GL::Renderer::PolygonFacing::Back); + sphere.draw(shader); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join({SHADERS_TEST_DIR, data.expected3D}), + /* Minor differences between opaque and diffuse, not sure why */ + (DebugTools::CompareImageToFile{_manager, 2.0f, 0.204f})); +} + }}}} CORRADE_TEST_MAIN(Magnum::Shaders::Test::FlatGLTest) diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/colored2D.tga b/src/Magnum/Shaders/Test/FlatTestFiles/colored2D.tga new file mode 100644 index 000000000..a28c76de6 Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/colored2D.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/colored3D.tga b/src/Magnum/Shaders/Test/FlatTestFiles/colored3D.tga new file mode 100644 index 000000000..3adb0d7c3 Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/colored3D.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/defaults.tga b/src/Magnum/Shaders/Test/FlatTestFiles/defaults.tga new file mode 100644 index 000000000..d901c0fab Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/defaults.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/textured2D-alpha-mask0.5.tga b/src/Magnum/Shaders/Test/FlatTestFiles/textured2D-alpha-mask0.5.tga new file mode 100644 index 000000000..179345aac Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/textured2D-alpha-mask0.5.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/textured2D-alpha.tga b/src/Magnum/Shaders/Test/FlatTestFiles/textured2D-alpha.tga new file mode 100644 index 000000000..483d32035 Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/textured2D-alpha.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/textured2D.tga b/src/Magnum/Shaders/Test/FlatTestFiles/textured2D.tga new file mode 100644 index 000000000..e8e799388 Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/textured2D.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/textured3D-alpha-mask0.5.tga b/src/Magnum/Shaders/Test/FlatTestFiles/textured3D-alpha-mask0.5.tga new file mode 100644 index 000000000..d4e6c467a Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/textured3D-alpha-mask0.5.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/textured3D-alpha.tga b/src/Magnum/Shaders/Test/FlatTestFiles/textured3D-alpha.tga new file mode 100644 index 000000000..9350d340e Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/textured3D-alpha.tga differ diff --git a/src/Magnum/Shaders/Test/FlatTestFiles/textured3D.tga b/src/Magnum/Shaders/Test/FlatTestFiles/textured3D.tga new file mode 100644 index 000000000..02f212206 Binary files /dev/null and b/src/Magnum/Shaders/Test/FlatTestFiles/textured3D.tga differ