Browse Source

Shaders: implement instancing in Phong.

pull/433/head
Vladimír Vondruš 6 years ago
parent
commit
55685ea382
  1. 2
      doc/changelog.dox
  2. 22
      doc/snippets/MagnumShaders.cpp
  3. 13
      src/Magnum/Shaders/Phong.cpp
  4. 113
      src/Magnum/Shaders/Phong.h
  5. 43
      src/Magnum/Shaders/Phong.vert
  6. 2
      src/Magnum/Shaders/Test/CMakeLists.txt
  7. 160
      src/Magnum/Shaders/Test/PhongGLTest.cpp
  8. 32
      src/Magnum/Shaders/Test/PhongTest.cpp
  9. BIN
      src/Magnum/Shaders/Test/PhongTestFiles/instanced-normal.tga
  10. BIN
      src/Magnum/Shaders/Test/PhongTestFiles/instanced.tga

2
doc/changelog.dox

@ -233,7 +233,7 @@ See also:
@ref Shaders::Generic::TransformationMatrix,
@ref Shaders::Generic::NormalMatrix and
@ref Shaders::Generic::TextureOffset for instancing
- Instancing in @ref Shaders::Flat
- Instancing in @ref Shaders::Flat and @ref Shaders::Phong
@subsubsection changelog-latest-new-trade Trade library

22
doc/snippets/MagnumShaders.cpp

@ -269,6 +269,28 @@ mesh.setInstanceCount(Containers::arraySize(instanceData))
/* [Flat-usage-instancing] */
}
{
GL::Mesh mesh;
/* [Phong-usage-instancing] */
struct {
Matrix4 transformation;
Matrix3x3 normal;
} instanceData[] {
{Matrix4::translation({1.0f, 2.0f, 0.0f})*Matrix4::rotationX(90.0_degf), {}},
{Matrix4::translation({2.0f, 1.0f, 0.0f})*Matrix4::rotationY(90.0_degf), {}},
{Matrix4::translation({3.0f, 0.0f, 1.0f})*Matrix4::rotationZ(90.0_degf), {}},
// ...
};
for(auto& instance: instanceData)
instance.normal = instance.transformation.normalMatrix();
mesh.setInstanceCount(Containers::arraySize(instanceData))
.addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0,
Shaders::Phong::TransformationMatrix{},
Shaders::Phong::NormalMatrix{});
/* [Phong-usage-instancing] */
}
{
/* [MeshVisualizer-usage-geom1] */
struct Vertex {

13
src/Magnum/Shaders/Phong.cpp

@ -104,6 +104,8 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(flags & Flag::InstancedTransformation ? "#define INSTANCED_TRANSFORMATION\n" : "")
.addSource(flags >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : "")
.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Phong.vert"));
frag.addSource(flags & Flag::AmbientTexture ? "#define AMBIENT_TEXTURE\n" : "")
@ -152,6 +154,10 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
}
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
if(flags & Flag::InstancedTransformation)
bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix");
if(flags >= Flag::InstancedTextureOffset)
bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
#endif
}
#endif
@ -364,6 +370,8 @@ Debug& operator<<(Debug& debug, const Phong::Flag value) {
_c(InstancedObjectId)
_c(ObjectId)
#endif
_c(InstancedTransformation)
_c(InstancedTextureOffset)
#undef _c
/* LCOV_EXCL_STOP */
}
@ -379,12 +387,13 @@ Debug& operator<<(Debug& debug, const Phong::Flags value) {
Phong::Flag::NormalTexture,
Phong::Flag::AlphaMask,
Phong::Flag::VertexColor,
Phong::Flag::InstancedTextureOffset, /* Superset of TextureTransformation */
Phong::Flag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2
Phong::Flag::InstancedObjectId, /* Superset of ObjectId */
Phong::Flag::ObjectId
Phong::Flag::ObjectId,
#endif
});
Phong::Flag::InstancedTransformation});
}
}}

113
src/Magnum/Shaders/Phong.h

@ -106,6 +106,30 @@ example.
@requires_gles30 Object ID output requires integer buffer attachments, which
are not available in OpenGL ES 2.0 or WebGL 1.0.
@section Shaders-Phong-instancing Instanced rendering
Enabling @ref Flag::InstancedTransformation will turn the shader into an
instanced one. It'll take per-instance transformation and normal matrix from
the @ref TransformationMatrix and @ref NormalMatrix attributes, applying those
before the matrix set by @ref setTransformationMatrix() and
@ref setNormalMatrix(). Besides that, @ref Flag::VertexColor (and the
@ref Color3 / @ref Color4) attributes can work as both per-vertex and
per-instance, and for texturing it's possible to have per-instance texture
offset taken from @ref TextureOffset when @ref Flag::InstancedTextureOffset is
enabled (similarly to transformation, applied before @ref setTextureMatrix()).
The snippet below shows adding a buffer with per-instance transformation to a
mesh --- note how a normal matrix attribute has to be populated and supplied as
well to ensure lighting works:
@snippet MagnumShaders.cpp Phong-usage-instancing
@requires_gl33 Extension @gl_extension{ARB,instanced_arrays}
@requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays},
@gl_extension{EXT,instanced_arrays} or @gl_extension{NV,instanced_arrays}
in OpenGL ES 2.0.
@requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} in WebGL
1.0.
@section Shaders-Phong-zero-lights Zero lights
Creating this shader with zero lights makes its output equivalent to the
@ -113,7 +137,10 @@ Creating this shader with zero lights makes its output equivalent to the
(if @ref Flag::AmbientTexture is enabled) are taken into account, which
correspond to @ref Flat::setColor() and @ref Flat::bindTexture(). This is
useful to reduce complexity in apps that render models with pre-baked lights.
In addition, enabling @ref Flag::VertexColor and using a default ambient color with no texturing makes this shader equivalent to @ref VertexColor.
For instanced workflows using zero lights means the @ref NormalMatrix instance
attribute doesn't need to be supplied either. In addition, enabling
@ref Flag::VertexColor and using a default ambient color with no texturing
makes this shader equivalent to @ref VertexColor.
@see @ref shaders
*/
@ -189,6 +216,51 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
typedef Generic3D::ObjectId ObjectId;
#endif
/**
* @brief (Instanced) transformation matrix
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Matrix4.
* Used only if @ref Flag::InstancedTransformation is set.
* @requires_gl33 Extension @gl_extension{ARB,instanced_arrays}
* @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays},
* @gl_extension{EXT,instanced_arrays} or
* @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
*/
typedef Generic3D::TransformationMatrix TransformationMatrix;
/**
* @brief (Instanced) normal matrix
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Matrix3x3.
* Used only if @ref Flag::InstancedTransformation is set.
* @requires_gl33 Extension @gl_extension{ARB,instanced_arrays}
* @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays},
* @gl_extension{EXT,instanced_arrays} or
* @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
*/
typedef Generic3D::NormalMatrix NormalMatrix;
/**
* @brief (Instanced) texture offset
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Vector2. Used
* only if @ref Flag::InstancedTextureOffset is set.
* @requires_gl33 Extension @gl_extension{ARB,instanced_arrays}
* @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays},
* @gl_extension{EXT,instanced_arrays} or
* @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
*/
typedef typename Generic3D::TextureOffset TextureOffset;
enum: UnsignedInt {
/**
* Color shader output. @ref shaders-generic "Generic output",
@ -298,8 +370,45 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* WebGL 1.0.
* @m_since_latest
*/
InstancedObjectId = (1 << 8)|ObjectId
InstancedObjectId = (1 << 8)|ObjectId,
#endif
/**
* Instanced transformation. Retrieves a per-instance
* transformation and normal matrix from the
* @ref TransformationMatrix / @ref NormalMatrix attributes and
* uses them together with matrices coming from
* @ref setTransformationMatrix() and @ref setNormalMatrix() (first
* the per-instance, then the uniform matrix). See
* @ref Shaders-Phong-instancing for more information.
* @requires_gl33 Extension @gl_extension{ARB,instanced_arrays}
* @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays},
* @gl_extension{EXT,instanced_arrays} or
* @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
* @m_since_latest
*/
InstancedTransformation = 1 << 9,
/**
* Instanced texture offset. Retrieves a per-instance offset vector
* from the @ref TextureOffset attribute and uses it together with
* the matrix coming from @ref setTextureMatrix() (first the
* per-instance vector, then the uniform matrix). Instanced texture
* scaling and rotation is not supported at the moment, you can
* specify that only via the uniform @ref setTextureMatrix().
* Implicitly enables @ref Flag::TextureTransformation. See
* @ref Shaders-Phong-instancing for more information.
* @requires_gl33 Extension @gl_extension{ARB,instanced_arrays}
* @requires_gles30 Extension @gl_extension{ANGLE,instanced_arrays},
* @gl_extension{EXT,instanced_arrays} or
* @gl_extension{NV,instanced_arrays} in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays}
* in WebGL 1.0.
* @m_since_latest
*/
InstancedTextureOffset = (1 << 10)|TextureTransformation
};
/**

43
src/Magnum/Shaders/Phong.vert

@ -122,6 +122,25 @@ in highp uint instanceObjectId;
flat out highp uint interpolatedInstanceObjectId;
#endif
#ifdef INSTANCED_TRANSFORMATION
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = TRANSFORMATION_MATRIX_ATTRIBUTE_LOCATION)
#endif
in highp mat4 instancedTransformationMatrix;
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = NORMAL_MATRIX_ATTRIBUTE_LOCATION)
#endif
in highp mat3 instancedNormalMatrix;
#endif
#ifdef INSTANCED_TEXTURE_OFFSET
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = TEXTURE_OFFSET_ATTRIBUTE_LOCATION)
#endif
in mediump vec2 instancedTextureOffset;
#endif
#if LIGHT_COUNT
out mediump vec3 transformedNormal;
#ifdef NORMAL_TEXTURE
@ -133,14 +152,26 @@ out highp vec3 cameraDirection;
void main() {
/* Transformed vertex position */
highp vec4 transformedPosition4 = transformationMatrix*position;
highp vec4 transformedPosition4 = transformationMatrix*
#ifdef INSTANCED_TRANSFORMATION
instancedTransformationMatrix*
#endif
position;
highp vec3 transformedPosition = transformedPosition4.xyz/transformedPosition4.w;
#if LIGHT_COUNT
/* Transformed normal and tangent vector */
transformedNormal = normalMatrix*normal;
transformedNormal = normalMatrix*
#ifdef INSTANCED_TRANSFORMATION
instancedNormalMatrix*
#endif
normal;
#ifdef NORMAL_TEXTURE
transformedTangent = normalMatrix*tangent;
transformedTangent = normalMatrix*
#ifdef INSTANCED_TRANSFORMATION
instancedNormalMatrix*
#endif
tangent;
#endif
/* Direction to the light */
@ -158,7 +189,11 @@ void main() {
/* Texture coordinates, if needed */
interpolatedTextureCoordinates =
#ifdef TEXTURE_TRANSFORMATION
(textureMatrix*vec3(textureCoordinates, 1.0)).xy
(textureMatrix*vec3(
#ifdef INSTANCED_TEXTURE_OFFSET
instancedTextureOffset +
#endif
textureCoordinates, 1.0)).xy
#else
textureCoordinates
#endif

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

@ -211,6 +211,8 @@ if(BUILD_GL_TESTS)
PhongTestFiles/colored.tga
PhongTestFiles/defaults.tga
PhongTestFiles/instanced.tga
PhongTestFiles/instanced-normal.tga
PhongTestFiles/shininess-black-specular.tga
PhongTestFiles/shininess0-overflow.tga
PhongTestFiles/shininess0.tga

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

@ -35,6 +35,7 @@
#include "Magnum/PixelFormat.h"
#include "Magnum/DebugTools/CompareImage.h"
#include "Magnum/GL/Context.h"
#include "Magnum/GL/Extensions.h"
#include "Magnum/GL/Framebuffer.h"
#include "Magnum/GL/Mesh.h"
#include "Magnum/GL/OpenGLTester.h"
@ -104,6 +105,8 @@ struct PhongGLTest: GL::OpenGLTester {
void renderZeroLights();
void renderInstanced();
private:
PluginManager::Manager<Trade::AbstractImporter> _manager{"nonexistent"};
std::string _testDir;
@ -121,12 +124,12 @@ struct PhongGLTest: GL::OpenGLTester {
- Mesa Intel
- Mesa AMD
- SwiftShader ES2/ES3
- ARM Mali (Huawei P10) ES2/ES3
- WebGL 1 / 2 (on Mesa Intel)
- NVidia Windows
- Intel Windows
- AMD on macOS
- iPhone 6 w/ iOS 12.4
- ARM Mali (Huawei P10) ES2/ES3 (except instancing)
- WebGL 1 / 2 (on Mesa Intel) (except instancing)
- NVidia Windows (except instancing)
- Intel Windows (except instancing)
- AMD on macOS (except instancing)
- iPhone 6 w/ iOS 12.4 (except instancing)
*/
constexpr struct {
@ -155,7 +158,10 @@ constexpr struct {
{"object ID + alpha mask + specular texture", Phong::Flag::ObjectId|Phong::Flag::AlphaMask|Phong::Flag::SpecularTexture, 1},
#endif
{"five lights", {}, 5},
{"zero lights", {}, 0}
{"zero lights", {}, 0},
{"instanced transformation", Phong::Flag::InstancedTransformation, 3},
{"instanced specular texture offset", Phong::Flag::SpecularTexture|Phong::Flag::InstancedTextureOffset, 3},
{"instanced normal texture offset", Phong::Flag::NormalTexture|Phong::Flag::InstancedTextureOffset, 3}
};
using namespace Math::Literals;
@ -284,6 +290,32 @@ constexpr struct {
};
#endif
constexpr struct {
const char* name;
const char* file;
Phong::Flags flags;
Float maxThreshold, meanThreshold;
} RenderInstancedData[] {
{"diffuse", "instanced.tga", {},
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/* AMD has one off pixel; SwiftShader a bit more */
93.67f, 0.106f,
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage */
93.67f, 0.106f,
#endif
},
{"diffuse + normal", "instanced-normal.tga", Phong::Flag::NormalTexture,
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/* AMD has one off pixel */
94.0f, 0.132f,
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage */
94.0f, 0.132f,
#endif
}
};
PhongGLTest::PhongGLTest() {
addInstancedTests({&PhongGLTest::construct}, Containers::arraySize(ConstructData));
@ -356,6 +388,11 @@ PhongGLTest::PhongGLTest() {
#endif
);
addInstancedTests({&PhongGLTest::renderInstanced},
Containers::arraySize(RenderInstancedData),
&PhongGLTest::renderSetup,
&PhongGLTest::renderTeardown);
/* 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
@ -1332,6 +1369,115 @@ void PhongGLTest::renderZeroLights() {
#endif
}
void PhongGLTest::renderInstanced() {
auto&& data = RenderInstancedData[testCaseInstanceId()];
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::instanced_arrays>())
CORRADE_SKIP(GL::Extensions::ARB::instanced_arrays::string() + std::string(" is not supported"));
#elif defined(MAGNUM_TARGET_GLES2)
#ifndef MAGNUM_TARGET_WEBGL
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ANGLE::instanced_arrays>() &&
!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::instanced_arrays>() &&
!GL::Context::current().isExtensionSupported<GL::Extensions::NV::instanced_arrays>())
CORRADE_SKIP("GL_{ANGLE,EXT,NV}_instanced_arrays is not supported");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ANGLE::instanced_arrays>())
CORRADE_SKIP(GL::Extensions::ANGLE::instanced_arrays::string() + std::string(" is not supported"));
#endif
#endif
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::UVSphereFlag::TextureCoordinates|
Primitives::UVSphereFlag::Tangents));
/* Three spheres, each in a different location, differently rotated to
ensure the normal matrix is properly used as well. */
struct {
Matrix4 transformation;
Matrix3x3 normal;
Color3 color;
Vector2 textureOffset;
} instanceData[] {
{Matrix4::translation({-1.25f, -1.25f, 0.0f})*
Matrix4::rotationX(90.0_degf),
{}, 0xff3333_rgbf, {0.0f, 0.0f}},
{Matrix4::translation({ 1.25f, -1.25f, 0.0f})*
Matrix4::rotationY(90.0_degf),
{}, 0x33ff33_rgbf, {1.0f, 0.0f}},
{Matrix4::translation({ 0.0f, 1.0f, 1.0f})*
Matrix4::rotationZ(90.0_degf),
{}, 0x9999ff_rgbf, {0.5f, 1.0f}}
};
for(auto& instance: instanceData)
instance.normal = instance.transformation.normalMatrix();
sphere
.addVertexBufferInstanced(GL::Buffer{instanceData}, 1, 0,
Phong::TransformationMatrix{},
Phong::NormalMatrix{},
Phong::Color3{},
Phong::TextureOffset{})
.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);
Phong shader{Phong::Flag::DiffuseTexture|
Phong::Flag::VertexColor|
Phong::Flag::InstancedTransformation|
Phong::Flag::InstancedTextureOffset|data.flags, 2};
shader
.setLightPositions({{-3.0f, -3.0f, 0.0f},
{ 3.0f, -3.0f, 0.0f}})
.setTransformationMatrix(
Matrix4::translation(Vector3::zAxis(-1.75f))*
Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf)*
Matrix4::scaling(Vector3{0.4f}))
.setNormalMatrix((Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf)).normalMatrix())
.setProjectionMatrix(
Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f))
.setTextureMatrix(Matrix3::scaling(Vector2{0.5f}))
.bindDiffuseTexture(diffuse)
.setDiffuseColor(0xffff99_rgbf);
if(data.flags & Phong::Flag::NormalTexture)
shader.bindNormalTexture(normal);
shader.draw(sphere);
MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join({_testDir, "PhongTestFiles", data.file}),
(DebugTools::CompareImageToFile{_manager, data.maxThreshold, data.meanThreshold}));
}
}}}}
CORRADE_TEST_MAIN(Magnum::Shaders::Test::PhongGLTest)

32
src/Magnum/Shaders/Test/PhongTest.cpp

@ -39,9 +39,7 @@ struct PhongTest: TestSuite::Tester {
void debugFlag();
void debugFlags();
#ifndef MAGNUM_TARGET_GLES2
void debugFlagsInstancedObjectId();
#endif
void debugFlagsSupersets();
};
PhongTest::PhongTest() {
@ -50,10 +48,7 @@ PhongTest::PhongTest() {
&PhongTest::debugFlag,
&PhongTest::debugFlags,
#ifndef MAGNUM_TARGET_GLES2
&PhongTest::debugFlagsInstancedObjectId
#endif
});
&PhongTest::debugFlagsSupersets});
}
void PhongTest::constructNoCreate() {
@ -84,16 +79,23 @@ void PhongTest::debugFlags() {
CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::DiffuseTexture|Shaders::Phong::Flag::SpecularTexture Shaders::Phong::Flags{}\n");
}
#ifndef MAGNUM_TARGET_GLES2
void PhongTest::debugFlagsInstancedObjectId() {
std::ostringstream out;
void PhongTest::debugFlagsSupersets() {
#ifndef MAGNUM_TARGET_GLES2
/* InstancedObjectId is a superset of ObjectId so only one should be
*printed */
Debug{&out} << (Phong::Flag::ObjectId|Phong::Flag::InstancedObjectId);
CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::InstancedObjectId\n");
printed */
{
std::ostringstream out;
Debug{&out} << (Phong::Flag::ObjectId|Phong::Flag::InstancedObjectId);
CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::InstancedObjectId\n");
}
#endif
/* InstancedTextureOffset is a superset of TextureTransformation so only
one should be printed */
std::ostringstream out;
Debug{&out} << (Phong::Flag::InstancedTextureOffset|Phong::Flag::TextureTransformation);
CORRADE_COMPARE(out.str(), "Shaders::Phong::Flag::InstancedTextureOffset\n");
}
#endif
}}}}

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

Binary file not shown.

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

Binary file not shown.
Loading…
Cancel
Save