Browse Source

Shaders: ability to render instanced object ID in Flat/Phong.

pull/432/head
Vladimír Vondruš 6 years ago
parent
commit
02525527a4
  1. 2
      doc/changelog.dox
  2. 8
      src/Magnum/Shaders/Flat.cpp
  3. 10
      src/Magnum/Shaders/Flat.frag
  4. 40
      src/Magnum/Shaders/Flat.h
  5. 14
      src/Magnum/Shaders/Flat.vert
  6. 8
      src/Magnum/Shaders/Phong.cpp
  7. 10
      src/Magnum/Shaders/Phong.frag
  8. 43
      src/Magnum/Shaders/Phong.h
  9. 14
      src/Magnum/Shaders/Phong.vert
  10. 57
      src/Magnum/Shaders/Test/FlatGLTest.cpp
  11. 20
      src/Magnum/Shaders/Test/FlatTest.cpp
  12. 38
      src/Magnum/Shaders/Test/PhongGLTest.cpp
  13. 20
      src/Magnum/Shaders/Test/PhongTest.cpp

2
doc/changelog.dox

@ -223,6 +223,8 @@ See also:
- Tangent space visualization in @ref Shaders::MeshVisualizer3D
- Texture coordinate transformation in @ref Shaders::DistanceFieldVector,
@ref Shaders::Flat, @ref Shaders::Phong and @ref Shaders::Vector
- Ability to render Per-instance / per-vertex object ID in @ref Shaders::Flat
and @ref Shaders::Phong, in addition to uniform object ID
- New attribute definitions and an location allocation scheme in
@ref Shaders::Generic --- @ref Shaders::Generic::Tangent4,
@ref Shaders::Generic::Bitangent, @ref Shaders::Generic::ObjectId plus

8
src/Magnum/Shaders/Flat.cpp

@ -69,6 +69,9 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(dimensions == 2 ? "#define TWO_DIMENSIONS\n" : "#define THREE_DIMENSIONS\n")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Flat.vert"));
frag.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
@ -76,6 +79,7 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Flat.frag"));
@ -101,6 +105,8 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
bindFragmentDataLocation(ColorOutput, "color");
bindFragmentDataLocation(ObjectIdOutput, "objectId");
}
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif
}
#endif
@ -195,6 +201,7 @@ Debug& operator<<(Debug& debug, const FlatFlag value) {
_c(TextureTransformation)
#ifndef MAGNUM_TARGET_GLES2
_c(ObjectId)
_c(InstancedObjectId)
#endif
#undef _c
/* LCOV_EXCL_STOP */
@ -210,6 +217,7 @@ Debug& operator<<(Debug& debug, const FlatFlags value) {
FlatFlag::VertexColor,
FlatFlag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2
FlatFlag::InstancedObjectId, /* Superset of ObjectId */
FlatFlag::ObjectId
#endif
});

10
src/Magnum/Shaders/Flat.frag

@ -72,6 +72,10 @@ in mediump vec2 interpolatedTextureCoordinates;
in lowp vec4 interpolatedVertexColor;
#endif
#ifdef INSTANCED_OBJECT_ID
flat in highp uint interpolatedInstanceObjectId;
#endif
#ifdef NEW_GLSL
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_OUTPUT_ATTRIBUTE_LOCATION)
@ -104,6 +108,10 @@ void main() {
#endif
#ifdef OBJECT_ID
fragmentObjectId = objectId;
fragmentObjectId =
#ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId +
#endif
objectId;
#endif
}

40
src/Magnum/Shaders/Flat.h

@ -43,7 +43,8 @@ namespace Implementation {
VertexColor = 1 << 2,
TextureTransformation = 1 << 3,
#ifndef MAGNUM_TARGET_GLES2
ObjectId = 1 << 4
ObjectId = 1 << 4,
InstancedObjectId = (1 << 5)|ObjectId
#endif
};
typedef Containers::EnumSet<FlatFlag> FlatFlags;
@ -115,6 +116,11 @@ on framebuffers with integer attachments.
@snippet MagnumShaders.cpp Flat-usage-object-id
If you have a batch of meshes with different object IDs, enable
@ref Flag::InstancedObjectId and supply per-vertex IDs to the @ref ObjectId
attribute. The output will contain a sum of the per-vertex ID and ID coming
from @ref setObjectId().
@requires_gles30 Object ID output requires integer buffer attachments, which
are not available in OpenGL ES 2.0 or WebGL 1.0.
@ -160,6 +166,20 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
*/
typedef typename Generic<dimensions>::Color4 Color4;
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief (Instanced) object ID
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt.
* Used only if @ref Flag::InstancedObjectId is set.
* @requires_gles30 Object ID output requires integer buffer
* attachments, which are not available in OpenGL ES 2.0 or WebGL
* 1.0.
*/
typedef typename Generic<dimensions>::ObjectId ObjectId;
#endif
enum: UnsignedInt {
/**
* Color shader output. Present always, expects three- or
@ -234,7 +254,20 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
* WebGL 1.0.
* @m_since{2019,10}
*/
ObjectId = 1 << 4
ObjectId = 1 << 4,
/**
* Instanced object ID. Retrieves a per-instance / per-vertex
* object ID from the @ref ObjectId attribute, outputting a sum of
* the per-vertex ID and ID coming from @ref setObjectId().
* Implicitly enables @ref Flag::ObjectId. See
* @ref Shaders-Flat-usage-object-id for more information.
* @requires_gles30 Object ID output requires integer buffer
* attachments, which are not available in OpenGL ES 2.0 or
* WebGL 1.0.
* @m_since_latest
*/
InstancedObjectId = (1 << 5)|ObjectId
#endif
};
@ -346,7 +379,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
* Expects that the shader was created with @ref Flag::ObjectId
* enabled. Value set here is written to the @ref ObjectIdOutput, see
* @ref Shaders-Flat-usage-object-id for more information. Default is
* @cpp 0 @ce.
* @cpp 0 @ce. If @ref Flag::InstancedObjectId is enabled as well, this
* value is combined with ID coming from the @ref ObjectId attribute.
* @requires_gles30 Object ID output requires integer buffer
* attachments, which are not available in OpenGL ES 2.0 or WebGL
* 1.0.

14
src/Magnum/Shaders/Flat.vert

@ -87,6 +87,15 @@ in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor;
#endif
#ifdef INSTANCED_OBJECT_ID
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = OBJECT_ID_ATTRIBUTE_LOCATION)
#endif
in highp uint instanceObjectId;
flat out highp uint interpolatedInstanceObjectId;
#endif
void main() {
#ifdef TWO_DIMENSIONS
gl_Position.xywz = vec4(transformationProjectionMatrix*vec3(position, 1.0), 0.0);
@ -111,4 +120,9 @@ void main() {
/* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor;
#endif
#ifdef INSTANCED_OBJECT_ID
/* Instanced object ID, if enabled */
interpolatedInstanceObjectId = instanceObjectId;
#endif
}

8
src/Magnum/Shaders/Phong.cpp

@ -101,6 +101,9 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(Utility::formatString("#define LIGHT_COUNT {}\n", lightCount))
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Phong.vert"));
frag.addSource(flags & Flag::AmbientTexture ? "#define AMBIENT_TEXTURE\n" : "")
@ -111,6 +114,7 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
.addSource(flags & Flag::AlphaMask ? "#define ALPHA_MASK\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(Utility::formatString(
"#define LIGHT_COUNT {}\n"
@ -146,6 +150,8 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
bindFragmentDataLocation(ColorOutput, "color");
bindFragmentDataLocation(ObjectIdOutput, "objectId");
}
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif
}
#endif
@ -355,6 +361,7 @@ Debug& operator<<(Debug& debug, const Phong::Flag value) {
_c(VertexColor)
_c(TextureTransformation)
#ifndef MAGNUM_TARGET_GLES2
_c(InstancedObjectId)
_c(ObjectId)
#endif
#undef _c
@ -374,6 +381,7 @@ Debug& operator<<(Debug& debug, const Phong::Flags value) {
Phong::Flag::VertexColor,
Phong::Flag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2
Phong::Flag::InstancedObjectId, /* Superset of ObjectId */
Phong::Flag::ObjectId
#endif
});

10
src/Magnum/Shaders/Phong.frag

@ -153,6 +153,10 @@ in mediump vec2 interpolatedTextureCoordinates;
in lowp vec4 interpolatedVertexColor;
#endif
#ifdef INSTANCED_OBJECT_ID
flat in highp uint interpolatedInstanceObjectId;
#endif
#ifdef NEW_GLSL
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_OUTPUT_ATTRIBUTE_LOCATION)
@ -229,6 +233,10 @@ void main() {
#endif
#ifdef OBJECT_ID
fragmentObjectId = objectId;
fragmentObjectId =
#ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId +
#endif
objectId;
#endif
}

43
src/Magnum/Shaders/Phong.h

@ -98,10 +98,14 @@ diffuse part and then separate the alpha like this:
The shader supports writing object ID to the framebuffer for object picking or
other annotation purposes. Enable it using @ref Flag::ObjectId and set up an
integer buffer attached to the @ref ObjectIdOutput attachment. The
functionality is practically the same as in the @ref Flat shader, see its
@ref Shaders-Flat-usage-object-id documentation for more information and usage
example.
integer buffer attached to the @ref ObjectIdOutput attachment. If you have a
batch of meshes with different object IDs, enable @ref Flag::InstancedObjectId
and supply per-vertex IDs to the @ref ObjectId attribute. The output will
contain a sum of the per-vertex ID and ID coming from @ref setObjectId().
The functionality is practically the same as in the @ref Flat shader, see
@ref Shaders-Flat-usage-object-id "its documentation" for more information and
usage example.
@requires_gles30 Object ID output requires integer buffer attachments, which
are not available in OpenGL ES 2.0 or WebGL 1.0.
@ -175,6 +179,20 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*/
typedef Generic3D::Color4 Color4;
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief (Instanced) object ID
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::UnsignedInt.
* Used only if @ref Flag::InstancedObjectId is set.
* @requires_gles30 Object ID output requires integer buffer
* attachments, which are not available in OpenGL ES 2.0 or WebGL
* 1.0.
*/
typedef Generic3D::ObjectId ObjectId;
#endif
enum: UnsignedInt {
/**
* Color shader output. @ref shaders-generic "Generic output",
@ -205,7 +223,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*
* @see @ref Flags, @ref flags()
*/
enum class Flag: UnsignedByte {
enum class Flag: UnsignedShort {
/**
* Multiply ambient color with a texture.
* @see @ref setAmbientColor(), @ref bindAmbientTexture()
@ -271,7 +289,20 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* WebGL 1.0.
* @m_since{2019,10}
*/
ObjectId = 1 << 7
ObjectId = 1 << 7,
/**
* Instanced object ID. Retrieves a per-instance / per-vertex
* object ID from the @ref ObjectId attribute, outputting a sum of
* the per-vertex ID and ID coming from @ref setObjectId().
* Implicitly enables @ref Flag::ObjectId. See
* @ref Shaders-Phong-usage-object-id for more information.
* @requires_gles30 Object ID output requires integer buffer
* attachments, which are not available in OpenGL ES 2.0 or
* WebGL 1.0.
* @m_since_latest
*/
InstancedObjectId = (1 << 8)|ObjectId
#endif
};

14
src/Magnum/Shaders/Phong.vert

@ -113,6 +113,15 @@ in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor;
#endif
#ifdef INSTANCED_OBJECT_ID
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = OBJECT_ID_ATTRIBUTE_LOCATION)
#endif
in highp uint instanceObjectId;
flat out highp uint interpolatedInstanceObjectId;
#endif
#if LIGHT_COUNT
out mediump vec3 transformedNormal;
#ifdef NORMAL_TEXTURE
@ -160,4 +169,9 @@ void main() {
/* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor;
#endif
#ifdef INSTANCED_OBJECT_ID
/* Instanced object ID, if enabled */
interpolatedInstanceObjectId = instanceObjectId;
#endif
}

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

@ -143,6 +143,7 @@ constexpr struct {
{"vertex colors + textured", Flat2D::Flag::VertexColor|Flat2D::Flag::Textured},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", Flat2D::Flag::ObjectId},
{"instanced object ID", Flat2D::Flag::InstancedObjectId},
{"object ID + alpha mask + textured", Flat2D::Flag::ObjectId|Flat2D::Flag::AlphaMask|Flat2D::Flag::Textured}
#endif
};
@ -182,6 +183,23 @@ const struct {
Flat2D::Flag::Textured|Flat2D::Flag::AlphaMask, 1.0f}
};
#ifndef MAGNUM_TARGET_GLES2
constexpr struct {
const char* name;
Flat2D::Flags flags;
UnsignedInt uniformId;
UnsignedInt instanceCount;
UnsignedInt expected;
} RenderObjectIdData[] {
{"", /* Verify that it can hold 16 bits at least */
Flat2D::Flag::ObjectId, 48526, 0, 48526},
{"instanced, first instance",
Flat2D::Flag::InstancedObjectId, 13524, 1, 24526},
{"instanced, second instance",
Flat2D::Flag::InstancedObjectId, 13524, 2, 62347}
};
#endif
FlatGLTest::FlatGLTest() {
addInstancedTests<FlatGLTest>({
&FlatGLTest::construct<2>,
@ -236,8 +254,9 @@ FlatGLTest::FlatGLTest() {
&FlatGLTest::renderAlphaTeardown);
#ifndef MAGNUM_TARGET_GLES2
addTests({&FlatGLTest::renderObjectId2D,
&FlatGLTest::renderObjectId3D},
addInstancedTests({&FlatGLTest::renderObjectId2D,
&FlatGLTest::renderObjectId3D},
Containers::arraySize(RenderObjectIdData),
&FlatGLTest::renderObjectIdSetup,
&FlatGLTest::renderObjectIdTeardown);
#endif
@ -975,14 +994,23 @@ void FlatGLTest::renderObjectIdTeardown() {
}
void FlatGLTest::renderObjectId2D() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete);
GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32));
Flat2D{Flat3D::Flag::ObjectId}
if(data.instanceCount) circle
.setInstanceCount(data.instanceCount)
.addVertexBufferInstanced(
GL::Buffer{Containers::arrayView({11002u, 48823u})},
1, 0, Flat2D::ObjectId{});
Flat2D{data.flags}
.setColor(0x9999ff_rgbf)
.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f}))
.setObjectId(47523)
.setObjectId(data.uniformId)
.draw(circle);
MAGNUM_VERIFY_NO_GL_ERROR();
@ -1014,23 +1042,32 @@ void FlatGLTest::renderObjectId2D() {
MAGNUM_VERIFY_NO_GL_ERROR();
/* Outside of the object, cleared to 27 */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27);
/* Inside of the object. Verify that it can hold 16 bits at least. */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 47523);
/* Inside of the object */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], data.expected);
}
void FlatGLTest::renderObjectId3D() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete);
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32));
Flat3D{Flat3D::Flag::ObjectId}
if(data.instanceCount) sphere
.setInstanceCount(data.instanceCount)
.addVertexBufferInstanced(
GL::Buffer{Containers::arrayView({11002u, 48823u})},
1, 0, Flat2D::ObjectId{});
Flat3D{data.flags}
.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))
.setObjectId(48526)
.setObjectId(data.uniformId)
.draw(sphere);
MAGNUM_VERIFY_NO_GL_ERROR();
@ -1065,8 +1102,8 @@ void FlatGLTest::renderObjectId3D() {
MAGNUM_VERIFY_NO_GL_ERROR();
/* Outside of the object, cleared to 27 */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27);
/* Inside of the object. Verify that it can hold 16 bits at least. */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 48526);
/* Inside of the object */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], data.expected);
}
#endif

20
src/Magnum/Shaders/Test/FlatTest.cpp

@ -39,6 +39,9 @@ struct FlatTest: TestSuite::Tester {
void debugFlag();
void debugFlags();
#ifndef MAGNUM_TARGET_GLES2
void debugFlagsInstancedObjectId();
#endif
};
FlatTest::FlatTest() {
@ -49,7 +52,11 @@ FlatTest::FlatTest() {
&FlatTest::constructCopy<3>,
&FlatTest::debugFlag,
&FlatTest::debugFlags});
&FlatTest::debugFlags,
#ifndef MAGNUM_TARGET_GLES2
&FlatTest::debugFlagsInstancedObjectId
#endif
});
}
template<UnsignedInt dimensions> void FlatTest::constructNoCreate() {
@ -87,6 +94,17 @@ void FlatTest::debugFlags() {
CORRADE_COMPARE(out.str(), "Shaders::Flat::Flag::Textured|Shaders::Flat::Flag::AlphaMask Shaders::Flat::Flags{}\n");
}
#ifndef MAGNUM_TARGET_GLES2
void FlatTest::debugFlagsInstancedObjectId() {
std::ostringstream out;
/* InstancedObjectId is a superset of ObjectId so only one should be
*printed */
Debug{&out} << (Flat3D::Flag::ObjectId|Flat3D::Flag::InstancedObjectId);
CORRADE_COMPARE(out.str(), "Shaders::Flat::Flag::InstancedObjectId\n");
}
#endif
}}}}
CORRADE_TEST_MAIN(Magnum::Shaders::Test::FlatTest)

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

@ -151,6 +151,7 @@ constexpr struct {
{"vertex colors + diffuse texture", Phong::Flag::VertexColor|Phong::Flag::DiffuseTexture, 1},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", Phong::Flag::ObjectId, 1},
{"instanced object ID", Phong::Flag::InstancedObjectId, 1},
{"object ID + alpha mask + specular texture", Phong::Flag::ObjectId|Phong::Flag::AlphaMask|Phong::Flag::SpecularTexture, 1},
#endif
{"five lights", {}, 5},
@ -266,6 +267,23 @@ const struct {
0xffffffff_rgbaf, 0x9999ff00_rgbaf}
};
#ifndef MAGNUM_TARGET_GLES2
constexpr struct {
const char* name;
Phong::Flags flags;
UnsignedInt uniformId;
UnsignedInt instanceCount;
UnsignedInt expected;
} RenderObjectIdData[] {
{"", /* Verify that it can hold 16 bits at least */
Phong::Flag::ObjectId, 48526, 0, 48526},
{"instanced, first instance",
Phong::Flag::InstancedObjectId, 13524, 1, 24526},
{"instanced, second instance",
Phong::Flag::InstancedObjectId, 13524, 2, 62347}
};
#endif
PhongGLTest::PhongGLTest() {
addInstancedTests({&PhongGLTest::construct}, Containers::arraySize(ConstructData));
@ -322,7 +340,8 @@ PhongGLTest::PhongGLTest() {
&PhongGLTest::renderAlphaTeardown);
#ifndef MAGNUM_TARGET_GLES2
addTests({&PhongGLTest::renderObjectId},
addInstancedTests({&PhongGLTest::renderObjectId},
Containers::arraySize(RenderObjectIdData),
&PhongGLTest::renderObjectIdSetup,
&PhongGLTest::renderObjectIdTeardown);
#endif
@ -1158,11 +1177,20 @@ void PhongGLTest::renderObjectIdTeardown() {
}
void PhongGLTest::renderObjectId() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete);
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32));
Phong{Phong::Flag::ObjectId, 2}
if(data.instanceCount) sphere
.setInstanceCount(data.instanceCount)
.addVertexBufferInstanced(
GL::Buffer{Containers::arrayView({11002u, 48823u})},
1, 0, Phong::ObjectId{});
Phong{data.flags, 2}
.setLightColors({0x993366_rgbf, 0x669933_rgbf})
.setLightPositions({{-3.0f, -3.0f, 0.0f},
{ 3.0f, -3.0f, 0.0f}})
@ -1171,7 +1199,7 @@ void PhongGLTest::renderObjectId() {
.setSpecularColor(0x6666ff_rgbf)
.setTransformationMatrix(Matrix4::translation(Vector3::zAxis(-2.15f)))
.setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f))
.setObjectId(48526)
.setObjectId(data.uniformId)
.draw(sphere);
MAGNUM_VERIFY_NO_GL_ERROR();
@ -1205,8 +1233,8 @@ void PhongGLTest::renderObjectId() {
MAGNUM_VERIFY_NO_GL_ERROR();
/* Outside of the object, cleared to 27 */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27);
/* Inside of the object. Verify that it can hold 16 bits at least. */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 48526);
/* Inside of the object */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], data.expected);
}
#endif

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

@ -39,6 +39,9 @@ struct PhongTest: TestSuite::Tester {
void debugFlag();
void debugFlags();
#ifndef MAGNUM_TARGET_GLES2
void debugFlagsInstancedObjectId();
#endif
};
PhongTest::PhongTest() {
@ -46,7 +49,11 @@ PhongTest::PhongTest() {
&PhongTest::constructCopy,
&PhongTest::debugFlag,
&PhongTest::debugFlags});
&PhongTest::debugFlags,
#ifndef MAGNUM_TARGET_GLES2
&PhongTest::debugFlagsInstancedObjectId
#endif
});
}
void PhongTest::constructNoCreate() {
@ -77,6 +84,17 @@ 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;
/* 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");
}
#endif
}}}}
CORRADE_TEST_MAIN(Magnum::Shaders::Test::PhongTest)

Loading…
Cancel
Save