Browse Source

Shaders: add missing MeshVisualizerGL*D::setObjectId().

Originally the uniform wasn't present with the assumption that users
could easily adjust color map offset to achieve the same effect. That
was however unnecessarily annoying and error-prone in cases where it's
essential to have the same object IDs from multiple draws have a
matching color, and it was complicating multidraw workflows as the color
map offset was not a part of per-draw data, but rather material data.
pull/547/head
Vladimír Vondruš 4 years ago
parent
commit
033e56ec23
  1. 10
      doc/changelog.dox
  2. 43
      src/Magnum/Shaders/MeshVisualizer.frag
  3. 7
      src/Magnum/Shaders/MeshVisualizer.geom
  4. 76
      src/Magnum/Shaders/MeshVisualizer.h
  5. 15
      src/Magnum/Shaders/MeshVisualizer.vert
  6. 70
      src/Magnum/Shaders/MeshVisualizerGL.cpp
  7. 130
      src/Magnum/Shaders/MeshVisualizerGL.h
  8. 4
      src/Magnum/Shaders/Test/CMakeLists.txt
  9. 224
      src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp
  10. 32
      src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp
  11. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid2D.tga
  12. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid3D.tga
  13. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid2D.tga
  14. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid3D.tga
  15. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid2D.tga
  16. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid3D.tga
  17. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid2D.tga
  18. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid3D.tga
  19. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid2D.tga
  20. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid3D.tga

10
doc/changelog.dox

@ -416,6 +416,16 @@ See also:
attributes and a @ref Shaders::PhongGL::Flag::Bitangent flag, implementing
support for both four-component tangents (used by glTF, for example) and
separate tangent and bitangent direction (used by Assimp).
- Added missing @ref Shaders::MeshVisualizerGL3D::setObjectId() "Shaders::MeshVisualizerGL*D::setObjectId()"
and a corresponding @ref Shaders::MeshVisualizerDrawUniform3D::objectId
"Shaders::MeshVisualizerDrawUniform*D::objectId"
member for UBO workflows. Originally the uniform wasn't present with the
assumption that users could easily adjust color map offset to achieve the
same effect. That was however unnecessarily annoying and error-prone in
cases where it's essential to have the same object IDs from multiple
draws have a matching color, and it was complicating multidraw workflows as
the color map offset was not a part of per-draw data, but rather material
data.
@subsubsection changelog-latest-changes-trade Trade library

43
src/Magnum/Shaders/MeshVisualizer.frag

@ -43,7 +43,7 @@
/* Uniforms */
#ifndef UNIFORM_BUFFERS
#if (defined(WIREFRAME_RENDERING) || defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)) && !defined(TBN_DIRECTION)
#if (defined(WIREFRAME_RENDERING) || defined(OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)) && !defined(TBN_DIRECTION)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 1)
#endif
@ -74,7 +74,7 @@ uniform lowp float wireframeWidth
;
#elif defined(TBN_DIRECTION)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 9)
layout(location = 10)
#endif
uniform lowp float lineWidth
#ifndef GL_ES
@ -94,7 +94,7 @@ uniform lowp float smoothness
;
#endif
#if defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 5)
#endif
@ -107,6 +107,14 @@ uniform lowp vec2 colorMapOffsetScale
#define colorMapScale colorMapOffsetScale.y
#endif
#ifdef OBJECT_ID
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6)
#endif
/* mediump is just 2^10, which might not be enough, this is 2^16 */
uniform highp uint objectId; /* defaults to zero */
#endif
/* Uniform buffers */
#else
@ -136,8 +144,9 @@ struct DrawUniform {
#elif !defined(TWO_DIMENSIONS)
#error
#endif
highp uvec4 materialIdReservedReservedReservedReserved;
#define draw_materialIdReserved materialIdReservedReservedReservedReserved.x
highp uvec4 materialIdReservedObjectIdReservedReserved;
#define draw_materialIdReserved materialIdReservedObjectIdReservedReserved.x
#define draw_objectId materialIdReservedObjectIdReservedReserved.y
};
layout(std140
@ -175,7 +184,7 @@ layout(std140
/* Textures */
#if defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#ifdef EXPLICIT_BINDING
layout(binding = 4)
#endif
@ -225,12 +234,15 @@ out lowp vec4 fragmentColor;
void main() {
#ifdef UNIFORM_BUFFERS
#ifdef OBJECT_ID
highp const uint objectId = draws[drawId].draw_objectId;
#endif
#if MATERIAL_COUNT > 1
mediump const uint materialId = draws[drawId].draw_materialIdReserved & 0xffffu;
#else
#define materialId 0u
#endif
#if (defined(WIREFRAME_RENDERING) || defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)) && !defined(TBN_DIRECTION)
#if (defined(WIREFRAME_RENDERING) || defined(OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)) && !defined(TBN_DIRECTION)
lowp const vec4 color = materials[materialId].color;
lowp const vec4 wireframeColor = materials[materialId].wireframeColor;
#endif
@ -242,7 +254,7 @@ void main() {
#if defined(WIREFRAME_RENDERING) || defined(TBN_DIRECTION)
lowp const float smoothness = materials[materialId].material_smoothness;
#endif
#if defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
lowp const float colorMapOffset = materials[materialId].material_colorMapOffset;
lowp const float colorMapScale = materials[materialId].material_colorMapScale;
#endif
@ -251,14 +263,17 @@ void main() {
/* Map object/vertex/primitive ID to a color. Will be either combined with
the wireframe background color (if wireframe is enabled), ignored (if
rendering TBN direction) or used as-is if nothing else is enabled */
#if defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
lowp vec4 faceColor = texture(colorMapTexture, vec2(
/* Object/primitive IDs are constant across the whole primitive so we
do the offset/scale mapping here */
#if defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
colorMapOffset + float(
#ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId
#ifdef OBJECT_ID
objectId
#ifdef INSTANCED_OBJECT_ID
+ interpolatedInstanceObjectId
#endif
#elif defined(PRIMITIVE_ID)
gl_PrimitiveID
#elif defined(PRIMITIVE_ID_FROM_VERTEX_ID)
@ -312,7 +327,7 @@ void main() {
#else
fragmentColor = backgroundColor;
#endif
#if defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
fragmentColor *= faceColor;
#endif
@ -362,7 +377,7 @@ void main() {
#endif
/* Object / Vertex / Primitive ID visualization using a colormap */
#elif defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#elif defined(OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
fragmentColor = color*faceColor;
#else

7
src/Magnum/Shaders/MeshVisualizer.geom

@ -66,7 +66,7 @@ uniform lowp vec4 wireframeColor
#if defined(TANGENT_DIRECTION) || defined(BITANGENT_DIRECTION) || defined(NORMAL_DIRECTION)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 9)
layout(location = 10)
#endif
uniform lowp float lineWidth
#ifndef GL_ES
@ -108,8 +108,9 @@ struct DrawUniform {
#elif !defined(TWO_DIMENSIONS)
#error
#endif
highp uvec4 materialIdReservedReservedReservedReserved;
#define draw_materialIdReserved materialIdReservedReservedReservedReserved.x
highp uvec4 materialIdReservedObjectIdReservedReserved;
#define draw_materialIdReserved materialIdReservedObjectIdReservedReserved.x
#define draw_objectId materialIdReservedObjectIdReservedReserved.y
};
layout(std140

76
src/Magnum/Shaders/MeshVisualizer.h

@ -59,11 +59,12 @@ struct MeshVisualizerDrawUniform2D {
_pad0{}, /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
materialId{0}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
#ifndef CORRADE_TARGET_BIG_ENDIAN
#if ((defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)) && !defined(CORRADE_TARGET_BIG_ENDIAN)
, _pad0{}
#endif
, _pad1{}, _pad2{}, _pad3{}
, objectId{0}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
, _pad1{}, _pad2{}
#endif
{}
@ -88,6 +89,15 @@ struct MeshVisualizerDrawUniform2D {
return *this;
}
/**
* @brief Set the @ref objectId field
* @return Reference to self (for method chaining)
*/
MeshVisualizerDrawUniform2D& setObjectId(UnsignedInt id) {
objectId = id;
return *this;
}
/**
* @}
*/
@ -108,7 +118,7 @@ struct MeshVisualizerDrawUniform2D {
/* This field is an UnsignedInt in the shader and materialId is extracted
as (value & 0xffff), so the order has to be different on BE */
#ifndef CORRADE_TARGET_BIG_ENDIAN
alignas(4) UnsignedShort materialId;
UnsignedShort materialId;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -119,7 +129,7 @@ struct MeshVisualizerDrawUniform2D {
:16; /* reserved for skinOffset */
#endif
#else
alignas(4) UnsignedShort
UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
@ -127,6 +137,21 @@ struct MeshVisualizerDrawUniform2D {
UnsignedShort materialId;
#endif
/**
* @brief Object ID
*
* Unlike @ref materialId, this index is used only for the object ID
* visualization, not to access any other uniform data. Default value
* is @cpp 0 @ce.
*
* Used only if @ref MeshVisualizerGL2D::Flag::ObjectId is enabled, ignored
* otherwise. If @ref MeshVisualizerGL2D::Flag::InstancedObjectId is
* enabled as well, this value is added to the ID coming from the
* @ref MeshVisualizerGL2D::ObjectId attribute.
* @see @ref MeshVisualizerGL2D::setObjectId()
*/
UnsignedInt objectId;
/* warning: Member __pad1__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -140,11 +165,6 @@ struct MeshVisualizerDrawUniform2D {
_pad2 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad3 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
};
@ -165,11 +185,12 @@ struct MeshVisualizerDrawUniform3D {
, _pad0{} /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
, materialId{0}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
#ifndef CORRADE_TARGET_BIG_ENDIAN
#if ((defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)) && !defined(CORRADE_TARGET_BIG_ENDIAN)
, _pad0{}
#endif
, _pad1{}, _pad2{}, _pad3{}
, objectId{0}
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
, _pad1{}, _pad2{}
#endif
{}
@ -206,6 +227,15 @@ struct MeshVisualizerDrawUniform3D {
return *this;
}
/**
* @brief Set the @ref objectId field
* @return Reference to self (for method chaining)
*/
MeshVisualizerDrawUniform3D& setObjectId(UnsignedInt id) {
objectId = id;
return *this;
}
/**
* @}
*/
@ -252,6 +282,21 @@ struct MeshVisualizerDrawUniform3D {
UnsignedShort materialId;
#endif
/**
* @brief Object ID
*
* Unlike @ref materialId, this index is used only for the object ID
* visualization, not to access any other uniform data. Default value
* is @cpp 0 @ce.
*
* Used only if @ref MeshVisualizerGL3D::Flag::ObjectId is enabled, ignored
* otherwise. If @ref MeshVisualizerGL3D::Flag::InstancedObjectId is
* enabled as well, this value is added to the ID coming from the
* @ref MeshVisualizerGL3D::ObjectId attribute.
* @see @ref MeshVisualizerGL3D::setObjectId()
*/
UnsignedInt objectId;
/* warning: Member __pad1__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -265,11 +310,6 @@ struct MeshVisualizerDrawUniform3D {
_pad2 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
Int
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8)
_pad3 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif
:32;
#endif
};

15
src/Magnum/Shaders/MeshVisualizer.vert

@ -49,7 +49,7 @@
#ifndef UNIFORM_BUFFERS
#ifdef TWO_DIMENSIONS
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6)
layout(location = 7)
#endif
uniform highp mat3 transformationProjectionMatrix
#ifndef GL_ES
@ -58,7 +58,7 @@ uniform highp mat3 transformationProjectionMatrix
;
#elif defined(THREE_DIMENSIONS)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6)
layout(location = 7)
#endif
uniform highp mat4 transformationMatrix
#ifndef GL_ES
@ -66,7 +66,7 @@ uniform highp mat4 transformationMatrix
#endif
;
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 7)
layout(location = 8)
#endif
uniform highp mat4 projectionMatrix
#ifndef GL_ES
@ -92,7 +92,7 @@ uniform lowp vec2 colorMapOffsetScale
#if defined(TANGENT_DIRECTION) || defined(BITANGENT_FROM_TANGENT_DIRECTION) || defined(BITANGENT_DIRECTION) || defined(NORMAL_DIRECTION)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 8)
layout(location = 9)
#endif
uniform highp mat3 normalMatrix
#ifndef GL_ES
@ -101,7 +101,7 @@ uniform highp mat3 normalMatrix
;
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 10)
layout(location = 11)
#endif
uniform highp float lineLength
#ifndef GL_ES
@ -166,8 +166,9 @@ struct DrawUniform {
#elif !defined(TWO_DIMENSIONS)
#error
#endif
highp uvec4 materialIdReservedReservedReservedReserved;
#define draw_materialIdReserved materialIdReservedReservedReservedReserved.x
highp uvec4 materialIdReservedObjectIdReservedReserved;
#define draw_materialIdReserved materialIdReservedObjectIdReservedReserved.x
#define draw_objectId materialIdReservedObjectIdReservedReserved.y
};
layout(std140

70
src/Magnum/Shaders/MeshVisualizerGL.cpp

@ -85,12 +85,12 @@ MeshVisualizerGLBase::MeshVisualizerGLBase(FlagsBase flags
#ifndef MAGNUM_TARGET_GLES2
#ifndef CORRADE_NO_ASSERT
Int countMutuallyExclusive = 0;
if(flags & FlagBase::InstancedObjectId) ++countMutuallyExclusive;
if(flags & FlagBase::ObjectId) ++countMutuallyExclusive;
if(flags & FlagBase::VertexId) ++countMutuallyExclusive;
if(flags & FlagBase::PrimitiveIdFromVertexId) ++countMutuallyExclusive;
#endif
CORRADE_ASSERT(countMutuallyExclusive <= 1,
"Shaders::MeshVisualizerGL: Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive", );
"Shaders::MeshVisualizerGL: Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive", );
#endif
#ifndef MAGNUM_TARGET_GLES
@ -161,7 +161,7 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra
vert.addSource(_flags & FlagBase::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(_flags & FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags >= FlagBase::PrimitiveIdFromVertexId ? "#define PRIMITIVE_ID_FROM_VERTEX_ID\n" : "")
#endif
@ -185,7 +185,8 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra
#endif
frag.addSource(_flags & FlagBase::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(_flags & FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
@ -208,13 +209,24 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra
return version;
}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGLBase& MeshVisualizerGLBase::setObjectId(UnsignedInt id) {
CORRADE_ASSERT(!(_flags >= FlagBase::UniformBuffers),
"Shaders::MeshVisualizerGL::setObjectId(): the shader was created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & FlagBase::ObjectId,
"Shaders::MeshVisualizerGL::setObjectId(): the shader was not created with object ID enabled", *this);
setUniform(_objectIdUniform, id);
return *this;
}
#endif
MeshVisualizerGLBase& MeshVisualizerGLBase::setColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= FlagBase::UniformBuffers),
"Shaders::MeshVisualizerGL::setColor(): the shader was created with uniform buffers enabled", *this);
#endif
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(_flags & (FlagBase::Wireframe|FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
CORRADE_ASSERT(_flags & (FlagBase::Wireframe|FlagBase::ObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizerGL::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled", *this);
#else
CORRADE_ASSERT(_flags & FlagBase::Wireframe,
@ -250,7 +262,7 @@ MeshVisualizerGLBase& MeshVisualizerGLBase::setWireframeWidth(const Float width)
MeshVisualizerGLBase& MeshVisualizerGLBase::setColorMapTransformation(const Float offset, const Float scale) {
CORRADE_ASSERT(!(_flags >= FlagBase::UniformBuffers),
"Shaders::MeshVisualizerGL::setColorMapTransformation(): the shader was created with uniform buffers enabled", *this);
CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
CORRADE_ASSERT(_flags & (FlagBase::ObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizerGL::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled", *this);
setUniform(_colorMapOffsetScaleUniform, Vector2{offset, scale});
return *this;
@ -284,7 +296,7 @@ MeshVisualizerGLBase& MeshVisualizerGLBase::bindMaterialBuffer(GL::Buffer& buffe
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGLBase& MeshVisualizerGLBase::bindColorMapTexture(GL::Texture2D& texture) {
CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
CORRADE_ASSERT(_flags & (FlagBase::ObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizerGL::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled", *this);
texture.bind(ColorMapTextureUnit);
return *this;
@ -303,7 +315,7 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
#endif
} {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL2D: at least one visualization feature has to be enabled", );
#else
CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader),
@ -356,7 +368,7 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
geom = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Geometry);
(*geom)
.addSource("#define WIREFRAME_RENDERING\n#define MAX_VERTICES 3\n")
.addSource(_flags & FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
@ -433,7 +445,7 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
_transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
if(flags & (Flag::Wireframe
#ifndef MAGNUM_TARGET_GLES2
|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
#endif
))
_colorUniform = uniformLocation("color");
@ -443,9 +455,11 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
_smoothnessUniform = uniformLocation("smoothness");
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
if(flags & (Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
_colorMapOffsetScaleUniform = uniformLocation("colorMapOffsetScale");
}
if(flags & Flag::ObjectId)
_objectIdUniform = uniformLocation("objectId");
#endif
}
}
@ -455,7 +469,7 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
if(flags && !context.isExtensionSupported<GL::Extensions::ARB::shading_language_420pack>(version))
#endif
{
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
if(flags & (Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
setUniform(uniformLocation("colorMapTexture"), ColorMapTextureUnit);
}
#ifndef MAGNUM_TARGET_GLES2
@ -480,7 +494,7 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
setTransformationProjectionMatrix(Matrix3{Math::IdentityInit});
if(flags & (Flag::Wireframe
#ifndef MAGNUM_TARGET_GLES2
|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
#endif
))
setColor(Color3(1.0f));
@ -491,7 +505,7 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
setSmoothness(2.0f);
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId))
if(flags & (Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId))
setColorMapTransformation(1.0f/512.0f, 1.0f/256.0f);
#endif
}
@ -572,14 +586,14 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
#endif
} {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", );
CORRADE_ASSERT(!(flags & Flag::NoGeometryShader && flags & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection)),
"Shaders::MeshVisualizerGL3D: geometry shader has to be enabled when rendering TBN direction", );
CORRADE_ASSERT(!(flags & Flag::BitangentDirection && flags & Flag::BitangentFromTangentDirection),
"Shaders::MeshVisualizerGL3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive", );
#elif !defined(MAGNUM_TARGET_GLES2)
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", );
#else
CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader),
@ -587,7 +601,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_ASSERT(!(flags & Flag::InstancedObjectId) || !(flags & Flag::BitangentDirection),
CORRADE_ASSERT(!(flags >= Flag::InstancedObjectId) || !(flags & Flag::BitangentDirection),
"Shaders::MeshVisualizerGL3D: Bitangent attribute binding conflicts with the ObjectId attribute, use a Tangent4 attribute with instanced object ID rendering instead", );
#endif
@ -669,7 +683,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
(*geom)
.addSource(Utility::formatString("#define MAX_VERTICES {}\n", maxVertices))
.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
.addSource(_flags & FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
@ -765,7 +779,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
_projectionMatrixUniform = uniformLocation("projectionMatrix");
if(flags & (Flag::Wireframe
#ifndef MAGNUM_TARGET_GLES2
|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
#endif
))
_colorUniform = uniformLocation("color");
@ -781,9 +795,11 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
_smoothnessUniform = uniformLocation("smoothness");
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
if(flags & (Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
_colorMapOffsetScaleUniform = uniformLocation("colorMapOffsetScale");
}
if(flags & Flag::ObjectId)
_objectIdUniform = uniformLocation("objectId");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(flags & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection)) {
@ -800,7 +816,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
if(flags && !context.isExtensionSupported<GL::Extensions::ARB::shading_language_420pack>(version))
#endif
{
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
if(flags & (Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
setUniform(uniformLocation("colorMapTexture"), ColorMapTextureUnit);
}
#ifndef MAGNUM_TARGET_GLES2
@ -827,7 +843,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
setProjectionMatrix(Matrix4{Math::IdentityInit});
if(flags & (Flag::Wireframe
#ifndef MAGNUM_TARGET_GLES2
|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
#endif
))
setColor(Color3(1.0f));
@ -844,7 +860,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
setSmoothness(2.0f);
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId))
if(flags & (Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId))
setColorMapTransformation(1.0f/512.0f, 1.0f/256.0f);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
@ -996,6 +1012,7 @@ Debug& operator<<(Debug& debug, const MeshVisualizerGL2D::Flag value) {
_c(NoGeometryShader)
_c(Wireframe)
#ifndef MAGNUM_TARGET_GLES2
_c(ObjectId)
_c(InstancedObjectId)
_c(VertexId)
#ifndef MAGNUM_TARGET_WEBGL
@ -1029,6 +1046,7 @@ Debug& operator<<(Debug& debug, const MeshVisualizerGL3D::Flag value) {
_c(NormalDirection)
#endif
#ifndef MAGNUM_TARGET_GLES2
_c(ObjectId)
_c(InstancedObjectId)
_c(VertexId)
#ifndef MAGNUM_TARGET_WEBGL
@ -1054,7 +1072,8 @@ Debug& operator<<(Debug& debug, const MeshVisualizerGL2D::Flags value) {
there */
MeshVisualizerGL2D::Flag::NoGeometryShader,
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL2D::Flag::InstancedObjectId,
MeshVisualizerGL2D::Flag::InstancedObjectId, /* Superset of ObjectId */
MeshVisualizerGL2D::Flag::ObjectId,
MeshVisualizerGL2D::Flag::VertexId,
MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */
#ifndef MAGNUM_TARGET_WEBGL
@ -1081,7 +1100,8 @@ Debug& operator<<(Debug& debug, const MeshVisualizerGL3D::Flags value) {
MeshVisualizerGL3D::Flag::NormalDirection,
#endif
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL3D::Flag::InstancedObjectId,
MeshVisualizerGL3D::Flag::InstancedObjectId, /* Superset of ObjectId */
MeshVisualizerGL3D::Flag::ObjectId,
MeshVisualizerGL3D::Flag::VertexId,
MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */
#ifndef MAGNUM_TARGET_WEBGL

130
src/Magnum/Shaders/MeshVisualizerGL.h

@ -50,7 +50,8 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgr
Wireframe = 1 << 0,
NoGeometryShader = 1 << 1,
#ifndef MAGNUM_TARGET_GLES2
InstancedObjectId = 1 << 2,
ObjectId = 1 << 12,
InstancedObjectId = (1 << 2)|ObjectId,
VertexId = 1 << 3,
PrimitiveId = 1 << 4,
PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId,
@ -72,6 +73,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgr
MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const;
MeshVisualizerGLBase& setObjectId(UnsignedInt id);
MeshVisualizerGLBase& setColor(const Color4& color);
MeshVisualizerGLBase& setWireframeColor(const Color4& color);
MeshVisualizerGLBase& setWireframeWidth(Float width);
@ -104,7 +106,8 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgr
_wireframeWidthUniform{3},
_smoothnessUniform{4};
#ifndef MAGNUM_TARGET_GLES2
Int _colorMapOffsetScaleUniform{5};
Int _colorMapOffsetScaleUniform{5},
_objectIdUniform{6};
/* Used instead of all other uniforms except viewportSize when
Flag::UniformBuffers is set, so it can alias them */
Int _drawOffsetUniform{1};
@ -208,8 +211,37 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
NoGeometryShader = 1 << 1,
#ifndef MAGNUM_TARGET_GLES2
/** @copydoc MeshVisualizerGL3D::Flag::InstancedObjectId */
InstancedObjectId = 1 << 2,
/**
* Visualize object ID set via @ref setObjectId() or
* @ref MeshVisualizerDrawUniform2D::objectId. Since the ID is
* uniform for the whole draw, this feature is mainly useful in
* multidraw scenarios or when combined with
* @ref Flag::InstancedObjectId. Mutually exclusive with
* @ref Flag::VertexId and @ref Flag::PrimitiveId.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID input requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID input requires integer support in
* shaders, which is not available in WebGL 1.0.
* @m_since_latest
*/
ObjectId = 1 << 12,
/**
* Visualize instanced object ID. You need to provide the
* @ref ObjectId attribute in the mesh, which then gets summed with
* the ID coming from @ref setObjectId() or
* @ref MeshVisualizerDrawUniform2D::objectId. Implicitly enables
* @ref Flag::ObjectId. Mutually exclusive with @ref Flag::VertexId
* and @ref Flag::PrimitiveId.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID input requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID input requires integer support in
* shaders, which is not available in WebGL 1.0.
* @m_since{2020,06}
*/
InstancedObjectId = (1 << 2)|ObjectId,
/** @copydoc MeshVisualizerGL3D::Flag::VertexId */
VertexId = 1 << 3,
@ -406,6 +438,28 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
*/
MeshVisualizerGL2D& setViewportSize(const Vector2& size);
/**
* @brief Set object ID
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that @ref Flag::ObjectId is enabled. Default is
* @cpp 0 @ce. If @ref Flag::InstancedObjectId is enabled as well, this
* value is added to the ID coming from the @ref ObjectId attribute.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref MeshVisualizerDrawUniform2D::objectId and call
* @ref bindDrawBuffer() instead.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID input requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID input requires integer support in
* shaders, which is not available in WebGL 1.0.
*/
MeshVisualizerGL2D& setObjectId(UnsignedInt id) {
return static_cast<MeshVisualizerGL2D&>(Implementation::MeshVisualizerGLBase::setObjectId(id));
}
/**
* @brief Set base object color
* @return Reference to self (for method chaining)
@ -633,7 +687,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
#endif
private:
Int _transformationProjectionMatrixUniform{6};
Int _transformationProjectionMatrixUniform{7};
};
/**
@ -960,17 +1014,36 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
#ifndef MAGNUM_TARGET_GLES2
/**
* Visualize instanced object ID. You need to provide the
* @ref ObjectId attribute in the mesh. Mutually exclusive with
* Visualize object ID set via @ref setObjectId() or
* @ref MeshVisualizerDrawUniform3D::objectId. Since the ID is
* uniform for the whole draw, this feature is mainly useful in
* multidraw scenarios or when combined with
* @ref Flag::InstancedObjectId. Mutually exclusive with
* @ref Flag::VertexId and @ref Flag::PrimitiveId.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID output requires integer support in
* @requires_gles30 Object ID input requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID output requires integer support in
* @requires_webgl20 Object ID input requires integer support in
* shaders, which is not available in WebGL 1.0.
* @m_since_latest
*/
ObjectId = 1 << 12,
/**
* Visualize instanced object ID. You need to provide the
* @ref ObjectId attribute in the mesh, which then gets summed with
* the ID coming from @ref setObjectId() or
* @ref MeshVisualizerDrawUniform3D::objectId. Implicitly enables
* @ref Flag::ObjectId. Mutually exclusive with @ref Flag::VertexId
* and @ref Flag::PrimitiveId.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID input requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID input requires integer support in
* shaders, which is not available in WebGL 1.0.
* @m_since{2020,06}
*/
InstancedObjectId = 1 << 2,
InstancedObjectId = (1 << 2)|ObjectId,
/**
* Visualize vertex ID (@cpp gl_VertexID @ce). Useful for
@ -1339,6 +1412,28 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
*/
MeshVisualizerGL3D& setViewportSize(const Vector2& size);
/**
* @brief Set object ID
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Expects that @ref Flag::ObjectId is enabled. Default is
* @cpp 0 @ce. If @ref Flag::InstancedObjectId is enabled as well, this
* value is added to the ID coming from the @ref ObjectId attribute.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref MeshVisualizerDrawUniform3D::objectId and call
* @ref bindDrawBuffer() instead.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID input requires integer support in
* shaders, which is not available in OpenGL ES 2.0.
* @requires_webgl20 Object ID input requires integer support in
* shaders, which is not available in WebGL 1.0.
*/
MeshVisualizerGL3D& setObjectId(UnsignedInt id) {
return static_cast<MeshVisualizerGL3D&>(Implementation::MeshVisualizerGLBase::setObjectId(id));
}
/**
* @brief Set base object color
* @return Reference to self (for method chaining)
@ -1405,11 +1500,6 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
* @ref Flag::InstancedObjectId or @ref Flag::PrimitiveId /
* @ref Flag::PrimitiveIdFromVertexId is enabled.
*
* Note that this shader doesn't directly offer a
* @ref FlatGL::setObjectId() "setObjectId()" uniform that's used to
* offset the per-vertex / per-instance ID. Instead, you need to encode
* the base offset into the @p offset parameter.
*
* Expects that @ref Flag::UniformBuffers is not set, in that case fill
* @ref MeshVisualizerMaterialUniform::colorMapOffset and
* @ref MeshVisualizerMaterialUniform::colorMapScale and call
@ -1685,12 +1775,12 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
#endif
private:
Int _transformationMatrixUniform{6},
_projectionMatrixUniform{7};
Int _transformationMatrixUniform{7},
_projectionMatrixUniform{8};
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
Int _normalMatrixUniform{8},
_lineWidthUniform{9},
_lineLengthUniform{10};
Int _normalMatrixUniform{9},
_lineWidthUniform{10},
_lineLengthUniform{11};
#endif
};

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

@ -199,6 +199,8 @@ if(BUILD_GL_TESTS)
MeshVisualizerTestFiles/bitangents-from-tangents.tga
MeshVisualizerTestFiles/defaults-instancedobjectid2D.tga
MeshVisualizerTestFiles/defaults-instancedobjectid3D.tga
MeshVisualizerTestFiles/defaults-objectid2D.tga
MeshVisualizerTestFiles/defaults-objectid3D.tga
MeshVisualizerTestFiles/defaults-primitiveid2D.tga
MeshVisualizerTestFiles/defaults-primitiveid3D.tga
MeshVisualizerTestFiles/defaults-tbn.tga
@ -208,6 +210,8 @@ if(BUILD_GL_TESTS)
MeshVisualizerTestFiles/defaults-wireframe3D.tga
MeshVisualizerTestFiles/instancedobjectid2D.tga
MeshVisualizerTestFiles/instancedobjectid3D.tga
MeshVisualizerTestFiles/objectid2D.tga
MeshVisualizerTestFiles/objectid3D.tga
MeshVisualizerTestFiles/primitiveid-tn.tga
MeshVisualizerTestFiles/primitiveid2D.tga
MeshVisualizerTestFiles/primitiveid3D.tga

224
src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp

@ -115,6 +115,8 @@ struct MeshVisualizerGLTest: GL::OpenGLTester {
void setWireframeNotEnabled2D();
void setWireframeNotEnabled3D();
#ifndef MAGNUM_TARGET_GLES2
void setObjectIdNotEnabled2D();
void setObjectIdNotEnabled3D();
void setColorMapNotEnabled2D();
void setColorMapNotEnabled3D();
#endif
@ -134,6 +136,8 @@ struct MeshVisualizerGLTest: GL::OpenGLTester {
template<MeshVisualizerGL3D::Flag flag = MeshVisualizerGL3D::Flag{}> void renderDefaultsWireframe3D();
#endif
#ifndef MAGNUM_TARGET_GLES2
template<MeshVisualizerGL2D::Flag flag = MeshVisualizerGL2D::Flag{}> void renderDefaultsObjectId2D();
template<MeshVisualizerGL3D::Flag flag = MeshVisualizerGL3D::Flag{}> void renderDefaultsObjectId3D();
template<MeshVisualizerGL2D::Flag flag = MeshVisualizerGL2D::Flag{}> void renderDefaultsInstancedObjectId2D();
template<MeshVisualizerGL3D::Flag flag = MeshVisualizerGL3D::Flag{}> void renderDefaultsInstancedObjectId3D();
template<MeshVisualizerGL2D::Flag flag = MeshVisualizerGL2D::Flag{}> void renderDefaultsVertexId2D();
@ -215,6 +219,7 @@ constexpr struct {
#endif
{"wireframe w/o GS", MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", MeshVisualizerGL2D::Flag::ObjectId},
{"instanced object ID", MeshVisualizerGL2D::Flag::InstancedObjectId},
{"vertex ID", MeshVisualizerGL2D::Flag::VertexId},
#ifndef MAGNUM_TARGET_WEBGL
@ -245,6 +250,7 @@ constexpr struct {
{"wireframe", MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe, 1, 1},
#endif
{"wireframe w/o GS", MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader, 1, 1},
{"object ID", MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::ObjectId, 1, 1},
{"instanced object ID", MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::InstancedObjectId, 1, 1},
{"vertex ID", MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::VertexId, 1, 1},
#ifndef MAGNUM_TARGET_WEBGL
@ -265,6 +271,7 @@ constexpr struct {
#endif
{"wireframe w/o GS", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", MeshVisualizerGL3D::Flag::ObjectId},
{"instanced object ID", MeshVisualizerGL3D::Flag::InstancedObjectId},
{"vertex ID", MeshVisualizerGL3D::Flag::VertexId},
#ifndef MAGNUM_TARGET_WEBGL
@ -284,7 +291,9 @@ constexpr struct {
{"wireframe + instanced object ID + T/N direction", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::NormalDirection},
{"wireframe + vertex ID + T/B direction", MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::VertexId|MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::BitangentDirection},
/* InstancedObjectId|BitangentDirection is disallowed (checked in
ConstructInvalidData3D), but this should work */
ConstructInvalidData3D), but both ObjectId alone and
BitangentFromTangentDirection should work */
{"object ID + bitangent direction", MeshVisualizerGL3D::Flag::ObjectId|MeshVisualizerGL3D::Flag::BitangentDirection},
{"instanced object ID + bitangent from tangent direction", MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::BitangentFromTangentDirection},
#endif
};
@ -310,6 +319,7 @@ constexpr struct {
{"wireframe", MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe, 1, 1},
#endif
{"wireframe w/o GS", MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader, 1, 1},
{"object ID", MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::ObjectId, 1, 1},
{"instanced object ID", MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::InstancedObjectId, 1, 1},
{"vertex ID", MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::VertexId, 1, 1},
#ifndef MAGNUM_TARGET_WEBGL
@ -345,12 +355,15 @@ constexpr struct {
#endif
},
#ifndef MAGNUM_TARGET_GLES2
{"both object and primitive ID",
MeshVisualizerGL2D::Flag::ObjectId|MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId,
": Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both instanced object and primitive ID",
MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId,
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both instanced object and vertex ID",
MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::VertexId,
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"}
": Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both object and vertex ID",
MeshVisualizerGL2D::Flag::ObjectId|MeshVisualizerGL2D::Flag::VertexId,
": Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"}
#endif
};
@ -382,12 +395,15 @@ constexpr struct {
#endif
},
#ifndef MAGNUM_TARGET_GLES2
{"both object and primitive ID",
MeshVisualizerGL3D::Flag::ObjectId|MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId,
": Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both instanced object and primitive ID",
MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId,
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
": Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both vertex and primitive ID",
MeshVisualizerGL3D::Flag::VertexId|MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId,
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
": Flag::ObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
{"geometry shader disabled but needed",
@ -477,6 +493,10 @@ constexpr struct {
const char* file2D;
const char* file3D;
} ObjectVertexPrimitiveIdData[] {
{"object ID",
MeshVisualizerGL2D::Flag::ObjectId,
MeshVisualizerGL3D::Flag::ObjectId,
"objectid2D.tga", "objectid3D.tga"},
{"instanced object ID",
MeshVisualizerGL2D::Flag::InstancedObjectId,
MeshVisualizerGL3D::Flag::InstancedObjectId,
@ -752,6 +772,8 @@ MeshVisualizerGLTest::MeshVisualizerGLTest() {
&MeshVisualizerGLTest::setWireframeNotEnabled2D,
&MeshVisualizerGLTest::setWireframeNotEnabled3D,
#ifndef MAGNUM_TARGET_GLES2
&MeshVisualizerGLTest::setObjectIdNotEnabled2D,
&MeshVisualizerGLTest::setObjectIdNotEnabled3D,
&MeshVisualizerGLTest::setColorMapNotEnabled2D,
&MeshVisualizerGLTest::setColorMapNotEnabled3D,
#endif
@ -780,6 +802,22 @@ MeshVisualizerGLTest::MeshVisualizerGLTest() {
&MeshVisualizerGLTest::renderTeardown);
#endif
#ifndef MAGNUM_TARGET_GLES2
/* MSVC needs explicit type due to default template args */
addTests<MeshVisualizerGLTest>({
&MeshVisualizerGLTest::renderDefaultsObjectId2D,
#ifndef MAGNUM_TARGET_GLES2
&MeshVisualizerGLTest::renderDefaultsObjectId2D<MeshVisualizerGL2D::Flag::UniformBuffers>,
#endif
&MeshVisualizerGLTest::renderDefaultsObjectId3D,
#ifndef MAGNUM_TARGET_GLES2
&MeshVisualizerGLTest::renderDefaultsObjectId3D<MeshVisualizerGL3D::Flag::UniformBuffers>,
#endif
},
&MeshVisualizerGLTest::renderSetup,
&MeshVisualizerGLTest::renderTeardown);
#endif
#ifndef MAGNUM_TARGET_GLES2
/* MSVC needs explicit type due to default template args */
addInstancedTests<MeshVisualizerGLTest>({
@ -1394,6 +1432,7 @@ void MeshVisualizerGLTest::setUniformUniformBuffersEnabled2D() {
MeshVisualizerGL2D shader{MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader};
shader.setTransformationProjectionMatrix({})
/* setViewportSize() works on both UBOs and classic */
.setObjectId({})
.setColor({})
.setWireframeColor({})
.setWireframeWidth({})
@ -1401,6 +1440,7 @@ void MeshVisualizerGLTest::setUniformUniformBuffersEnabled2D() {
.setSmoothness({});
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizerGL2D::setTransformationProjectionMatrix(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setObjectId(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setColor(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setWireframeColor(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setWireframeWidth(): the shader was created with uniform buffers enabled\n"
@ -1425,6 +1465,7 @@ void MeshVisualizerGLTest::setUniformUniformBuffersEnabled3D() {
shader.setProjectionMatrix({})
.setTransformationMatrix({})
/* setViewportSize() works on both UBOs and classic */
.setObjectId({})
.setColor({})
.setWireframeColor({})
.setWireframeWidth({})
@ -1433,6 +1474,7 @@ void MeshVisualizerGLTest::setUniformUniformBuffersEnabled3D() {
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizerGL3D::setProjectionMatrix(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL3D::setTransformationMatrix(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setObjectId(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setColor(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setWireframeColor(): the shader was created with uniform buffers enabled\n"
"Shaders::MeshVisualizerGL::setWireframeWidth(): the shader was created with uniform buffers enabled\n"
@ -1582,6 +1624,32 @@ void MeshVisualizerGLTest::setWireframeNotEnabled3D() {
}
#ifndef MAGNUM_TARGET_GLES2
void MeshVisualizerGLTest::setObjectIdNotEnabled2D() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
MeshVisualizerGL2D shader{NoCreate};
std::ostringstream out;
Error redirectError{&out};
shader.setObjectId({});
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL::setObjectId(): the shader was not created with object ID enabled\n");
}
void MeshVisualizerGLTest::setObjectIdNotEnabled3D() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
MeshVisualizerGL3D shader{NoCreate};
std::ostringstream out;
Error redirectError{&out};
shader.setObjectId({});
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL::setObjectId(): the shader was not created with object ID enabled\n");
}
void MeshVisualizerGLTest::setColorMapNotEnabled2D() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
@ -1919,6 +1987,114 @@ template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderDefault
#endif
#ifndef MAGNUM_TARGET_GLES2
template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderDefaultsObjectId2D() {
if(flag == MeshVisualizerGL2D::Flag::UniformBuffers) {
setTestCaseTemplateName("Flag::UniformBuffers");
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::uniform_buffer_object>())
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
}
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
GL::Mesh circle = MeshTools::compile(Primitives::circle2DSolid(16));
MeshVisualizerGL2D shader{MeshVisualizerGL2D::Flag::ObjectId|flag};
shader.bindColorMapTexture(_colorMapTexture);
if(flag == MeshVisualizerGL2D::Flag{}) {
shader.draw(circle);
} else if(flag == MeshVisualizerGL2D::Flag::UniformBuffers) {
GL::Buffer transformationProjectionUniform{GL::Buffer::TargetHint::Uniform, {
TransformationProjectionUniform2D{}
}};
GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, {
MeshVisualizerDrawUniform2D{}
}};
GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, {
MeshVisualizerMaterialUniform{}
}};
shader
.bindTransformationProjectionBuffer(transformationProjectionUniform)
.bindDrawBuffer(drawUniform)
.bindMaterialBuffer(materialUniform)
.draw(circle);
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE();
MAGNUM_VERIFY_NO_GL_ERROR();
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(_testDir, "MeshVisualizerTestFiles/defaults-objectid2D.tga"),
(DebugTools::CompareImageToFile{_manager}));
}
template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderDefaultsObjectId3D() {
if(flag == MeshVisualizerGL3D::Flag::UniformBuffers) {
setTestCaseTemplateName("Flag::UniformBuffers");
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::uniform_buffer_object>())
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
}
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
GL::Mesh icosphere = MeshTools::compile(Primitives::icosphereSolid(0));
MeshVisualizerGL3D shader{MeshVisualizerGL3D::Flag::InstancedObjectId|flag};
shader.bindColorMapTexture(_colorMapTexture);
if(flag == MeshVisualizerGL3D::Flag{}) {
shader.draw(icosphere);
} else if(flag == MeshVisualizerGL3D::Flag::UniformBuffers) {
GL::Buffer projectionUniform{GL::Buffer::TargetHint::Uniform, {
ProjectionUniform3D{}
}};
GL::Buffer transformationUniform{GL::Buffer::TargetHint::Uniform, {
TransformationUniform3D{}
}};
GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, {
MeshVisualizerDrawUniform3D{}
}};
GL::Buffer materialUniform{GL::Buffer::TargetHint::Uniform, {
MeshVisualizerMaterialUniform{}
}};
shader
.bindProjectionBuffer(projectionUniform)
.bindTransformationBuffer(transformationUniform)
.bindDrawBuffer(drawUniform)
.bindMaterialBuffer(materialUniform)
.draw(icosphere);
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE();
MAGNUM_VERIFY_NO_GL_ERROR();
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImporter plugins not found.");
CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(_testDir, "MeshVisualizerTestFiles/defaults-objectid3D.tga"),
(DebugTools::CompareImageToFile{_manager}));
}
template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderDefaultsInstancedObjectId2D() {
auto&& data = InstancedObjectIdDefaultsData[testCaseInstanceId()];
setTestCaseDescription(data.name);
@ -2710,7 +2886,7 @@ template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderObjectV
}
#ifndef MAGNUM_TARGET_GLES
if((data.flags2D & MeshVisualizerGL2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
if((data.flags2D & MeshVisualizerGL2D::Flag::ObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
@ -2739,7 +2915,9 @@ template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderObjectV
Trade::MeshData circleData = Primitives::circle2DSolid(16);
if(data.flags2D & MeshVisualizerGL2D::Flag::InstancedObjectId) {
/* Add the instanced Object ID data even if visualizing just uniform object
ID, to test the attribute isn't accidentally accessed always */
if(data.flags2D & MeshVisualizerGL2D::Flag::ObjectId) {
Containers::Array<UnsignedInt> ids{16};
/* Each two faces share the same ID */
for(std::size_t i = 0; i != ids.size(); ++i) ids[i] = i/2;
@ -2777,14 +2955,19 @@ template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderObjectV
/* OTOH the wireframe color should stay at full channels, not mixed */
if(data.flags2D & MeshVisualizerGL2D::Flag::Wireframe)
shader.setWireframeColor(0xffffff_rgbf);
/* For object ID we set a base ID to verify the uniform and instanced
ID get summed. */
if(data.flags2D & MeshVisualizerGL2D::Flag::ObjectId)
shader.setObjectId(8);
/* For vertex ID we don't want any repeat/wraparound as that causes
disruptions in the gradient and test failures. There's 17 vertices
also. */
if(data.flags2D & MeshVisualizerGL2D::Flag::VertexId)
shader.setColorMapTransformation(1.0f, -1.0f/17.0f);
/* For object/primitive ID there's no gradient so a wraparound is okay.
This should cover the first half of the colormap, in reverse order;
for primitive ID the whole colormap due to the repeat wrapping */
For the object ID this should cover the second half of the colormap
(due to the uniform object ID), in reverse order; for primitive ID
the whole colormap due to the repeat wrapping */
else
shader.setColorMapTransformation(0.5f, -1.0f/16.0f);
shader.draw(circle);
@ -2796,6 +2979,7 @@ template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderObjectV
}};
GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, {
MeshVisualizerDrawUniform2D{}
.setObjectId(8)
}};
MeshVisualizerMaterialUniform materialUniformData[1];
materialUniformData->setColor(0xffff00_rgbf);
@ -2825,7 +3009,7 @@ template<MeshVisualizerGL2D::Flag flag> void MeshVisualizerGLTest::renderObjectV
Utility::Directory::join({_testDir, "MeshVisualizerTestFiles", data.file2D}),
/* AMD has slight off-by-one errors compared to Intel, SwiftShader a
bit more */
(DebugTools::CompareImageToFile{_manager, 4.0f, 0.141f}));
(DebugTools::CompareImageToFile{_manager, 4.67f, 0.141f}));
}
template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() {
@ -2842,7 +3026,7 @@ template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderObjectV
}
#ifndef MAGNUM_TARGET_GLES
if((data.flags3D & MeshVisualizerGL3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
if((data.flags3D & MeshVisualizerGL3D::Flag::ObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
@ -2871,7 +3055,9 @@ template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderObjectV
Trade::MeshData icosphereData = Primitives::icosphereSolid(1);
if(data.flags3D & MeshVisualizerGL3D::Flag::InstancedObjectId) {
/* Add the instanced Object ID data even if visualizing just uniform object
ID, to test the attribute isn't accidentally accessed always */
if(data.flags3D & MeshVisualizerGL3D::Flag::ObjectId) {
Containers::Array<UnsignedInt> ids{80};
/* Each four faces share the same ID */
for(std::size_t i = 0; i != ids.size(); ++i) ids[i] = i/4;
@ -2908,14 +3094,19 @@ template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderObjectV
/* OTOH the wireframe color should stay at full channels, not mixed */
if(data.flags3D & MeshVisualizerGL3D::Flag::Wireframe)
shader.setWireframeColor(0xffffff_rgbf);
/* For object ID we set a base ID to verify the uniform and instanced
ID get summed. */
if(data.flags3D & MeshVisualizerGL3D::Flag::ObjectId)
shader.setObjectId(20);
/* For vertex ID we don't want any repeat/wraparound as that causes
disruptions in the gradient and test failures. There's 42 vertices
also. */
if(data.flags3D & MeshVisualizerGL3D::Flag::VertexId)
shader.setColorMapTransformation(1.0f, -1.0f/42.0f);
/* For object/primitive ID there's no gradient so a wraparound is okay.
This should cover the first half of the colormap, in reverse order;
for primitive ID the whole colormap due to the repeat wrapping */
For the object ID this should cover the second half of the colormap
(due to the uniform object ID), in reverse order; for primitive ID
the whole colormap due to the repeat wrapping */
else
shader.setColorMapTransformation(0.5f, -1.0f/40.0f);
shader.draw(icosphere);
@ -2935,6 +3126,7 @@ template<MeshVisualizerGL3D::Flag flag> void MeshVisualizerGLTest::renderObjectV
}};
GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, {
MeshVisualizerDrawUniform3D{}
.setObjectId(20)
}};
MeshVisualizerMaterialUniform materialUniformData[1];
materialUniformData->setColor(0xffff00_rgbf);

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

@ -152,17 +152,37 @@ void MeshVisualizerGL_Test::debugFlags3D() {
#ifndef MAGNUM_TARGET_GLES2
void MeshVisualizerGL_Test::debugFlagsSupersets2D() {
/* InstancedObjectId is a superset of ObjectId so only one should be
printed */
{
std::ostringstream out;
Debug{&out} << (MeshVisualizerGL2D::Flag::InstancedObjectId|MeshVisualizerGL2D::Flag::ObjectId);
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL2D::Flag::InstancedObjectId\n");
}
/* MultiDraw is a superset of UniformBuffers so only one should be printed */
std::ostringstream out;
Debug{&out} << (MeshVisualizerGL2D::Flag::MultiDraw|MeshVisualizerGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL2D::Flag::MultiDraw\n");
{
std::ostringstream out;
Debug{&out} << (MeshVisualizerGL2D::Flag::MultiDraw|MeshVisualizerGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL2D::Flag::MultiDraw\n");
}
}
void MeshVisualizerGL_Test::debugFlagsSupersets3D() {
/* InstancedObjectId is a superset of ObjectId so only one should be
printed */
{
std::ostringstream out;
Debug{&out} << (MeshVisualizerGL3D::Flag::InstancedObjectId|MeshVisualizerGL3D::Flag::ObjectId);
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL3D::Flag::InstancedObjectId\n");
}
/* MultiDraw is a superset of UniformBuffers so only one should be printed */
std::ostringstream out;
Debug{&out} << (MeshVisualizerGL3D::Flag::MultiDraw|MeshVisualizerGL3D::Flag::UniformBuffers);
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL3D::Flag::MultiDraw\n");
{
std::ostringstream out;
Debug{&out} << (MeshVisualizerGL3D::Flag::MultiDraw|MeshVisualizerGL3D::Flag::UniformBuffers);
CORRADE_COMPARE(out.str(), "Shaders::MeshVisualizerGL3D::Flag::MultiDraw\n");
}
}
#endif

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid3D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid3D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid3D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid3D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid2D.tga

Binary file not shown.

BIN
src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid3D.tga

Binary file not shown.
Loading…
Cancel
Save