Browse Source

Shaders: support object ID textures in the PhongGL shader.

pull/547/head
Vladimír Vondruš 4 years ago
parent
commit
229641d2ac
  1. 4
      doc/changelog.dox
  2. 2
      src/Magnum/Shaders/FlatGL.cpp
  3. 18
      src/Magnum/Shaders/Phong.frag
  4. 6
      src/Magnum/Shaders/Phong.h
  5. 69
      src/Magnum/Shaders/PhongGL.cpp
  6. 79
      src/Magnum/Shaders/PhongGL.h
  7. 302
      src/Magnum/Shaders/Test/PhongGLTest.cpp
  8. 12
      src/Magnum/Shaders/Test/PhongGL_Test.cpp

4
doc/changelog.dox

@ -205,8 +205,8 @@ See also:
updated with an introduction the new features. updated with an introduction the new features.
- @ref Shaders::FlatGL and @ref Shaders::PhongGL now support texture arrays, - @ref Shaders::FlatGL and @ref Shaders::PhongGL now support texture arrays,
available also in multi-draw and instanced scenarios available also in multi-draw and instanced scenarios
- @ref Shaders::FlatGL now supports object ID textures in addition to uniform - @ref Shaders::FlatGL and @ref Shaders::PhongGL now support object ID
and per-vertex object ID textures in addition to uniform and per-vertex object ID
- Added @ref Shaders::PhongGL::setNormalTextureScale(), consuming the - Added @ref Shaders::PhongGL::setNormalTextureScale(), consuming the
recently added @ref Trade::MaterialAttribute::NormalTextureScale material recently added @ref Trade::MaterialAttribute::NormalTextureScale material
attribute attribute

2
src/Magnum/Shaders/FlatGL.cpp

@ -52,7 +52,7 @@ namespace {
enum: Int { enum: Int {
TextureUnit = 0, TextureUnit = 0,
/* 1/2/3 taken by Phong (D/S/N), 4 by MeshVisualizer colormap */ /* 1/2/3 taken by Phong (D/S/N), 4 by MeshVisualizer colormap */
ObjectIdTextureUnit = 5 ObjectIdTextureUnit = 5 /* shared with Phong */
}; };
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2

18
src/Magnum/Shaders/Phong.frag

@ -293,6 +293,19 @@ uniform lowp
#endif #endif
#endif #endif
#ifdef OBJECT_ID_TEXTURE
#ifdef EXPLICIT_BINDING
layout(binding = 5)
#endif
uniform lowp
#ifndef TEXTURE_ARRAYS
usampler2D
#else
usampler2DArray
#endif
objectIdTextureData;
#endif
/* Inputs */ /* Inputs */
#if LIGHT_COUNT #if LIGHT_COUNT
@ -308,7 +321,7 @@ in mediump vec3 transformedBitangent;
in highp vec3 transformedPosition; in highp vec3 transformedPosition;
#endif #endif
#if defined(AMBIENT_TEXTURE) || defined(DIFFUSE_TEXTURE) || defined(SPECULAR_TEXTURE) || defined(NORMAL_TEXTURE) #if defined(AMBIENT_TEXTURE) || defined(DIFFUSE_TEXTURE) || defined(SPECULAR_TEXTURE) || defined(NORMAL_TEXTURE) || defined(OBJECT_ID_TEXTURE)
in mediump in mediump
#ifndef TEXTURE_ARRAYS #ifndef TEXTURE_ARRAYS
vec2 vec2
@ -524,6 +537,9 @@ void main() {
#ifdef INSTANCED_OBJECT_ID #ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId + interpolatedInstanceObjectId +
#endif #endif
#ifdef OBJECT_ID_TEXTURE
texture(objectIdTextureData, interpolatedTextureCoordinates).r +
#endif
objectId; objectId;
#endif #endif
} }

6
src/Magnum/Shaders/Phong.h

@ -176,8 +176,10 @@ struct PhongDrawUniform {
* is @cpp 0 @ce. * is @cpp 0 @ce.
* *
* Used only if @ref PhongGL::Flag::ObjectId is enabled, ignored otherwise. * Used only if @ref PhongGL::Flag::ObjectId is enabled, ignored otherwise.
* If @ref PhongGL::Flag::InstancedObjectId is enabled as well, this value * If @ref PhongGL::Flag::InstancedObjectId and/or
* is added to the ID coming from the @ref PhongGL::ObjectId attribute. * @ref PhongGL::Flag::ObjectIdTexture is enabled as well, this value is
* added to the ID coming from the @ref PhongGL::ObjectId attribute and/or
* the texture.
* @see @ref PhongGL::setObjectId() * @see @ref PhongGL::setObjectId()
*/ */
UnsignedInt objectId; UnsignedInt objectId;

69
src/Magnum/Shaders/PhongGL.cpp

@ -57,7 +57,9 @@ namespace {
AmbientTextureUnit = 0, AmbientTextureUnit = 0,
DiffuseTextureUnit = 1, DiffuseTextureUnit = 1,
SpecularTextureUnit = 2, SpecularTextureUnit = 2,
NormalTextureUnit = 3 NormalTextureUnit = 3,
/* 4 taken by MeshVisualizer colormap */
ObjectIdTextureUnit = 5 /* shared with Flat */
}; };
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -87,8 +89,15 @@ PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount
_lightSpecularColorsUniform{_lightPositionsUniform + 2*Int(lightCount)}, _lightSpecularColorsUniform{_lightPositionsUniform + 2*Int(lightCount)},
_lightRangesUniform{_lightPositionsUniform + 3*Int(lightCount)} _lightRangesUniform{_lightPositionsUniform + 3*Int(lightCount)}
{ {
CORRADE_ASSERT(!(flags & Flag::TextureTransformation) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)), {
"Shaders::PhongGL: texture transformation enabled but the shader is not textured", ); const bool textureTransformationNotEnabledOrTextured = !(flags & Flag::TextureTransformation) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture))
#ifndef MAGNUM_TARGET_GLES2
|| flags >= Flag::ObjectIdTexture
#endif
;
CORRADE_ASSERT(textureTransformationNotEnabledOrTextured,
"Shaders::PhongGL: texture transformation enabled but the shader is not textured", );
}
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags >= Flag::InstancedObjectId) || !(flags & Flag::Bitangent), CORRADE_ASSERT(!(flags >= Flag::InstancedObjectId) || !(flags & Flag::Bitangent),
@ -103,7 +112,7 @@ PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount
#endif #endif
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags & Flag::TextureArrays) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)), CORRADE_ASSERT(!(flags & Flag::TextureArrays) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)) || flags >= Flag::ObjectIdTexture,
"Shaders::PhongGL: texture arrays enabled but the shader is not textured", ); "Shaders::PhongGL: texture arrays enabled but the shader is not textured", );
CORRADE_ASSERT(!(flags & Flag::UniformBuffers) || !(flags & Flag::TextureArrays) || flags >= (Flag::TextureArrays|Flag::TextureTransformation), CORRADE_ASSERT(!(flags & Flag::UniformBuffers) || !(flags & Flag::TextureArrays) || flags >= (Flag::TextureArrays|Flag::TextureTransformation),
"Shaders::PhongGL: texture arrays require texture transformation enabled as well if uniform buffers are used", ); "Shaders::PhongGL: texture arrays require texture transformation enabled as well if uniform buffers are used", );
@ -206,7 +215,11 @@ PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount
} }
#endif #endif
vert.addSource(flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture) ? "#define TEXTURED\n" : "") vert.addSource((flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)
#ifndef MAGNUM_TARGET_GLES2
|| flags >= Flag::ObjectIdTexture
#endif
) ? "#define TEXTURED\n" : "")
.addSource(flags & Flag::NormalTexture ? "#define NORMAL_TEXTURE\n" : "") .addSource(flags & Flag::NormalTexture ? "#define NORMAL_TEXTURE\n" : "")
.addSource(flags & Flag::Bitangent ? "#define BITANGENT\n" : "") .addSource(flags & Flag::Bitangent ? "#define BITANGENT\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "") .addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
@ -245,6 +258,7 @@ PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount
#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" : "") .addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(flags >= Flag::ObjectIdTexture ? "#define OBJECT_ID_TEXTURE\n" : "")
#endif #endif
.addSource(flags & Flag::NoSpecular ? "#define NO_SPECULAR\n" : "") .addSource(flags & Flag::NoSpecular ? "#define NO_SPECULAR\n" : "")
; ;
@ -301,7 +315,11 @@ PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount
} }
if(flags & Flag::VertexColor) if(flags & Flag::VertexColor)
bindAttributeLocation(Color3::Location, "vertexColor"); /* Color4 is the same */ bindAttributeLocation(Color3::Location, "vertexColor"); /* Color4 is the same */
if(flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture)) if(flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture)
#ifndef MAGNUM_TARGET_GLES2
|| flags >= Flag::ObjectIdTexture
#endif
)
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(flags & Flag::ObjectId) { if(flags & Flag::ObjectId) {
@ -372,6 +390,7 @@ PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount
if(flags & Flag::NormalTexture) setUniform(uniformLocation("normalTexture"), NormalTextureUnit); if(flags & Flag::NormalTexture) setUniform(uniformLocation("normalTexture"), NormalTextureUnit);
} }
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::ObjectIdTexture) setUniform(uniformLocation("objectIdTextureData"), ObjectIdTextureUnit);
if(flags >= Flag::UniformBuffers) { if(flags >= Flag::UniformBuffers) {
setUniformBlockBinding(uniformBlockIndex("Projection"), ProjectionBufferBinding); setUniformBlockBinding(uniformBlockIndex("Projection"), ProjectionBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Transformation"), TransformationBufferBinding); setUniformBlockBinding(uniformBlockIndex("Transformation"), TransformationBufferBinding);
@ -901,6 +920,28 @@ PhongGL& PhongGL::bindNormalTexture(GL::Texture2DArray& texture) {
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES2
PhongGL& PhongGL::bindObjectIdTexture(GL::Texture2D& texture) {
CORRADE_ASSERT(_flags >= Flag::ObjectIdTexture,
"Shaders::PhongGL::bindObjectIdTexture(): the shader was not created with object ID texture enabled", *this);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags & Flag::TextureArrays),
"Shaders::PhongGL::bindObjectIdTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead", *this);
#endif
texture.bind(ObjectIdTextureUnit);
return *this;
}
PhongGL& PhongGL::bindObjectIdTexture(GL::Texture2DArray& texture) {
CORRADE_ASSERT(_flags >= Flag::ObjectIdTexture,
"Shaders::PhongGL::bindObjectIdTexture(): the shader was not created with object ID texture enabled", *this);
CORRADE_ASSERT(_flags & Flag::TextureArrays,
"Shaders::PhongGL::bindObjectIdTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead", *this);
texture.bind(ObjectIdTextureUnit);
return *this;
}
#endif
PhongGL& PhongGL::bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal) { PhongGL& PhongGL::bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal) {
CORRADE_ASSERT(_flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture), CORRADE_ASSERT(_flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture),
"Shaders::PhongGL::bindTextures(): the shader was not created with any textures enabled", *this); "Shaders::PhongGL::bindTextures(): the shader was not created with any textures enabled", *this);
@ -913,6 +954,14 @@ PhongGL& PhongGL::bindTextures(GL::Texture2D* ambient, GL::Texture2D* diffuse, G
} }
Debug& operator<<(Debug& debug, const PhongGL::Flag value) { Debug& operator<<(Debug& debug, const PhongGL::Flag value) {
#ifndef MAGNUM_TARGET_GLES2
/* Special case coming from the Flags printer. As both flags are a superset
of ObjectId, printing just one would result in
`Flag::InstancedObjectId|Flag(0x20000)` in the output. */
if(value == PhongGL::Flag(UnsignedInt(PhongGL::Flag::InstancedObjectId|PhongGL::Flag::ObjectIdTexture)))
return debug << PhongGL::Flag::InstancedObjectId << Debug::nospace << "|" << Debug::nospace << PhongGL::Flag::ObjectIdTexture;
#endif
debug << "Shaders::PhongGL::Flag" << Debug::nospace; debug << "Shaders::PhongGL::Flag" << Debug::nospace;
switch(value) { switch(value) {
@ -927,8 +976,9 @@ Debug& operator<<(Debug& debug, const PhongGL::Flag value) {
_c(VertexColor) _c(VertexColor)
_c(TextureTransformation) _c(TextureTransformation)
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
_c(InstancedObjectId)
_c(ObjectId) _c(ObjectId)
_c(InstancedObjectId)
_c(ObjectIdTexture)
#endif #endif
_c(InstancedTransformation) _c(InstancedTransformation)
_c(InstancedTextureOffset) _c(InstancedTextureOffset)
@ -958,7 +1008,12 @@ Debug& operator<<(Debug& debug, const PhongGL::Flags value) {
PhongGL::Flag::InstancedTextureOffset, /* Superset of TextureTransformation */ PhongGL::Flag::InstancedTextureOffset, /* Superset of TextureTransformation */
PhongGL::Flag::TextureTransformation, PhongGL::Flag::TextureTransformation,
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/* Both are a superset of ObjectId, meaning printing just one would
result in `Flag::InstancedObjectId|Flag(0x20000)` in the output. So
we pass both and let the Flag printer deal with that. */
PhongGL::Flag(UnsignedInt(PhongGL::Flag::InstancedObjectId|PhongGL::Flag::ObjectIdTexture)),
PhongGL::Flag::InstancedObjectId, /* Superset of ObjectId */ PhongGL::Flag::InstancedObjectId, /* Superset of ObjectId */
PhongGL::Flag::ObjectIdTexture, /* Superset of ObjectId */
PhongGL::Flag::ObjectId, PhongGL::Flag::ObjectId,
#endif #endif
PhongGL::Flag::InstancedTransformation, PhongGL::Flag::InstancedTransformation,

79
src/Magnum/Shaders/PhongGL.h

@ -214,8 +214,10 @@ 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. If you have a integer buffer attached to the @ref ObjectIdOutput attachment. If you have a
batch of meshes with different object IDs, enable @ref Flag::InstancedObjectId batch of meshes with different object IDs, enable @ref Flag::InstancedObjectId
and supply per-vertex IDs to the @ref ObjectId attribute. The output will and supply per-vertex IDs to the @ref ObjectId attribute. The object ID can be
contain a sum of the per-vertex ID and ID coming from @ref setObjectId(). also supplied from an integer texture bound via @ref bindObjectIdTexture() if
@ref Flag::ObjectIdTexture is enabled. The output will contain a sum of the
per-vertex ID, texture ID and ID coming from @ref setObjectId().
The functionality is practically the same as in the @ref FlatGL shader, see The functionality is practically the same as in the @ref FlatGL shader, see
@ref Shaders-FlatGL-object-id "its documentation" for more information and usage @ref Shaders-FlatGL-object-id "its documentation" for more information and usage
@ -472,8 +474,9 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
* Object ID shader output. @ref shaders-generic "Generic output", * Object ID shader output. @ref shaders-generic "Generic output",
* present only if @ref Flag::ObjectId is set. Expects a * present only if @ref Flag::ObjectId is set. Expects a
* single-component unsigned integral attachment. Writes the value * single-component unsigned integral attachment. Writes the value
* set in @ref setObjectId() there, see * set in @ref setObjectId() and possibly also a per-vertex ID and
* @ref Shaders-PhongGL-object-id for more information. * an ID fetched from a texture, see @ref Shaders-PhongGL-object-id
* for more information.
* @requires_gl30 Extension @gl_extension{EXT,texture_integer} * @requires_gl30 Extension @gl_extension{EXT,texture_integer}
* @requires_gles30 Object ID output requires integer support in * @requires_gles30 Object ID output requires integer support in
* shaders, which is not available in OpenGL ES 2.0. * shaders, which is not available in OpenGL ES 2.0.
@ -585,6 +588,23 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
* @m_since{2020,06} * @m_since{2020,06}
*/ */
InstancedObjectId = (1 << 8)|ObjectId, InstancedObjectId = (1 << 8)|ObjectId,
/**
* Object ID texture. Retrieves object IDs from a texture bound
* with @ref bindObjectIdTexture(), outputting a sum of the object
* ID texture, the ID coming from @ref setObjectId() or
* @ref PhongDrawUniform::objectId and possibly also the per-vertex
* ID, if @ref Flag::InstancedObjectId is enabled as well.
* Implicitly enables @ref Flag::ObjectId. See
* @ref Shaders-PhongGL-object-id for more information.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID output requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID output requires integer support in
* shaders, which is not available in WebGL 1.0.
* @m_since_latest
*/
ObjectIdTexture = (1 << 17)|ObjectId,
#endif #endif
/** /**
@ -976,8 +996,10 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
* 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-PhongGL-object-id for more information. Default is * @ref Shaders-PhongGL-object-id for more information. Default is
* @cpp 0 @ce. If @ref Flag::InstancedObjectId is enabled as well, this * @cpp 0 @ce. If @ref Flag::InstancedObjectId and/or
* value is added to the ID coming from the @ref ObjectId attribute. * @ref Flag::ObjectIdTexture is enabled as well, this value is added
* to the ID coming from the @ref ObjectId attribute and/or the
* texture.
* *
* Expects that @ref Flag::UniformBuffers is not set, in that case fill * Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref PhongDrawUniform::objectId and call @ref bindDrawBuffer() * @ref PhongDrawUniform::objectId and call @ref bindDrawBuffer()
@ -1617,6 +1639,51 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
PhongGL& bindNormalTexture(GL::Texture2DArray& texture); PhongGL& bindNormalTexture(GL::Texture2DArray& texture);
#endif #endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Bind an object ID texture
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that the shader was created with @ref Flag::ObjectIdTexture
* enabled. If @ref Flag::TextureArrays is enabled as well, use
* @ref bindObjectIdTexture(GL::Texture2DArray&) instead. The texture
* needs to have an unsigned integer format.
* @see @ref setObjectId(), @ref Flag::TextureTransformation,
* @ref setTextureMatrix()
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID output requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID output requires integer support in
* shaders, which is not available in WebGL 1.0.
*/
PhongGL& bindObjectIdTexture(GL::Texture2D& texture);
/**
* @brief Bind an object ID array texture
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that the shader was created with both
* @ref Flag::ObjectIdTexture and @ref Flag::TextureArrays enabled. If
* @ref Flag::UniformBuffers is not enabled, the layer is set via
* @ref setTextureLayer(); if @ref Flag::UniformBuffers is enabled,
* @ref Flag::TextureTransformation has to be enabled as well and the
* layer is set via @ref TextureTransformationUniform::layer.
* @see @ref setObjectId(), @ref Flag::TextureTransformation,
* @ref setTextureLayer()
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4} and
* @gl_extension{EXT,texture_array}
* @requires_gles30 Object ID output requires integer support in
* shaders, which is not available in OpenGL ES 2.0. Texture
* arrays are not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID output requires integer support in
* shaders, which is not available in WebGL 1.0. Texture arrays
* are not available in WebGL 1.0.
*/
PhongGL& bindObjectIdTexture(GL::Texture2DArray& texture);
#endif
/** /**
* @brief Bind textures * @brief Bind textures
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)

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

@ -235,6 +235,10 @@ constexpr struct {
{"object ID + separate bitangent", PhongGL::Flag::ObjectId|PhongGL::Flag::Bitangent, 1}, {"object ID + separate bitangent", PhongGL::Flag::ObjectId|PhongGL::Flag::Bitangent, 1},
{"instanced object ID", PhongGL::Flag::InstancedObjectId, 1}, {"instanced object ID", PhongGL::Flag::InstancedObjectId, 1},
{"object ID + alpha mask + specular texture", PhongGL::Flag::ObjectId|PhongGL::Flag::AlphaMask|PhongGL::Flag::SpecularTexture, 1}, {"object ID + alpha mask + specular texture", PhongGL::Flag::ObjectId|PhongGL::Flag::AlphaMask|PhongGL::Flag::SpecularTexture, 1},
{"object ID texture", PhongGL::Flag::ObjectIdTexture, 1},
{"instanced object ID texture array + texture transformation", PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::InstancedObjectId|PhongGL::Flag::TextureArrays|PhongGL::Flag::TextureTransformation, 1},
{"object ID texture + diffuse texture", PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::DiffuseTexture, 1},
{"object ID texture, zero lights", PhongGL::Flag::ObjectIdTexture, 0},
#endif #endif
{"no specular", PhongGL::Flag::NoSpecular, 1}, {"no specular", PhongGL::Flag::NoSpecular, 1},
{"five lights", {}, 5}, {"five lights", {}, 5},
@ -269,6 +273,9 @@ constexpr struct {
{"normal texture + separate bitangents", PhongGL::Flag::UniformBuffers|PhongGL::Flag::NormalTexture|PhongGL::Flag::Bitangent, 1, 1, 1}, {"normal texture + separate bitangents", PhongGL::Flag::UniformBuffers|PhongGL::Flag::NormalTexture|PhongGL::Flag::Bitangent, 1, 1, 1},
{"alpha mask", PhongGL::Flag::UniformBuffers|PhongGL::Flag::AlphaMask, 1, 1, 1}, {"alpha mask", PhongGL::Flag::UniformBuffers|PhongGL::Flag::AlphaMask, 1, 1, 1},
{"object ID", PhongGL::Flag::UniformBuffers|PhongGL::Flag::ObjectId, 1, 1, 1}, {"object ID", PhongGL::Flag::UniformBuffers|PhongGL::Flag::ObjectId, 1, 1, 1},
{"object ID texture", PhongGL::Flag::ObjectIdTexture, 1, 1, 1},
{"instanced object ID texture array + texture transformation", PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::InstancedObjectId|PhongGL::Flag::TextureArrays|PhongGL::Flag::TextureTransformation, 1, 1, 1},
{"object ID texture + diffuse texture", PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::DiffuseTexture, 1, 1, 1},
{"no specular", PhongGL::Flag::UniformBuffers|PhongGL::Flag::NoSpecular, 1, 1, 1}, {"no specular", PhongGL::Flag::UniformBuffers|PhongGL::Flag::NoSpecular, 1, 1, 1},
{"multidraw with all the things", PhongGL::Flag::MultiDraw|PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::AmbientTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture|PhongGL::Flag::TextureArrays|PhongGL::Flag::AlphaMask|PhongGL::Flag::ObjectId|PhongGL::Flag::InstancedTextureOffset|PhongGL::Flag::InstancedTransformation|PhongGL::Flag::InstancedObjectId|PhongGL::Flag::LightCulling, 8, 16, 24} {"multidraw with all the things", PhongGL::Flag::MultiDraw|PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::AmbientTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture|PhongGL::Flag::TextureArrays|PhongGL::Flag::AlphaMask|PhongGL::Flag::ObjectId|PhongGL::Flag::InstancedTextureOffset|PhongGL::Flag::InstancedTransformation|PhongGL::Flag::InstancedObjectId|PhongGL::Flag::LightCulling, 8, 16, 24}
}; };
@ -280,10 +287,19 @@ constexpr struct {
const char* message; const char* message;
} ConstructInvalidData[] { } ConstructInvalidData[] {
{"texture transformation but not textured", {"texture transformation but not textured",
PhongGL::Flag::TextureTransformation, /* ObjectId shares bits with ObjectIdTexture but should still trigger
the assert */
PhongGL::Flag::TextureTransformation
#ifndef MAGNUM_TARGET_GLES2
|PhongGL::Flag::ObjectId
#endif
,
"texture transformation enabled but the shader is not textured"}, "texture transformation enabled but the shader is not textured"},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
{"texture arrays but not textured", PhongGL::Flag::TextureArrays, {"texture arrays but not textured",
/* ObjectId shares bits with ObjectIdTexture but should still trigger
the assert */
PhongGL::Flag::TextureArrays|PhongGL::Flag::ObjectId,
"texture arrays enabled but the shader is not textured"}, "texture arrays enabled but the shader is not textured"},
{"conflicting bitangent and instanced object id attribute", {"conflicting bitangent and instanced object id attribute",
PhongGL::Flag::Bitangent|PhongGL::Flag::InstancedObjectId, PhongGL::Flag::Bitangent|PhongGL::Flag::InstancedObjectId,
@ -317,18 +333,29 @@ constexpr struct {
PhongGL::Flags flags; PhongGL::Flags flags;
const char* message; const char* message;
} BindTexturesInvalidData[]{ } BindTexturesInvalidData[]{
{"not textured", {}, {"not textured",
PhongGL::Flags{}
#ifndef MAGNUM_TARGET_GLES2
/* ObjectId shares bits with ObjectIdTexture but should still
trigger the assert */
|PhongGL::Flag::ObjectId
#endif
,
"Shaders::PhongGL::bindAmbientTexture(): the shader was not created with ambient texture enabled\n" "Shaders::PhongGL::bindAmbientTexture(): the shader was not created with ambient texture enabled\n"
"Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with diffuse texture enabled\n" "Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with diffuse texture enabled\n"
"Shaders::PhongGL::bindSpecularTexture(): the shader was not created with specular texture enabled\n" "Shaders::PhongGL::bindSpecularTexture(): the shader was not created with specular texture enabled\n"
"Shaders::PhongGL::bindNormalTexture(): the shader was not created with normal texture enabled\n" "Shaders::PhongGL::bindNormalTexture(): the shader was not created with normal texture enabled\n"
#ifndef MAGNUM_TARGET_GLES2
"Shaders::PhongGL::bindObjectIdTexture(): the shader was not created with object ID texture enabled\n"
#endif
"Shaders::PhongGL::bindTextures(): the shader was not created with any textures enabled\n"}, "Shaders::PhongGL::bindTextures(): the shader was not created with any textures enabled\n"},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
{"array", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture|PhongGL::Flag::TextureArrays, {"array", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture|PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureArrays,
"Shaders::PhongGL::bindAmbientTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n" "Shaders::PhongGL::bindAmbientTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"
"Shaders::PhongGL::bindDiffuseTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n" "Shaders::PhongGL::bindDiffuseTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"
"Shaders::PhongGL::bindSpecularTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n" "Shaders::PhongGL::bindSpecularTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"
"Shaders::PhongGL::bindNormalTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n" "Shaders::PhongGL::bindNormalTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"
"Shaders::PhongGL::bindObjectIdTexture(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"
"Shaders::PhongGL::bindTextures(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"} "Shaders::PhongGL::bindTextures(): the shader was created with texture arrays enabled, use a Texture2DArray instead\n"}
#endif #endif
}; };
@ -339,16 +366,22 @@ constexpr struct {
PhongGL::Flags flags; PhongGL::Flags flags;
const char* message; const char* message;
} BindTextureArraysInvalidData[]{ } BindTextureArraysInvalidData[]{
{"not textured", {}, {"not textured",
/* ObjectId shares bits with ObjectIdTexture but should still trigger
the assert */
PhongGL::Flag::ObjectId,
"Shaders::PhongGL::bindAmbientTexture(): the shader was not created with ambient texture enabled\n" "Shaders::PhongGL::bindAmbientTexture(): the shader was not created with ambient texture enabled\n"
"Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with diffuse texture enabled\n" "Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with diffuse texture enabled\n"
"Shaders::PhongGL::bindSpecularTexture(): the shader was not created with specular texture enabled\n" "Shaders::PhongGL::bindSpecularTexture(): the shader was not created with specular texture enabled\n"
"Shaders::PhongGL::bindNormalTexture(): the shader was not created with normal texture enabled\n"}, "Shaders::PhongGL::bindNormalTexture(): the shader was not created with normal texture enabled\n"
{"not array", PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture, "Shaders::PhongGL::bindObjectIdTexture(): the shader was not created with object ID texture enabled\n"},
{"not array",
PhongGL::Flag::AmbientTexture|PhongGL::Flag::DiffuseTexture|PhongGL::Flag::SpecularTexture|PhongGL::Flag::NormalTexture|PhongGL::Flag::ObjectIdTexture,
"Shaders::PhongGL::bindAmbientTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n" "Shaders::PhongGL::bindAmbientTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n"
"Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n" "Shaders::PhongGL::bindDiffuseTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n"
"Shaders::PhongGL::bindSpecularTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n" "Shaders::PhongGL::bindSpecularTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n"
"Shaders::PhongGL::bindNormalTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n"} "Shaders::PhongGL::bindNormalTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n"
"Shaders::PhongGL::bindObjectIdTexture(): the shader was not created with texture arrays enabled, use a Texture2D instead\n"}
}; };
#endif #endif
@ -662,6 +695,39 @@ const struct {
1.0f, 0.0f, {}} 1.0f, 0.0f, {}}
}; };
#ifndef MAGNUM_TARGET_GLES2
const struct {
const char* name;
UnsignedInt expected[4];
PhongGL::Flags flags;
Matrix3 textureTransformation;
Int layer;
} RenderObjectIdData[]{
{"",
{40006, 40006, 40006, 40006},
{}, {}, 0},
{"textured",
{40106, 40206, 40306, 40406},
PhongGL::Flag::ObjectIdTexture, {}, 0},
{"textured, texture transformation",
{40406, 40306, 40206, 40106},
PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureTransformation,
Matrix3::translation(Vector2{1.0f})*Matrix3::scaling(Vector2{-1.0f}), 0},
{"texture array, first layer",
{40106, 40206, 40306, 40406},
PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureArrays,
{}, 0},
{"texture array, arbitrary layer",
{40106, 40206, 40306, 40406},
PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureArrays,
{}, 6},
{"texture array, texture transformation, arbitrary layer",
{40406, 40306, 40206, 40106},
PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureTransformation|PhongGL::Flag::TextureArrays,
Matrix3::translation(Vector2{1.0f})*Matrix3::scaling(Vector2{-1.0f}), 6},
};
#endif
constexpr struct { constexpr struct {
const char* name; const char* name;
const char* expected; const char* expected;
@ -685,6 +751,21 @@ constexpr struct {
PhongGL::Flag::InstancedObjectId, PhongGL::Flag::InstancedObjectId,
/* Minor differences on SwiftShader */ /* Minor differences on SwiftShader */
81.0f, 0.06f}, 81.0f, 0.06f},
{"diffuse color + textured object ID",
"instanced.tga", {3000, 4000, 5000},
PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::InstancedTextureOffset,
/* Minor differences on SwiftShader */
81.0f, 0.06f},
{"diffuse color + instanced textured object ID",
"instanced.tga", {3211, 8627, 40363},
PhongGL::Flag::InstancedObjectId|PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::InstancedTextureOffset,
/* Minor differences on SwiftShader */
81.0f, 0.06f},
{"diffuse color + instanced texture array object ID",
"instanced.tga", {3211, 8627, 40363},
PhongGL::Flag::InstancedObjectId|PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::InstancedTextureOffset|PhongGL::Flag::TextureArrays,
/* Minor differences on SwiftShader */
81.0f, 0.06f},
#endif #endif
{"diffuse texture", {"diffuse texture",
"instanced-textured.tga", {}, "instanced-textured.tga", {},
@ -725,6 +806,18 @@ constexpr struct {
2, 1, 1, 16, 2, 1, 1, 16,
/* Minor differences on ARM Mali */ /* Minor differences on ARM Mali */
3.34f, 0.01f}, 3.34f, 0.01f},
{"bind with offset, colored + textured object ID",
"multidraw.tga", {3211, 8627, 40363},
PhongGL::Flag::TextureTransformation|PhongGL::Flag::ObjectIdTexture,
2, 1, 1, 16,
/* Minor differences on ARM Mali */
3.34f, 0.01f},
{"bind with offset, colored + textured array object ID",
"multidraw.tga", {3211, 8627, 40363},
PhongGL::Flag::TextureTransformation|PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureArrays,
2, 1, 1, 16,
/* Minor differences on ARM Mali */
3.34f, 0.01f},
{"bind with offset, textured", {"bind with offset, textured",
"multidraw-textured.tga", {}, "multidraw-textured.tga", {},
PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture, PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture,
@ -750,6 +843,18 @@ constexpr struct {
4, 2, 3, 1, 4, 2, 3, 1,
/* Minor differences on ARM Mali */ /* Minor differences on ARM Mali */
3.34f, 0.01f}, 3.34f, 0.01f},
{"draw offset, colored + textured object ID",
"multidraw.tga", {3211, 8627, 40363},
PhongGL::Flag::TextureTransformation|PhongGL::Flag::ObjectIdTexture,
4, 2, 3, 1,
/* Minor differences on ARM Mali */
3.34f, 0.01f},
{"draw offset, colored + textured array object ID",
"multidraw.tga", {3211, 8627, 40363},
PhongGL::Flag::TextureTransformation|PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureArrays,
4, 2, 3, 1,
/* Minor differences on ARM Mali */
3.34f, 0.01f},
{"draw offset, textured", {"draw offset, textured",
"multidraw-textured.tga", {}, "multidraw-textured.tga", {},
PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture, PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture,
@ -775,6 +880,18 @@ constexpr struct {
4, 2, 3, 1, 4, 2, 3, 1,
/* Minor differences on ARM Mali */ /* Minor differences on ARM Mali */
3.34f, 0.01f}, 3.34f, 0.01f},
{"multidraw, colored + textured object ID",
"multidraw.tga", {3211, 8627, 40363},
PhongGL::Flag::MultiDraw|PhongGL::Flag::TextureTransformation|PhongGL::Flag::ObjectIdTexture,
4, 2, 3, 1,
/* Minor differences on ARM Mali */
3.34f, 0.01f},
{"multidraw, colored + textured array object ID",
"multidraw.tga", {3211, 8627, 40363},
PhongGL::Flag::MultiDraw|PhongGL::Flag::TextureTransformation|PhongGL::Flag::ObjectIdTexture|PhongGL::Flag::TextureArrays,
4, 2, 3, 1,
/* Minor differences on ARM Mali */
3.34f, 0.01f},
{"multidraw, textured", {"multidraw, textured",
"multidraw-textured.tga", {}, "multidraw-textured.tga", {},
PhongGL::Flag::MultiDraw|PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture, PhongGL::Flag::MultiDraw|PhongGL::Flag::TextureTransformation|PhongGL::Flag::DiffuseTexture,
@ -943,9 +1060,10 @@ PhongGLTest::PhongGLTest() {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/* MSVC needs explicit type due to default template args */ /* MSVC needs explicit type due to default template args */
addTests<PhongGLTest>({ addInstancedTests<PhongGLTest>({
&PhongGLTest::renderObjectId, &PhongGLTest::renderObjectId,
&PhongGLTest::renderObjectId<PhongGL::Flag::UniformBuffers>}, &PhongGLTest::renderObjectId<PhongGL::Flag::UniformBuffers>},
Containers::arraySize(RenderObjectIdData),
&PhongGLTest::renderObjectIdSetup, &PhongGLTest::renderObjectIdSetup,
&PhongGLTest::renderObjectIdTeardown); &PhongGLTest::renderObjectIdTeardown);
#endif #endif
@ -1314,6 +1432,9 @@ void PhongGLTest::bindTexturesInvalid() {
.bindDiffuseTexture(texture) .bindDiffuseTexture(texture)
.bindSpecularTexture(texture) .bindSpecularTexture(texture)
.bindNormalTexture(texture) .bindNormalTexture(texture)
#ifndef MAGNUM_TARGET_GLES2
.bindObjectIdTexture(texture)
#endif
.bindTextures(&texture, &texture, &texture, &texture); .bindTextures(&texture, &texture, &texture, &texture);
CORRADE_COMPARE(out.str(), data.message); CORRADE_COMPARE(out.str(), data.message);
@ -1341,7 +1462,11 @@ void PhongGLTest::bindTextureArraysInvalid() {
shader.bindAmbientTexture(textureArray) shader.bindAmbientTexture(textureArray)
.bindDiffuseTexture(textureArray) .bindDiffuseTexture(textureArray)
.bindSpecularTexture(textureArray) .bindSpecularTexture(textureArray)
.bindNormalTexture(textureArray); .bindNormalTexture(textureArray)
#ifndef MAGNUM_TARGET_GLES2
.bindObjectIdTexture(textureArray)
#endif
;
CORRADE_COMPARE(out.str(), data.message); CORRADE_COMPARE(out.str(), data.message);
} }
@ -2824,6 +2949,9 @@ void PhongGLTest::renderObjectIdTeardown() {
} }
template<PhongGL::Flag flag> void PhongGLTest::renderObjectId() { template<PhongGL::Flag flag> void PhongGLTest::renderObjectId() {
auto&& data = RenderObjectIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
if(flag == PhongGL::Flag::UniformBuffers) { if(flag == PhongGL::Flag::UniformBuffers) {
setTestCaseTemplateName("Flag::UniformBuffers"); setTestCaseTemplateName("Flag::UniformBuffers");
@ -2845,11 +2973,50 @@ template<PhongGL::Flag flag> void PhongGLTest::renderObjectId() {
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)); Primitives::UVSphereFlags sphereFlags;
if(data.flags & PhongGL::Flag::ObjectIdTexture)
sphereFlags |= Primitives::UVSphereFlag::TextureCoordinates;
GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32, sphereFlags));
PhongGL::Flags flags = data.flags|flag;
if(flag == PhongGL::Flag::UniformBuffers && (data.flags & PhongGL::Flag::TextureArrays) && !(data.flags & PhongGL::Flag::TextureTransformation)) {
CORRADE_INFO("Texture arrays currently require texture transformation if UBOs are used, enabling implicitly.");
flags |= PhongGL::Flag::TextureTransformation;
}
PhongGL shader{PhongGL::Flag::ObjectId|flags, 2};
PhongGL shader{PhongGL::Flag::ObjectId|flag, 2}; GL::Texture2D texture{NoCreate};
GL::Texture2DArray textureArray{NoCreate};
if(data.flags >= PhongGL::Flag::ObjectIdTexture) {
const UnsignedShort imageData[]{
100, 200, 300, 400
};
ImageView2D image{PixelFormat::R16UI, {2, 2}, imageData};
if(data.flags & PhongGL::Flag::TextureArrays) {
textureArray = GL::Texture2DArray{};
textureArray.setMinificationFilter(GL::SamplerFilter::Nearest)
.setMagnificationFilter(GL::SamplerFilter::Nearest)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, GL::TextureFormat::R16UI, {image.size(), data.layer + 1})
.setSubImage(0, {0, 0, data.layer}, image);
shader.bindObjectIdTexture(textureArray);
if(flag != PhongGL::Flag::UniformBuffers && data.layer != 0)
shader.setTextureLayer(data.layer); /* to verify the default */
} else {
texture = GL::Texture2D{};
texture.setMinificationFilter(GL::SamplerFilter::Nearest)
.setMagnificationFilter(GL::SamplerFilter::Nearest)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, GL::TextureFormat::R16UI, image.size())
.setSubImage(0, {}, image);
shader.bindObjectIdTexture(texture);
}
}
if(flag == PhongGL::Flag{}) { if(flag == PhongGL::Flag{}) {
if(data.textureTransformation != Matrix3{})
shader.setTextureMatrix(data.textureTransformation);
shader shader
.setLightColors({0x993366_rgbf, 0x669933_rgbf}) .setLightColors({0x993366_rgbf, 0x669933_rgbf})
.setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f},
@ -2859,7 +3026,7 @@ template<PhongGL::Flag flag> 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(40006)
.draw(sphere); .draw(sphere);
} else if(flag == PhongGL::Flag::UniformBuffers) { } else if(flag == PhongGL::Flag::UniformBuffers) {
GL::Buffer projectionUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer projectionUniform{GL::Buffer::TargetHint::Uniform, {
@ -2874,7 +3041,7 @@ template<PhongGL::Flag flag> void PhongGLTest::renderObjectId() {
}}; }};
GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, {
PhongDrawUniform{} PhongDrawUniform{}
.setObjectId(48526) .setObjectId(40006)
}}; }};
GL::Buffer lightUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer lightUniform{GL::Buffer::TargetHint::Uniform, {
PhongLightUniform{} PhongLightUniform{}
@ -2884,12 +3051,21 @@ template<PhongGL::Flag flag> void PhongGLTest::renderObjectId() {
.setPosition({3.0f, -3.0f, 2.0f, 0.0f}) .setPosition({3.0f, -3.0f, 2.0f, 0.0f})
.setColor(0x669933_rgbf) .setColor(0x669933_rgbf)
}}; }};
GL::Buffer textureTransformationUniform{GL::Buffer::TargetHint::Uniform, {
TextureTransformationUniform{}
.setTextureMatrix(data.textureTransformation)
.setLayer(data.layer)
}};
GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, { GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, {
PhongMaterialUniform{} PhongMaterialUniform{}
.setAmbientColor(0x330033_rgbf) .setAmbientColor(0x330033_rgbf)
.setDiffuseColor(0xccffcc_rgbf) .setDiffuseColor(0xccffcc_rgbf)
.setSpecularColor(0x6666ff_rgbf) .setSpecularColor(0x6666ff_rgbf)
}}; }};
/* Also take into account the case when texture transform needs to be
enabled for texture arrays, so not data.flags but flags */
if(flags & PhongGL::Flag::TextureTransformation)
shader.bindTextureTransformationBuffer(textureTransformationUniform);
shader.bindProjectionBuffer(projectionUniform) shader.bindProjectionBuffer(projectionUniform)
.bindTransformationBuffer(transformationUniform) .bindTransformationBuffer(transformationUniform)
.bindDrawBuffer(drawUniform) .bindDrawBuffer(drawUniform)
@ -2924,8 +3100,13 @@ template<PhongGL::Flag flag> 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 */ /* Inside of the object. It's a sphere and the seam is at the front,
CORRADE_COMPARE(image.pixels<UnsignedInt>()[40][46], 48526); rotated to bottom left, meaning left is actually the right part of the
texture and right is the left part of the texture. */
CORRADE_COMPARE(image.pixels<UnsignedInt>()[20][50], data.expected[0]);
CORRADE_COMPARE(image.pixels<UnsignedInt>()[20][20], data.expected[1]);
CORRADE_COMPARE(image.pixels<UnsignedInt>()[50][50], data.expected[2]);
CORRADE_COMPARE(image.pixels<UnsignedInt>()[50][20], data.expected[3]);
} }
#endif #endif
@ -3589,6 +3770,53 @@ template<PhongGL::Flag flag> void PhongGLTest::renderInstanced() {
shader.bindNormalTexture(normal); shader.bindNormalTexture(normal);
} }
} }
#ifndef MAGNUM_TARGET_GLES2
GL::Texture2D objectIdTexture{NoCreate};
GL::Texture2DArray objectIdTextureArray{NoCreate};
if(data.flags >= PhongGL::Flag::ObjectIdTexture) {
/* This should match transformation done for the diffuse/normal
texture */
if(data.flags & PhongGL::Flag::TextureArrays) {
/* 2 extra slices as a base offset, each slice has half height,
second slice has the data in the right half */
const UnsignedShort imageData[]{
0, 0,
0, 0,
2000, 0,
0, 3000,
4000, 0
};
ImageView3D image{PixelFormat::R16UI, {2, 1, 5}, imageData};
objectIdTextureArray = GL::Texture2DArray{};
objectIdTextureArray.setMinificationFilter(GL::SamplerFilter::Nearest)
.setMagnificationFilter(GL::SamplerFilter::Nearest)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, GL::TextureFormat::R16UI, image.size())
.setSubImage(0, {}, image);
shader.bindObjectIdTexture(objectIdTextureArray);
} else {
/* First is taken from bottom left, second from bottom right, third
from top center (there I just duplicate the pixel on both
sides) */
const UnsignedShort imageData[]{
2000, 3000,
4000, 4000
};
ImageView2D image{PixelFormat::R16UI, {2, 2}, imageData};
objectIdTexture = GL::Texture2D{};
objectIdTexture.setMinificationFilter(GL::SamplerFilter::Nearest)
.setMagnificationFilter(GL::SamplerFilter::Nearest)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, GL::TextureFormat::R16UI, image.size())
.setSubImage(0, {}, image);
shader.bindObjectIdTexture(objectIdTexture);
}
}
#endif
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},
@ -3823,6 +4051,48 @@ void PhongGLTest::renderMulti() {
} }
} }
GL::Texture2D objectIdTexture{NoCreate};
GL::Texture2DArray objectIdTextureArray{NoCreate};
if(data.flags >= PhongGL::Flag::ObjectIdTexture) {
/* This should match transformation done for the diffuse/normal
texture */
if(data.flags & PhongGL::Flag::TextureArrays) {
/* Each slice has half height, second slice has the data in the
right half */
const UnsignedShort imageData[]{
2000, 0,
0, 3000,
4000, 0
};
ImageView3D image{PixelFormat::R16UI, {2, 1, 3}, imageData};
objectIdTextureArray = GL::Texture2DArray{};
objectIdTextureArray.setMinificationFilter(GL::SamplerFilter::Nearest)
.setMagnificationFilter(GL::SamplerFilter::Nearest)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, GL::TextureFormat::R16UI, image.size())
.setSubImage(0, {}, image);
shader.bindObjectIdTexture(objectIdTextureArray);
} else {
/* First is taken from bottom left, second from bottom right, third
from top center (there I just duplicate the pixel on both
sides) */
const UnsignedShort imageData[]{
2000, 3000,
4000, 4000
};
ImageView2D image{PixelFormat::R16UI, {2, 2}, imageData};
objectIdTexture = GL::Texture2D{};
objectIdTexture.setMinificationFilter(GL::SamplerFilter::Nearest)
.setMagnificationFilter(GL::SamplerFilter::Nearest)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, GL::TextureFormat::R16UI, image.size())
.setSubImage(0, {}, image);
shader.bindObjectIdTexture(objectIdTexture);
}
}
Trade::MeshData sphereData = Primitives::uvSphereSolid(16, 32, Trade::MeshData sphereData = Primitives::uvSphereSolid(16, 32,
Primitives::UVSphereFlag::TextureCoordinates| Primitives::UVSphereFlag::TextureCoordinates|
Primitives::UVSphereFlag::Tangents); Primitives::UVSphereFlag::Tangents);

12
src/Magnum/Shaders/Test/PhongGL_Test.cpp

@ -85,12 +85,20 @@ void PhongGL_Test::debugFlags() {
void PhongGL_Test::debugFlagsSupersets() { void PhongGL_Test::debugFlagsSupersets() {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/* InstancedObjectId is a superset of ObjectId so only one should be /* InstancedObjectId and ObjectIdTexture are a superset of ObjectId so only
printed */ one should be printed, but if there are both then both should be */
{ {
std::ostringstream out; std::ostringstream out;
Debug{&out} << (PhongGL::Flag::ObjectId|PhongGL::Flag::InstancedObjectId); Debug{&out} << (PhongGL::Flag::ObjectId|PhongGL::Flag::InstancedObjectId);
CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::InstancedObjectId\n"); CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::InstancedObjectId\n");
} {
std::ostringstream out;
Debug{&out} << (PhongGL::Flag::ObjectId|PhongGL::Flag::ObjectIdTexture);
CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::ObjectIdTexture\n");
} {
std::ostringstream out;
Debug{&out} << (PhongGL::Flag::ObjectId|PhongGL::Flag::InstancedObjectId|PhongGL::Flag::ObjectIdTexture);
CORRADE_COMPARE(out.str(), "Shaders::PhongGL::Flag::InstancedObjectId|Shaders::PhongGL::Flag::ObjectIdTexture\n");
} }
#endif #endif

Loading…
Cancel
Save