diff --git a/doc/changelog.dox b/doc/changelog.dox index edb2a8967..1b6e10446 100644 --- a/doc/changelog.dox +++ b/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 diff --git a/src/Magnum/Shaders/MeshVisualizer.frag b/src/Magnum/Shaders/MeshVisualizer.frag index db16422a8..2cb67b5a0 100644 --- a/src/Magnum/Shaders/MeshVisualizer.frag +++ b/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 diff --git a/src/Magnum/Shaders/MeshVisualizer.geom b/src/Magnum/Shaders/MeshVisualizer.geom index ac662e2ad..e2a31d8f1 100644 --- a/src/Magnum/Shaders/MeshVisualizer.geom +++ b/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 diff --git a/src/Magnum/Shaders/MeshVisualizer.h b/src/Magnum/Shaders/MeshVisualizer.h index 9b0a540c4..dc174dfc1 100644 --- a/src/Magnum/Shaders/MeshVisualizer.h +++ b/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 }; diff --git a/src/Magnum/Shaders/MeshVisualizer.vert b/src/Magnum/Shaders/MeshVisualizer.vert index 91f2355e7..8e3a8732f 100644 --- a/src/Magnum/Shaders/MeshVisualizer.vert +++ b/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 diff --git a/src/Magnum/Shaders/MeshVisualizerGL.cpp b/src/Magnum/Shaders/MeshVisualizerGL.cpp index 1fc40b8ec..9a61eee5d 100644 --- a/src/Magnum/Shaders/MeshVisualizerGL.cpp +++ b/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(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(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 diff --git a/src/Magnum/Shaders/MeshVisualizerGL.h b/src/Magnum/Shaders/MeshVisualizerGL.h index 1b2dda3ed..8f9b8e228 100644 --- a/src/Magnum/Shaders/MeshVisualizerGL.h +++ b/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(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(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 }; diff --git a/src/Magnum/Shaders/Test/CMakeLists.txt b/src/Magnum/Shaders/Test/CMakeLists.txt index 90feea049..02e748404 100644 --- a/src/Magnum/Shaders/Test/CMakeLists.txt +++ b/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 diff --git a/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp b/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp index 3417e73d4..743eea173 100644 --- a/src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp +++ b/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 void renderDefaultsWireframe3D(); #endif #ifndef MAGNUM_TARGET_GLES2 + template void renderDefaultsObjectId2D(); + template void renderDefaultsObjectId3D(); template void renderDefaultsInstancedObjectId2D(); template void renderDefaultsInstancedObjectId3D(); template 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::renderDefaultsObjectId2D, + #ifndef MAGNUM_TARGET_GLES2 + &MeshVisualizerGLTest::renderDefaultsObjectId2D, + #endif + &MeshVisualizerGLTest::renderDefaultsObjectId3D, + #ifndef MAGNUM_TARGET_GLES2 + &MeshVisualizerGLTest::renderDefaultsObjectId3D, + #endif + }, + &MeshVisualizerGLTest::renderSetup, + &MeshVisualizerGLTest::renderTeardown); + #endif + #ifndef MAGNUM_TARGET_GLES2 /* MSVC needs explicit type due to default template args */ addInstancedTests({ @@ -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 void MeshVisualizerGLTest::renderDefault #endif #ifndef MAGNUM_TARGET_GLES2 +template void MeshVisualizerGLTest::renderDefaultsObjectId2D() { + if(flag == MeshVisualizerGL2D::Flag::UniformBuffers) { + setTestCaseTemplateName("Flag::UniformBuffers"); + + #ifndef MAGNUM_TARGET_GLES + if(!GL::Context::current().isExtensionSupported()) + CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported."); + #endif + } + + #ifndef MAGNUM_TARGET_GLES + if(!GL::Context::current().isExtensionSupported()) + 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(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(_testDir, "MeshVisualizerTestFiles/defaults-objectid2D.tga"), + (DebugTools::CompareImageToFile{_manager})); +} + +template void MeshVisualizerGLTest::renderDefaultsObjectId3D() { + if(flag == MeshVisualizerGL3D::Flag::UniformBuffers) { + setTestCaseTemplateName("Flag::UniformBuffers"); + + #ifndef MAGNUM_TARGET_GLES + if(!GL::Context::current().isExtensionSupported()) + CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported."); + #endif + } + + #ifndef MAGNUM_TARGET_GLES + if(!GL::Context::current().isExtensionSupported()) + 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(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels()), + Utility::Directory::join(_testDir, "MeshVisualizerTestFiles/defaults-objectid3D.tga"), + (DebugTools::CompareImageToFile{_manager})); +} + template void MeshVisualizerGLTest::renderDefaultsInstancedObjectId2D() { auto&& data = InstancedObjectIdDefaultsData[testCaseInstanceId()]; setTestCaseDescription(data.name); @@ -2710,7 +2886,7 @@ template void MeshVisualizerGLTest::renderObjectV } #ifndef MAGNUM_TARGET_GLES - if((data.flags2D & MeshVisualizerGL2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags2D & MeshVisualizerGL2D::Flag::ObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif @@ -2739,7 +2915,9 @@ template 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 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 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 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 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 void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() { @@ -2842,7 +3026,7 @@ template void MeshVisualizerGLTest::renderObjectV } #ifndef MAGNUM_TARGET_GLES - if((data.flags3D & MeshVisualizerGL3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported()) + if((data.flags3D & MeshVisualizerGL3D::Flag::ObjectId) && !GL::Context::current().isExtensionSupported()) CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported."); #endif @@ -2871,7 +3055,9 @@ template 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 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 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 void MeshVisualizerGLTest::renderObjectV }}; GL::Buffer drawUniform{GL::Buffer::TargetHint::Uniform, { MeshVisualizerDrawUniform3D{} + .setObjectId(20) }}; MeshVisualizerMaterialUniform materialUniformData[1]; materialUniformData->setColor(0xffff00_rgbf); diff --git a/src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp b/src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp index 10e7ffc53..f13e7a11b 100644 --- a/src/Magnum/Shaders/Test/MeshVisualizerGL_Test.cpp +++ b/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 diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid2D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid2D.tga new file mode 100644 index 000000000..b8d999b78 Binary files /dev/null and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid2D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid3D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid3D.tga new file mode 100644 index 000000000..b4caf06d4 Binary files /dev/null and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-objectid3D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid2D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid2D.tga index 6e6a7b4af..c31502283 100644 Binary files a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid2D.tga and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid2D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid3D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid3D.tga index 90e05699e..8c4e19df2 100644 Binary files a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid3D.tga and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/instancedobjectid3D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid2D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid2D.tga new file mode 100644 index 000000000..bd42fbbed Binary files /dev/null and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid2D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid3D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid3D.tga new file mode 100644 index 000000000..81654345a Binary files /dev/null and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/objectid3D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid2D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid2D.tga index 5ed8df360..0a64e6270 100644 Binary files a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid2D.tga and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid2D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid3D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid3D.tga index 44a7028c9..13b87c990 100644 Binary files a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid3D.tga and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-instancedobjectid3D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid2D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid2D.tga index 4d0b06899..7accebcf3 100644 Binary files a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid2D.tga and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid2D.tga differ diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid3D.tga b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid3D.tga index 32fa6390f..5182ba0f7 100644 Binary files a/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid3D.tga and b/src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-nogeo-instancedobjectid3D.tga differ