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 - Tangent space visualization in @ref Shaders::MeshVisualizer3D
- Texture coordinate transformation in @ref Shaders::DistanceFieldVector, - Texture coordinate transformation in @ref Shaders::DistanceFieldVector,
@ref Shaders::Flat, @ref Shaders::Phong and @ref Shaders::Vector @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 - New attribute definitions and an location allocation scheme in
@ref Shaders::Generic --- @ref Shaders::Generic::Tangent4, @ref Shaders::Generic --- @ref Shaders::Generic::Tangent4,
@ref Shaders::Generic::Bitangent, @ref Shaders::Generic::ObjectId plus @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::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "") .addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(dimensions == 2 ? "#define TWO_DIMENSIONS\n" : "#define THREE_DIMENSIONS\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("generic.glsl"))
.addSource(rs.get("Flat.vert")); .addSource(rs.get("Flat.vert"));
frag.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "") 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" : "") .addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "") .addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif #endif
.addSource(rs.get("generic.glsl")) .addSource(rs.get("generic.glsl"))
.addSource(rs.get("Flat.frag")); .addSource(rs.get("Flat.frag"));
@ -101,6 +105,8 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
bindFragmentDataLocation(ColorOutput, "color"); bindFragmentDataLocation(ColorOutput, "color");
bindFragmentDataLocation(ObjectIdOutput, "objectId"); bindFragmentDataLocation(ObjectIdOutput, "objectId");
} }
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif #endif
} }
#endif #endif
@ -195,6 +201,7 @@ Debug& operator<<(Debug& debug, const FlatFlag value) {
_c(TextureTransformation) _c(TextureTransformation)
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
_c(ObjectId) _c(ObjectId)
_c(InstancedObjectId)
#endif #endif
#undef _c #undef _c
/* LCOV_EXCL_STOP */ /* LCOV_EXCL_STOP */
@ -210,6 +217,7 @@ Debug& operator<<(Debug& debug, const FlatFlags value) {
FlatFlag::VertexColor, FlatFlag::VertexColor,
FlatFlag::TextureTransformation, FlatFlag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
FlatFlag::InstancedObjectId, /* Superset of ObjectId */
FlatFlag::ObjectId FlatFlag::ObjectId
#endif #endif
}); });

10
src/Magnum/Shaders/Flat.frag

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

40
src/Magnum/Shaders/Flat.h

@ -43,7 +43,8 @@ namespace Implementation {
VertexColor = 1 << 2, VertexColor = 1 << 2,
TextureTransformation = 1 << 3, TextureTransformation = 1 << 3,
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
ObjectId = 1 << 4 ObjectId = 1 << 4,
InstancedObjectId = (1 << 5)|ObjectId
#endif #endif
}; };
typedef Containers::EnumSet<FlatFlag> FlatFlags; typedef Containers::EnumSet<FlatFlag> FlatFlags;
@ -115,6 +116,11 @@ on framebuffers with integer attachments.
@snippet MagnumShaders.cpp Flat-usage-object-id @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 @requires_gles30 Object ID output requires integer buffer attachments, which
are not available in OpenGL ES 2.0 or WebGL 1.0. 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; 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 { enum: UnsignedInt {
/** /**
* Color shader output. Present always, expects three- or * 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. * WebGL 1.0.
* @m_since{2019,10} * @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 #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 * Expects that the shader was created with @ref Flag::ObjectId
* enabled. Value set here is written to the @ref ObjectIdOutput, see * enabled. Value set here is written to the @ref ObjectIdOutput, see
* @ref Shaders-Flat-usage-object-id for more information. Default is * @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 * @requires_gles30 Object ID output requires integer buffer
* attachments, which are not available in OpenGL ES 2.0 or WebGL * attachments, which are not available in OpenGL ES 2.0 or WebGL
* 1.0. * 1.0.

14
src/Magnum/Shaders/Flat.vert

@ -87,6 +87,15 @@ in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor; out lowp vec4 interpolatedVertexColor;
#endif #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() { void main() {
#ifdef TWO_DIMENSIONS #ifdef TWO_DIMENSIONS
gl_Position.xywz = vec4(transformationProjectionMatrix*vec3(position, 1.0), 0.0); gl_Position.xywz = vec4(transformationProjectionMatrix*vec3(position, 1.0), 0.0);
@ -111,4 +120,9 @@ void main() {
/* Vertex colors, if enabled */ /* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor; interpolatedVertexColor = vertexColor;
#endif #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::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "") .addSource(flags & Flag::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(Utility::formatString("#define LIGHT_COUNT {}\n", lightCount)) .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("generic.glsl"))
.addSource(rs.get("Phong.vert")); .addSource(rs.get("Phong.vert"));
frag.addSource(flags & Flag::AmbientTexture ? "#define AMBIENT_TEXTURE\n" : "") 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" : "") .addSource(flags & Flag::AlphaMask ? "#define ALPHA_MASK\n" : "")
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "") .addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif #endif
.addSource(Utility::formatString( .addSource(Utility::formatString(
"#define LIGHT_COUNT {}\n" "#define LIGHT_COUNT {}\n"
@ -146,6 +150,8 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
bindFragmentDataLocation(ColorOutput, "color"); bindFragmentDataLocation(ColorOutput, "color");
bindFragmentDataLocation(ObjectIdOutput, "objectId"); bindFragmentDataLocation(ObjectIdOutput, "objectId");
} }
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif #endif
} }
#endif #endif
@ -355,6 +361,7 @@ Debug& operator<<(Debug& debug, const Phong::Flag value) {
_c(VertexColor) _c(VertexColor)
_c(TextureTransformation) _c(TextureTransformation)
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
_c(InstancedObjectId)
_c(ObjectId) _c(ObjectId)
#endif #endif
#undef _c #undef _c
@ -374,6 +381,7 @@ Debug& operator<<(Debug& debug, const Phong::Flags value) {
Phong::Flag::VertexColor, Phong::Flag::VertexColor,
Phong::Flag::TextureTransformation, Phong::Flag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
Phong::Flag::InstancedObjectId, /* Superset of ObjectId */
Phong::Flag::ObjectId Phong::Flag::ObjectId
#endif #endif
}); });

10
src/Magnum/Shaders/Phong.frag

@ -153,6 +153,10 @@ in mediump vec2 interpolatedTextureCoordinates;
in lowp vec4 interpolatedVertexColor; in lowp vec4 interpolatedVertexColor;
#endif #endif
#ifdef INSTANCED_OBJECT_ID
flat in highp uint interpolatedInstanceObjectId;
#endif
#ifdef NEW_GLSL #ifdef NEW_GLSL
#ifdef EXPLICIT_ATTRIB_LOCATION #ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_OUTPUT_ATTRIBUTE_LOCATION) layout(location = COLOR_OUTPUT_ATTRIBUTE_LOCATION)
@ -229,6 +233,10 @@ void main() {
#endif #endif
#ifdef OBJECT_ID #ifdef OBJECT_ID
fragmentObjectId = objectId; fragmentObjectId =
#ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId +
#endif
objectId;
#endif #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 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 other annotation purposes. Enable it using @ref Flag::ObjectId and set up an
integer buffer attached to the @ref ObjectIdOutput attachment. The integer buffer attached to the @ref ObjectIdOutput attachment. If you have a
functionality is practically the same as in the @ref Flat shader, see its batch of meshes with different object IDs, enable @ref Flag::InstancedObjectId
@ref Shaders-Flat-usage-object-id documentation for more information and usage and supply per-vertex IDs to the @ref ObjectId attribute. The output will
example. 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 @requires_gles30 Object ID output requires integer buffer attachments, which
are not available in OpenGL ES 2.0 or WebGL 1.0. 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; 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 { enum: UnsignedInt {
/** /**
* Color shader output. @ref shaders-generic "Generic output", * 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() * @see @ref Flags, @ref flags()
*/ */
enum class Flag: UnsignedByte { enum class Flag: UnsignedShort {
/** /**
* Multiply ambient color with a texture. * Multiply ambient color with a texture.
* @see @ref setAmbientColor(), @ref bindAmbientTexture() * @see @ref setAmbientColor(), @ref bindAmbientTexture()
@ -271,7 +289,20 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* WebGL 1.0. * WebGL 1.0.
* @m_since{2019,10} * @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 #endif
}; };

14
src/Magnum/Shaders/Phong.vert

@ -113,6 +113,15 @@ in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor; out lowp vec4 interpolatedVertexColor;
#endif #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 #if LIGHT_COUNT
out mediump vec3 transformedNormal; out mediump vec3 transformedNormal;
#ifdef NORMAL_TEXTURE #ifdef NORMAL_TEXTURE
@ -160,4 +169,9 @@ void main() {
/* Vertex colors, if enabled */ /* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor; interpolatedVertexColor = vertexColor;
#endif #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}, {"vertex colors + textured", Flat2D::Flag::VertexColor|Flat2D::Flag::Textured},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
{"object ID", Flat2D::Flag::ObjectId}, {"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} {"object ID + alpha mask + textured", Flat2D::Flag::ObjectId|Flat2D::Flag::AlphaMask|Flat2D::Flag::Textured}
#endif #endif
}; };
@ -182,6 +183,23 @@ const struct {
Flat2D::Flag::Textured|Flat2D::Flag::AlphaMask, 1.0f} 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() { FlatGLTest::FlatGLTest() {
addInstancedTests<FlatGLTest>({ addInstancedTests<FlatGLTest>({
&FlatGLTest::construct<2>, &FlatGLTest::construct<2>,
@ -236,8 +254,9 @@ FlatGLTest::FlatGLTest() {
&FlatGLTest::renderAlphaTeardown); &FlatGLTest::renderAlphaTeardown);
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
addTests({&FlatGLTest::renderObjectId2D, addInstancedTests({&FlatGLTest::renderObjectId2D,
&FlatGLTest::renderObjectId3D}, &FlatGLTest::renderObjectId3D},
Containers::arraySize(RenderObjectIdData),
&FlatGLTest::renderObjectIdSetup, &FlatGLTest::renderObjectIdSetup,
&FlatGLTest::renderObjectIdTeardown); &FlatGLTest::renderObjectIdTeardown);
#endif #endif
@ -975,14 +994,23 @@ void FlatGLTest::renderObjectIdTeardown() {
} }
void FlatGLTest::renderObjectId2D() { void FlatGLTest::renderObjectId2D() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete); CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete);
GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(32)); 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) .setColor(0x9999ff_rgbf)
.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f})) .setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f}))
.setObjectId(47523) .setObjectId(data.uniformId)
.draw(circle); .draw(circle);
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
@ -1014,23 +1042,32 @@ void FlatGLTest::renderObjectId2D() {
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
/* Outside of the object, cleared to 27 */ /* Outside of the object, cleared to 27 */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27); CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27);
/* Inside of the object. Verify that it can hold 16 bits at least. */ /* Inside of the object */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 47523); CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], data.expected);
} }
void FlatGLTest::renderObjectId3D() { void FlatGLTest::renderObjectId3D() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete); CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete);
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); 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) .setColor(0x9999ff_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::rotationY(-15.0_degf)* Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf)) Matrix4::rotationX(15.0_degf))
.setObjectId(48526) .setObjectId(data.uniformId)
.draw(sphere); .draw(sphere);
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
@ -1065,8 +1102,8 @@ void FlatGLTest::renderObjectId3D() {
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
/* Outside of the object, cleared to 27 */ /* Outside of the object, cleared to 27 */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27); CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27);
/* Inside of the object. Verify that it can hold 16 bits at least. */ /* Inside of the object */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 48526); CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], data.expected);
} }
#endif #endif

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

@ -39,6 +39,9 @@ struct FlatTest: TestSuite::Tester {
void debugFlag(); void debugFlag();
void debugFlags(); void debugFlags();
#ifndef MAGNUM_TARGET_GLES2
void debugFlagsInstancedObjectId();
#endif
}; };
FlatTest::FlatTest() { FlatTest::FlatTest() {
@ -49,7 +52,11 @@ FlatTest::FlatTest() {
&FlatTest::constructCopy<3>, &FlatTest::constructCopy<3>,
&FlatTest::debugFlag, &FlatTest::debugFlag,
&FlatTest::debugFlags}); &FlatTest::debugFlags,
#ifndef MAGNUM_TARGET_GLES2
&FlatTest::debugFlagsInstancedObjectId
#endif
});
} }
template<UnsignedInt dimensions> void FlatTest::constructNoCreate() { 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"); 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) 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}, {"vertex colors + diffuse texture", Phong::Flag::VertexColor|Phong::Flag::DiffuseTexture, 1},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
{"object ID", Phong::Flag::ObjectId, 1}, {"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}, {"object ID + alpha mask + specular texture", Phong::Flag::ObjectId|Phong::Flag::AlphaMask|Phong::Flag::SpecularTexture, 1},
#endif #endif
{"five lights", {}, 5}, {"five lights", {}, 5},
@ -266,6 +267,23 @@ const struct {
0xffffffff_rgbaf, 0x9999ff00_rgbaf} 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() { PhongGLTest::PhongGLTest() {
addInstancedTests({&PhongGLTest::construct}, Containers::arraySize(ConstructData)); addInstancedTests({&PhongGLTest::construct}, Containers::arraySize(ConstructData));
@ -322,7 +340,8 @@ PhongGLTest::PhongGLTest() {
&PhongGLTest::renderAlphaTeardown); &PhongGLTest::renderAlphaTeardown);
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
addTests({&PhongGLTest::renderObjectId}, addInstancedTests({&PhongGLTest::renderObjectId},
Containers::arraySize(RenderObjectIdData),
&PhongGLTest::renderObjectIdSetup, &PhongGLTest::renderObjectIdSetup,
&PhongGLTest::renderObjectIdTeardown); &PhongGLTest::renderObjectIdTeardown);
#endif #endif
@ -1158,11 +1177,20 @@ void PhongGLTest::renderObjectIdTeardown() {
} }
void PhongGLTest::renderObjectId() { void PhongGLTest::renderObjectId() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete); CORRADE_COMPARE(_framebuffer.checkStatus(GL::FramebufferTarget::Draw), GL::Framebuffer::Status::Complete);
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); 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}) .setLightColors({0x993366_rgbf, 0x669933_rgbf})
.setLightPositions({{-3.0f, -3.0f, 0.0f}, .setLightPositions({{-3.0f, -3.0f, 0.0f},
{ 3.0f, -3.0f, 0.0f}}) { 3.0f, -3.0f, 0.0f}})
@ -1171,7 +1199,7 @@ void PhongGLTest::renderObjectId() {
.setSpecularColor(0x6666ff_rgbf) .setSpecularColor(0x6666ff_rgbf)
.setTransformationMatrix(Matrix4::translation(Vector3::zAxis(-2.15f))) .setTransformationMatrix(Matrix4::translation(Vector3::zAxis(-2.15f)))
.setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)) .setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f))
.setObjectId(48526) .setObjectId(data.uniformId)
.draw(sphere); .draw(sphere);
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
@ -1205,8 +1233,8 @@ void PhongGLTest::renderObjectId() {
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
/* Outside of the object, cleared to 27 */ /* Outside of the object, cleared to 27 */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27); CORRADE_COMPARE(image.pixels<UnsignedInt>()[10][10], 27);
/* Inside of the object. Verify that it can hold 16 bits at least. */ /* Inside of the object */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 48526); CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], data.expected);
} }
#endif #endif

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

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

Loading…
Cancel
Save