Browse Source

Shaders: separate instanced colored and textured test cases.

With everything smashed together it was quite annoying to eyeball and
too easy to miss issues.
pull/518/head
Vladimír Vondruš 5 years ago
parent
commit
45f115b931
  1. 2
      src/Magnum/Shaders/Test/CMakeLists.txt
  2. 236
      src/Magnum/Shaders/Test/FlatGLTest.cpp
  3. BIN
      src/Magnum/Shaders/Test/FlatTestFiles/instanced-textured2D.tga
  4. BIN
      src/Magnum/Shaders/Test/FlatTestFiles/instanced-textured3D.tga
  5. BIN
      src/Magnum/Shaders/Test/FlatTestFiles/instanced2D.tga
  6. BIN
      src/Magnum/Shaders/Test/FlatTestFiles/instanced3D.tga
  7. 204
      src/Magnum/Shaders/Test/PhongGLTest.cpp
  8. BIN
      src/Magnum/Shaders/Test/PhongTestFiles/instanced-textured.tga
  9. BIN
      src/Magnum/Shaders/Test/PhongTestFiles/instanced.tga

2
src/Magnum/Shaders/Test/CMakeLists.txt

@ -152,6 +152,8 @@ if(BUILD_GL_TESTS)
FlatTestFiles/defaults.tga FlatTestFiles/defaults.tga
FlatTestFiles/instanced2D.tga FlatTestFiles/instanced2D.tga
FlatTestFiles/instanced3D.tga FlatTestFiles/instanced3D.tga
FlatTestFiles/instanced-textured2D.tga
FlatTestFiles/instanced-textured3D.tga
FlatTestFiles/textured2D.tga FlatTestFiles/textured2D.tga
FlatTestFiles/textured3D.tga FlatTestFiles/textured3D.tga
FlatTestFiles/textured2D-alpha.tga FlatTestFiles/textured2D-alpha.tga

236
src/Magnum/Shaders/Test/FlatGLTest.cpp

@ -166,21 +166,21 @@ struct FlatGLTest: GL::OpenGLTester {
Mesa Intel BADIOM Mesa Intel BADIOM
ES2 xx ES2 xx
ES3 BADIOx ES3 BAD Ox
Mesa AMD BADI Mesa AMD BAD
Mesa llvmpipe BADI Mesa llvmpipe BAD
SwiftShader ES2 BADIxx SwiftShader ES2 BAD xx
ES3 BADI ES3 BAD
ANGLE ES2 xx ANGLE ES2 xx
ES3 BADIOM ES3 BAD OM
ARM Mali (Huawei P10) ES2 BAD xx ARM Mali (Huawei P10) ES2 BAD xx
ES3 BADIOx ES3 BAD Ox
WebGL (on Mesa Intel) 1.0 BAD xx WebGL (on Mesa Intel) 1.0 BAD xx
2.0 BADIOM 2.0 BAD OM
NVidia BAD NVidia BAD
Intel Windows BAD Intel Windows BAD
AMD macOS BAD AMD macOS BAD
Intel macOS BADIOx Intel macOS BAD Ox
iPhone 6 w/ iOS 12.4 ES3 BAD x iPhone 6 w/ iOS 12.4 ES3 BAD x
*/ */
@ -274,6 +274,23 @@ const struct {
FlatGL2D::Flag::Textured|FlatGL2D::Flag::AlphaMask, 1.0f} FlatGL2D::Flag::Textured|FlatGL2D::Flag::AlphaMask, 1.0f}
}; };
constexpr struct {
const char* name;
const char* expected2D;
const char* expected3D;
FlatGL2D::Flags flags;
Float maxThreshold, meanThreshold;
} RenderInstancedData[] {
{"colored", "instanced2D.tga", "instanced3D.tga",
{},
/* Minor differences on SwiftShader */
164.4f, 0.094f},
{"textured", "instanced-textured2D.tga", "instanced-textured3D.tga",
FlatGL2D::Flag::InstancedTextureOffset|FlatGL2D::Flag::Textured,
/* Minor differences on SwiftShader */
192.67f, 0.140f},
};
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
constexpr struct { constexpr struct {
const char* name; const char* name;
@ -462,7 +479,7 @@ FlatGLTest::FlatGLTest() {
#endif #endif
/* MSVC needs explicit type due to default template args */ /* MSVC needs explicit type due to default template args */
addTests<FlatGLTest>({ addInstancedTests<FlatGLTest>({
&FlatGLTest::renderInstanced2D, &FlatGLTest::renderInstanced2D,
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
&FlatGLTest::renderInstanced2D<FlatGL2D::Flag::UniformBuffers>, &FlatGLTest::renderInstanced2D<FlatGL2D::Flag::UniformBuffers>,
@ -472,6 +489,7 @@ FlatGLTest::FlatGLTest() {
&FlatGLTest::renderInstanced3D<FlatGL3D::Flag::UniformBuffers> &FlatGLTest::renderInstanced3D<FlatGL3D::Flag::UniformBuffers>
#endif #endif
}, },
Containers::arraySize(RenderInstancedData),
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
&FlatGLTest::renderObjectIdSetup, &FlatGLTest::renderObjectIdSetup,
&FlatGLTest::renderObjectIdTeardown &FlatGLTest::renderObjectIdTeardown
@ -2090,6 +2108,9 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderObjectId3D() {
#endif #endif
template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() { template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
auto&& data = RenderInstancedData[testCaseInstanceId()];
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(flag == FlatGL2D::Flag::UniformBuffers) { if(flag == FlatGL2D::Flag::UniformBuffers) {
setTestCaseTemplateName("Flag::UniformBuffers"); setTestCaseTemplateName("Flag::UniformBuffers");
@ -2116,10 +2137,6 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
#endif #endif
#endif #endif
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32, GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32,
Primitives::Circle2DFlag::TextureCoordinates)); Primitives::Circle2DFlag::TextureCoordinates));
@ -2130,11 +2147,14 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
Vector2 textureOffset; Vector2 textureOffset;
UnsignedInt objectId; UnsignedInt objectId;
} instanceData[] { } instanceData[] {
{Matrix3::translation({-1.25f, -1.25f}), 0xff3333_rgbf, {Matrix3::translation({-1.25f, -1.25f}),
data.flags & FlatGL2D::Flag::Textured ? 0xffffff_rgbf : 0xffff00_rgbf,
{0.0f, 0.0f}, 211}, {0.0f, 0.0f}, 211},
{Matrix3::translation({ 1.25f, -1.25f}), 0x33ff33_rgbf, {Matrix3::translation({ 1.25f, -1.25f}),
data.flags & FlatGL2D::Flag::Textured ? 0xffffff_rgbf : 0x00ffff_rgbf,
{1.0f, 0.0f}, 4627}, {1.0f, 0.0f}, 4627},
{Matrix3::translation({ 0.00f, 1.25f}), 0x9999ff_rgbf, {Matrix3::translation({ 0.00f, 1.25f}),
data.flags & FlatGL2D::Flag::Textured ? 0xffffff_rgbf : 0xff00ff_rgbf,
{0.5f, 1.0f}, 35363}, {0.5f, 1.0f}, 35363},
}; };
@ -2151,22 +2171,9 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
) )
.setInstanceCount(3); .setInstanceCount(3);
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
GL::Texture2D texture;
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "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);
/* Enable also Object ID, if supported */ /* Enable also Object ID, if supported */
FlatGL2D::Flags flags = FlatGL2D::Flag::Textured| FlatGL2D::Flags flags = FlatGL2D::Flag::VertexColor|
FlatGL2D::Flag::VertexColor|FlatGL2D::Flag::InstancedTransformation| FlatGL2D::Flag::InstancedTransformation|data.flags|flag;
FlatGL2D::Flag::InstancedTextureOffset|flag;
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>()) if(GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
@ -2176,14 +2183,36 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
} }
#endif #endif
FlatGL2D shader{flags}; FlatGL2D shader{flags};
shader.bindTexture(texture);
GL::Texture2D texture;
if(data.flags & FlatGL3D::Flag::Textured) {
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "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);
shader.bindTexture(texture);
}
if(flag == FlatGL2D::Flag{}) { if(flag == FlatGL2D::Flag{}) {
shader.setColor(0xffff99_rgbf) shader
.setColor(data.flags & FlatGL2D::Flag::Textured ? 0xffffff_rgbf : 0xffff00_rgbf)
.setTransformationProjectionMatrix( .setTransformationProjectionMatrix(
Matrix3::projection({2.1f, 2.1f})* Matrix3::projection({2.1f, 2.1f})*
Matrix3::scaling(Vector2{0.4f})) Matrix3::scaling(Vector2{0.4f}));
.setTextureMatrix(Matrix3::scaling(Vector2{0.5f}));
if(data.flags & FlatGL3D::Flag::Textured)
shader.setTextureMatrix(Matrix3::scaling(Vector2{0.5f}));
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -2215,11 +2244,12 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
}}; }};
GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, {
FlatMaterialUniform{} FlatMaterialUniform{}
.setColor(0xffff99_rgbf) .setColor(data.flags & FlatGL2D::Flag::Textured ? 0xffffff_rgbf : 0xffff00_rgbf)
}}; }};
if(data.flags & FlatGL3D::Flag::Textured)
shader.bindTextureTransformationBuffer(textureTransformationUniform);
shader.bindTransformationProjectionBuffer(transformationProjectionUniform) shader.bindTransformationProjectionBuffer(transformationProjectionUniform)
.bindDrawBuffer(drawUniform) .bindDrawBuffer(drawUniform)
.bindTextureTransformationBuffer(textureTransformationUniform)
.bindMaterialBuffer(materialUniform) .bindMaterialBuffer(materialUniform)
.draw(circle); .draw(circle);
} }
@ -2228,18 +2258,29 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
/* Minor differences on AMD, SwiftShader a bit more */ !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
const Float maxThreshold = 3.0f, meanThreshold = 0.018f; CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage */ /*
const Float maxThreshold = 3.0f, meanThreshold = 0.018f; Colored case:
#endif
- First should be lower left, yellow with a yellow base color, so
yellow
- Second lower right, cyan with a yellow base color, so green
- Third up center, magenta with a yellow base color, so red
Textured case:
- Lower left has bottom left numbers, so light 7881
- Lower light has bottom right, 1223
- Up center has 6778
*/
CORRADE_COMPARE_WITH( CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */ /* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()), Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(_testDir, "FlatTestFiles/instanced2D.tga"), Utility::Directory::join({_testDir, "FlatTestFiles", data.expected2D}),
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold})); (DebugTools::CompareImageToFile{_manager, data.maxThreshold, data.meanThreshold}));
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/* Object ID -- no need to verify the whole image, just check that pixels /* Object ID -- no need to verify the whole image, just check that pixels
@ -2263,6 +2304,9 @@ template<FlatGL2D::Flag flag> void FlatGLTest::renderInstanced2D() {
} }
template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() { template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
auto&& data = RenderInstancedData[testCaseInstanceId()];
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(flag == FlatGL2D::Flag::UniformBuffers) { if(flag == FlatGL2D::Flag::UniformBuffers) {
setTestCaseTemplateName("Flag::UniformBuffers"); setTestCaseTemplateName("Flag::UniformBuffers");
@ -2289,10 +2333,6 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
#endif #endif
#endif #endif
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32,
Primitives::UVSphereFlag::TextureCoordinates)); Primitives::UVSphereFlag::TextureCoordinates));
@ -2303,11 +2343,17 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
Vector2 textureOffset; Vector2 textureOffset;
UnsignedInt objectId; UnsignedInt objectId;
} instanceData[] { } instanceData[] {
{Matrix4::translation({-1.25f, -1.25f, 0.0f}), 0xff3333_rgbf, {Matrix4::translation({-1.25f, -1.25f, 0.0f})*
/* To be consistent with Phong's output where it tests that the
normal matrix is applied properly */
Matrix4::rotationX(90.0_degf),
data.flags & FlatGL3D::Flag::Textured ? 0xffffff_rgbf : 0xffff00_rgbf,
{0.0f, 0.0f}, 211}, {0.0f, 0.0f}, 211},
{Matrix4::translation({ 1.25f, -1.25f, 0.0f}), 0x33ff33_rgbf, {Matrix4::translation({ 1.25f, -1.25f, 0.0f}),
data.flags & FlatGL3D::Flag::Textured ? 0xffffff_rgbf : 0x00ffff_rgbf,
{1.0f, 0.0f}, 4627}, {1.0f, 0.0f}, 4627},
{Matrix4::translation({ 0.0f, 1.0f, 1.0f}), 0x9999ff_rgbf, {Matrix4::translation({ 0.0f, 1.0f, 1.0f}),
data.flags & FlatGL3D::Flag::Textured ? 0xffffff_rgbf : 0xff00ff_rgbf,
{0.5f, 1.0f}, 35363} {0.5f, 1.0f}, 35363}
}; };
@ -2324,22 +2370,9 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
) )
.setInstanceCount(3); .setInstanceCount(3);
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
GL::Texture2D texture;
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "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);
/* Enable also Object ID, if supported */ /* Enable also Object ID, if supported */
FlatGL3D::Flags flags = FlatGL3D::Flag::Textured| FlatGL3D::Flags flags = FlatGL3D::Flag::VertexColor|
FlatGL3D::Flag::VertexColor|FlatGL3D::Flag::InstancedTransformation| FlatGL3D::Flag::InstancedTransformation|data.flags|flag;
FlatGL3D::Flag::InstancedTextureOffset|flag;
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>()) if(GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
@ -2349,15 +2382,37 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
} }
#endif #endif
FlatGL3D shader{flags}; FlatGL3D shader{flags};
shader.bindTexture(texture);
GL::Texture2D texture;
if(data.flags & FlatGL2D::Flag::Textured) {
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "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);
shader.bindTexture(texture);
}
if(flag == FlatGL3D::Flag{}) { if(flag == FlatGL3D::Flag{}) {
shader.setColor(0xffff99_rgbf) shader
.setColor(data.flags & FlatGL2D::Flag::Textured ? 0xffffff_rgbf : 0xffff00_rgbf)
.setTransformationProjectionMatrix( .setTransformationProjectionMatrix(
Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)* Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)*
Matrix4::translation(Vector3::zAxis(-2.15f))* Matrix4::translation(Vector3::zAxis(-2.15f))*
Matrix4::scaling(Vector3{0.4f})) Matrix4::scaling(Vector3{0.4f}));
.setTextureMatrix(Matrix3::scaling(Vector2{0.5f}));
if(data.flags & FlatGL3D::Flag::Textured)
shader.setTextureMatrix(Matrix3::scaling(Vector2{0.5f}));
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -2390,11 +2445,12 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
}}; }};
GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, {
FlatMaterialUniform{} FlatMaterialUniform{}
.setColor(0xffff99_rgbf) .setColor(data.flags & FlatGL3D::Flag::Textured ? 0xffffff_rgbf : 0xffff00_rgbf)
}}; }};
if(data.flags & FlatGL3D::Flag::Textured)
shader.bindTextureTransformationBuffer(textureTransformationUniform);
shader.bindTransformationProjectionBuffer(transformationProjectionUniform) shader.bindTransformationProjectionBuffer(transformationProjectionUniform)
.bindDrawBuffer(drawUniform) .bindDrawBuffer(drawUniform)
.bindTextureTransformationBuffer(textureTransformationUniform)
.bindMaterialBuffer(materialUniform) .bindMaterialBuffer(materialUniform)
.draw(sphere); .draw(sphere);
} }
@ -2403,18 +2459,30 @@ template<FlatGL3D::Flag flag> void FlatGLTest::renderInstanced3D() {
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
/* Minor differences on AMD, SwiftShader a bit more */ !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
const Float maxThreshold = 67.67f, meanThreshold = 0.062f; CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage */ /*
const Float maxThreshold = 67.67f, meanThreshold = 0.062f; Colored case:
#endif
- First should be lower left, yellow with a yellow base color, so
yellow
- Second lower right, cyan with a yellow base color, so green
- Third up center, magenta with a yellow base color, so red
Textured case:
- Lower left has bottom left numbers, so light 7881, rotated (78
visible)
- Lower light has bottom right, 1223
- Up center has 6778
*/
CORRADE_COMPARE_WITH( CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */ /* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()), Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(_testDir, "FlatTestFiles/instanced3D.tga"), Utility::Directory::join({_testDir, "FlatTestFiles", data.expected3D}),
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold})); (DebugTools::CompareImageToFile{_manager, data.maxThreshold, data.meanThreshold}));
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/* Object ID -- no need to verify the whole image, just check that pixels /* Object ID -- no need to verify the whole image, just check that pixels

BIN
src/Magnum/Shaders/Test/FlatTestFiles/instanced-textured2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/FlatTestFiles/instanced-textured3D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/FlatTestFiles/instanced2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/FlatTestFiles/instanced3D.tga

Binary file not shown.

204
src/Magnum/Shaders/Test/PhongGLTest.cpp

@ -49,6 +49,7 @@
#include "Magnum/GL/TextureFormat.h" #include "Magnum/GL/TextureFormat.h"
#include "Magnum/Math/Color.h" #include "Magnum/Math/Color.h"
#include "Magnum/Math/Matrix4.h" #include "Magnum/Math/Matrix4.h"
#include "Magnum/Math/Swizzle.h"
#include "Magnum/MeshTools/Compile.h" #include "Magnum/MeshTools/Compile.h"
#include "Magnum/MeshTools/Transform.h" #include "Magnum/MeshTools/Transform.h"
#include "Magnum/Primitives/Plane.h" #include "Magnum/Primitives/Plane.h"
@ -173,21 +174,21 @@ struct PhongGLTest: GL::OpenGLTester {
Mesa Intel BADLIOM Mesa Intel BADLIOM
ES2 xx ES2 xx
ES3 BADLIOx ES3 BADL Ox
Mesa AMD BAD I Mesa AMD BAD
Mesa llvmpipe BAD I Mesa llvmpipe BAD
SwiftShader ES2 BADLIxx SwiftShader ES2 BADL xx
ES3 BADLI ES3 BADL
ANGLE ES2 xx ANGLE ES2 xx
ES3 BADLIOM ES3 BADL OM
ARM Mali (Huawei P10) ES2 BAD xx ARM Mali (Huawei P10) ES2 BAD xx
ES3 BADLIOx ES3 BADL Ox
WebGL (on Mesa Intel) 1.0 BAD xx WebGL (on Mesa Intel) 1.0 BAD xx
2.0 BADLIOM 2.0 BADL OM
NVidia BAD NVidia BAD
Intel Windows BAD Intel Windows BAD
AMD macOS BAD AMD macOS BAD
Intel macOS BADLIOx Intel macOS BADL Ox
iPhone 6 w/ iOS 12.4 ES3 BAD x iPhone 6 w/ iOS 12.4 ES3 BAD x
*/ */
@ -555,24 +556,14 @@ constexpr struct {
PhongGL::Flags flags; PhongGL::Flags flags;
Float maxThreshold, meanThreshold; Float maxThreshold, meanThreshold;
} RenderInstancedData[] { } RenderInstancedData[] {
{"diffuse", "instanced.tga", {}, {"diffuse color", "instanced.tga", {},
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* Minor differences on SwiftShader */
/* AMD has one off pixel; SwiftShader a bit more */ 81.0f, 0.06f},
96.34f, 0.113f, {"diffuse texture", "instanced-textured.tga",
#else PhongGL::Flag::DiffuseTexture|PhongGL::Flag::InstancedTextureOffset,
/* WebGL 1 doesn't have 8bit renderbuffer storage */ /* Minor differences on SwiftShader */
96.34f, 0.113f, 112.0f, 0.09f},
#endif /** @todo test normal when there's usable texture */
},
{"diffuse + normal", "instanced-normal.tga", PhongGL::Flag::NormalTexture,
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/* AMD has one off pixel, llvmpipe more */
96.0f, 0.333f,
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage */
96.0f, 0.333f,
#endif
}
}; };
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -614,6 +605,7 @@ constexpr struct {
4, 2, 3, 1, 4, 2, 3, 1,
/* Minor differences on ARM Mali */ /* Minor differences on ARM Mali */
4.67f, 0.02f}, 4.67f, 0.02f},
/** @todo test normal and per-draw scaling when there's usable texture */
}; };
#endif #endif
@ -2833,16 +2825,13 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
#endif #endif
#endif #endif
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32,
Primitives::UVSphereFlag::TextureCoordinates| Primitives::UVSphereFlag::TextureCoordinates|
Primitives::UVSphereFlag::Tangents)); Primitives::UVSphereFlag::Tangents));
/* Three spheres, each in a different location, differently rotated to /* Three spheres, each in a different location. To test normal matrix
ensure the normal matrix is properly used as well. */ concatenation, everything is rotated 90° on Y, thus X is now -Z and Z is
now X. */
struct { struct {
Matrix4 transformation; Matrix4 transformation;
Matrix3x3 normal; Matrix3x3 normal;
@ -2850,18 +2839,22 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
Vector2 textureOffset; Vector2 textureOffset;
UnsignedInt objectId; UnsignedInt objectId;
} instanceData[] { } instanceData[] {
{Matrix4::translation({-1.25f, -1.25f, 0.0f})* {Matrix4::translation(Math::gather<'z', 'y', 'x'>(Vector3{-1.25f, -1.25f, 0.0f}))*Matrix4::rotationY(-90.0_degf)*Matrix4::rotationX(90.0_degf),
Matrix4::rotationX(90.0_degf), /* to test also per-instance normal matrix is applied properly --
{}, 0xff3333_rgbf, {0.0f, 0.0f}, 211}, the texture should look the same as in the case of Flat 3D
{Matrix4::translation({ 1.25f, -1.25f, 0.0f})* instanced textured */
Matrix4::rotationY(90.0_degf), (Matrix4::rotationY(-90.0_degf)*Matrix4::rotationX(90.0_degf)).normalMatrix(),
{}, 0x33ff33_rgbf, {1.0f, 0.0f}, 4627}, data.flags & PhongGL::Flag::DiffuseTexture ? 0xffffff_rgbf : 0xffff00_rgbf,
{Matrix4::translation({ 0.0f, 1.0f, 1.0f})* {0.0f, 0.0f}, 211},
Matrix4::rotationZ(90.0_degf), {Matrix4::translation(Math::gather<'z', 'y', 'x'>(Vector3{ 1.25f, -1.25f, 0.0f})),
{}, 0x9999ff_rgbf, {0.5f, 1.0f}, 35363} {},
data.flags & PhongGL::Flag::DiffuseTexture ? 0xffffff_rgbf : 0x00ffff_rgbf,
{1.0f, 0.0f}, 4627},
{Matrix4::translation(Math::gather<'z', 'y', 'x'>(Vector3{ 0.0f, 1.0f, -1.0f})),
{},
data.flags & PhongGL::Flag::DiffuseTexture ? 0xffffff_rgbf : 0xff00ff_rgbf,
{0.5f, 1.0f}, 35363}
}; };
for(auto& instance: instanceData)
instance.normal = instance.transformation.normalMatrix();
sphere sphere
.addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0, .addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0,
@ -2877,31 +2870,9 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
) )
.setInstanceCount(3); .setInstanceCount(3);
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0)));
GL::Texture2D diffuse;
diffuse.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/normal-texture.tga")) && (image = importer->image2D(0)));
GL::Texture2D normal;
normal.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
/* Enable also Object ID, if supported */ /* Enable also Object ID, if supported */
PhongGL::Flags flags = PhongGL::Flag::DiffuseTexture| PhongGL::Flags flags = PhongGL::Flag::VertexColor|
PhongGL::Flag::VertexColor| PhongGL::Flag::InstancedTransformation|data.flags|flag;
PhongGL::Flag::InstancedTransformation|
PhongGL::Flag::InstancedTextureOffset|data.flags|flag;
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>()) if(GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
@ -2911,25 +2882,58 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
} }
#endif #endif
PhongGL shader{flags, 2}; PhongGL shader{flags, 2};
shader.bindDiffuseTexture(diffuse);
if(data.flags & PhongGL::Flag::NormalTexture) GL::Texture2D diffuse;
shader.bindNormalTexture(normal); GL::Texture2D normal;
if(data.flags & (PhongGL::Flag::DiffuseTexture|PhongGL::Flag::NormalTexture)) {
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
if(data.flags & PhongGL::Flag::DiffuseTexture) {
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0)));
diffuse.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
shader.bindDiffuseTexture(diffuse);
}
if(data.flags & PhongGL::Flag::NormalTexture) {
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(_testDir, "TestFiles/normal-texture.tga")) && (image = importer->image2D(0)));
normal.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
shader.bindNormalTexture(normal);
}
}
if(flag == PhongGL::Flag{}) { if(flag == PhongGL::Flag{}) {
shader shader
.setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f},
{ 3.0f, -3.0f, 2.0f, 0.0f}}) { 3.0f, -3.0f, 2.0f, 0.0f}})
.setLightColors({0x999999_rgbf, 0x999999_rgbf})
.setLightSpecularColors({0x0000ff_rgbf, 0x00ff00_rgbf})
.setTransformationMatrix( .setTransformationMatrix(
Matrix4::translation(Vector3::zAxis(-1.75f))* Matrix4::translation(Vector3::zAxis(-2.15f))*
Matrix4::rotationY(-15.0_degf)* Matrix4::rotationY(90.0_degf)*
Matrix4::rotationX(15.0_degf)*
Matrix4::scaling(Vector3{0.4f})) Matrix4::scaling(Vector3{0.4f}))
.setNormalMatrix((Matrix4::rotationY(-15.0_degf)* .setNormalMatrix(Matrix4::rotationY(90.0_degf).normalMatrix())
Matrix4::rotationX(15.0_degf)).normalMatrix())
.setProjectionMatrix( .setProjectionMatrix(
Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)) Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f))
.setTextureMatrix(Matrix3::scaling(Vector2{0.5f})) .setDiffuseColor(data.flags & PhongGL::Flag::DiffuseTexture ?
.setDiffuseColor(0xffff99_rgbf); 0xffffff_rgbf : 0xffff00_rgbf);
if(data.flags & PhongGL::Flag::TextureTransformation)
shader.setTextureMatrix(Matrix3::scaling(Vector2{0.5f}));
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -2951,34 +2955,39 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
}}; }};
GL::Buffer transformationUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer transformationUniform{GL::Buffer::TargetHint::Uniform, {
TransformationUniform3D{}.setTransformationMatrix( TransformationUniform3D{}.setTransformationMatrix(
Matrix4::translation(Vector3::zAxis(-1.75f))* Matrix4::translation(Vector3::zAxis(-2.15f))*
Matrix4::rotationY(-15.0_degf)* Matrix4::rotationY(90.0_degf)*
Matrix4::rotationX(15.0_degf)*
Matrix4::scaling(Vector3{0.4f}) Matrix4::scaling(Vector3{0.4f})
) )
}}; }};
GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, {
PhongDrawUniform{} PhongDrawUniform{}
.setNormalMatrix( .setNormalMatrix(Matrix4::rotationY(90.0_degf).normalMatrix())
(Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf)).normalMatrix())
.setObjectId(1000) /* gets added to the per-instance ID */ .setObjectId(1000) /* gets added to the per-instance ID */
}}; }};
GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, {
PhongMaterialUniform{} PhongMaterialUniform{}
.setDiffuseColor(0xffff99_rgbf) .setDiffuseColor(data.flags & PhongGL::Flag::DiffuseTexture ?
0xffffff_rgbf : 0xffff00_rgbf)
}}; }};
GL::Buffer textureTransformationUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer textureTransformationUniform{GL::Buffer::TargetHint::Uniform, {
TextureTransformationUniform{} TextureTransformationUniform{}
.setTextureMatrix(Matrix3::scaling(Vector2{0.5f})) .setTextureMatrix(Matrix3::scaling(Vector2{0.5f}))
}}; }};
GL::Buffer lightUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer lightUniform{GL::Buffer::TargetHint::Uniform, {
PhongLightUniform{}.setPosition(Vector4{-3.0f, -3.0f, 2.0f, 0.0f}), PhongLightUniform{}
PhongLightUniform{}.setPosition(Vector4{3.0f, -3.0f, 2.0f, 0.0f}) .setPosition({-3.0f, -3.0f, 2.0f, 0.0f})
.setColor(0x999999_rgbf)
.setSpecularColor(0x0000ff_rgbf),
PhongLightUniform{}
.setPosition({3.0f, -3.0f, 2.0f, 0.0f})
.setColor(0x999999_rgbf)
.setSpecularColor(0x00ff00_rgbf)
}}; }};
if(data.flags & PhongGL::Flag::TextureTransformation)
shader.bindTextureTransformationBuffer(textureTransformationUniform);
shader.bindProjectionBuffer(projectionUniform) shader.bindProjectionBuffer(projectionUniform)
.bindTransformationBuffer(transformationUniform) .bindTransformationBuffer(transformationUniform)
.bindTextureTransformationBuffer(textureTransformationUniform)
.bindDrawBuffer(drawUniform) .bindDrawBuffer(drawUniform)
.bindMaterialBuffer(materialUniform) .bindMaterialBuffer(materialUniform)
.bindLightBuffer(lightUniform) .bindLightBuffer(lightUniform)
@ -2987,6 +2996,25 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
#endif #endif
else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); else CORRADE_INTERNAL_ASSERT_UNREACHABLE();
/*
Colored case:
- First should be lower left, yellow with a blue and green highlight
on bottom left and right part
- Second lower right, cyan with a yellow light, so green, the same
highlight at the same position
- Third up center, magenta with a yellow light, so red, the same
highlight at the same position
Textured case:
- Lower left has bottom left numbers, so light 7881, rotated (78
visible, should look the same as the multidraw case or as Flat)
- Lower light has bottom right, 1223, rotated (23 visible, looking at
the left side of the sphere in the equivalent Flat test)
- Up center has 6778, rotated (78 visible, looking at the left side
of the sphere in the equivalent Flat test)
*/
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_COMPARE_WITH( CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */ /* Dropping the alpha channel, as it's always 1.0 */

BIN
src/Magnum/Shaders/Test/PhongTestFiles/instanced-textured.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/PhongTestFiles/instanced.tga

Binary file not shown.
Loading…
Cancel
Save