Browse Source

Shaders: add vertex ID visualization to MeshVisualizer.

Helps visualizing face connectivity (or the lack of it).
pull/442/head
Vladimír Vondruš 6 years ago
parent
commit
062055d20d
  1. 4
      doc/changelog.dox
  2. 39
      src/Magnum/Shaders/MeshVisualizer.cpp
  3. 52
      src/Magnum/Shaders/MeshVisualizer.frag
  4. 12
      src/Magnum/Shaders/MeshVisualizer.geom
  5. 74
      src/Magnum/Shaders/MeshVisualizer.h
  6. 29
      src/Magnum/Shaders/MeshVisualizer.vert
  7. 6
      src/Magnum/Shaders/Test/CMakeLists.txt
  8. 149
      src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp
  9. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-vertexid2D.tga
  10. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/defaults-vertexid3D.tga
  11. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/vertexid2D.tga
  12. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/vertexid3D.tga
  13. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-vertexid2D.tga
  14. BIN
      src/Magnum/Shaders/Test/MeshVisualizerTestFiles/wireframe-vertexid3D.tga

4
doc/changelog.dox

@ -247,8 +247,8 @@ See also:
- New @ref Shaders::MeshVisualizer2D for 2D mesh visualization
- Tangent space visualization in @ref Shaders::MeshVisualizer3D
- Object and primitive ID visualization in @ref Shaders::MeshVisualizer2D
and @ref Shaders::MeshVisualizer3D
- Object, vertex and primitive ID visualization in
@ref Shaders::MeshVisualizer2D and @ref Shaders::MeshVisualizer3D
- Texture coordinate transformation in @ref Shaders::DistanceFieldVector,
@ref Shaders::Flat, @ref Shaders::Phong and @ref Shaders::Vector
- Ability to render Per-instance / per-vertex object ID in @ref Shaders::Flat

39
src/Magnum/Shaders/MeshVisualizer.cpp

@ -57,10 +57,11 @@ MeshVisualizerBase::MeshVisualizerBase(FlagsBase flags): _flags{flags} {
#ifndef CORRADE_NO_ASSERT
Int countMutuallyExclusive = 0;
if(flags & FlagBase::InstancedObjectId) ++countMutuallyExclusive;
if(flags & FlagBase::VertexId) ++countMutuallyExclusive;
if(flags & FlagBase::PrimitiveIdFromVertexId) ++countMutuallyExclusive;
#endif
CORRADE_ASSERT(countMutuallyExclusive <= 1,
"Shaders::MeshVisualizer: Flag::InstancedObjectId and Flag::PrimitiveId are mutually exclusive", );
"Shaders::MeshVisualizer: Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive", );
#endif
#ifndef MAGNUM_TARGET_GLES2
@ -113,6 +114,7 @@ GL::Version MeshVisualizerBase::setupShaders(GL::Shader& vert, GL::Shader& frag,
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::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags >= FlagBase::PrimitiveIdFromVertexId ? "#define PRIMITIVE_ID_FROM_VERTEX_ID\n" : "")
#endif
#ifdef MAGNUM_TARGET_WEBGL
@ -126,6 +128,7 @@ GL::Version MeshVisualizerBase::setupShaders(GL::Shader& vert, GL::Shader& frag,
.addSource(_flags & FlagBase::NoGeometryShader ? "#define NO_GEOMETRY_SHADER\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(_flags & FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
"#define PRIMITIVE_ID_FROM_VERTEX_ID\n" :
@ -138,8 +141,8 @@ GL::Version MeshVisualizerBase::setupShaders(GL::Shader& vert, GL::Shader& frag,
MeshVisualizerBase& MeshVisualizerBase::setColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(_flags & (FlagBase::Wireframe|FlagBase::InstancedObjectId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/primitive ID enabled", *this);
CORRADE_ASSERT(_flags & (FlagBase::Wireframe|FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled", *this);
#else
CORRADE_ASSERT(_flags & FlagBase::Wireframe,
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe enabled", *this);
@ -164,15 +167,15 @@ MeshVisualizerBase& MeshVisualizerBase::setWireframeWidth(const Float width) {
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerBase& MeshVisualizerBase::setColorMapTransformation(const Float offset, const Float scale) {
CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/primitive ID enabled", *this);
CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled", *this);
setUniform(_colorMapOffsetScaleUniform, Vector2{offset, scale});
return *this;
}
MeshVisualizerBase& MeshVisualizerBase::bindColorMapTexture(GL::Texture2D& texture) {
CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/primitive ID enabled", *this);
CORRADE_ASSERT(_flags & (FlagBase::InstancedObjectId|FlagBase::VertexId|FlagBase::PrimitiveId),
"Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled", *this);
texture.bind(ColorMapTextureUnit);
return *this;
}
@ -182,7 +185,7 @@ MeshVisualizerBase& MeshVisualizerBase::bindColorMapTexture(GL::Texture2D& textu
MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisualizerBase{Implementation::MeshVisualizerBase::FlagBase(UnsignedShort(flags))} {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizer2D: at least one visualization feature has to be enabled", );
#else
CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader),
@ -212,6 +215,7 @@ MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisua
(*geom)
.addSource("#define WIREFRAME_RENDERING\n#define MAX_VERTICES 3\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 ?
"#define PRIMITIVE_ID_FROM_VERTEX_ID\n" :
@ -264,7 +268,7 @@ MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisua
_transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
if(flags & (Flag::Wireframe
#ifndef MAGNUM_TARGET_GLES2
|Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId
|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
#endif
))
_colorUniform = uniformLocation("color");
@ -276,7 +280,7 @@ MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisua
_viewportSizeUniform = uniformLocation("viewportSize");
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId)) {
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
_colorMapOffsetScaleUniform = uniformLocation("colorMapOffsetScale");
setUniform(uniformLocation("colorMapTexture"), ColorMapTextureUnit);
}
@ -299,7 +303,7 @@ MeshVisualizer2D::MeshVisualizer2D(const Flags flags): Implementation::MeshVisua
setSmoothness(2.0f);
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId))
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId))
setColorMapTransformation(1.0f/512.0f, 1.0f/256.0f);
#endif
#endif
@ -329,7 +333,7 @@ MeshVisualizer2D& MeshVisualizer2D::setSmoothness(const Float smoothness) {
MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisualizerBase{Implementation::MeshVisualizerBase::FlagBase(UnsignedShort(flags))} {
#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::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizer3D: at least one visualization feature has to be enabled", );
CORRADE_ASSERT(!(flags & Flag::NoGeometryShader && flags & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection)),
"Shaders::MeshVisualizer3D: geometry shader has to be enabled when rendering TBN direction", );
@ -394,6 +398,7 @@ MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisua
.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::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
"#define PRIMITIVE_ID_FROM_VERTEX_ID\n" :
@ -461,7 +466,7 @@ MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisua
_projectionMatrixUniform = uniformLocation("projectionMatrix");
if(flags & (Flag::Wireframe
#ifndef MAGNUM_TARGET_GLES2
|Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId
|Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId
#endif
))
_colorUniform = uniformLocation("color");
@ -479,7 +484,7 @@ MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisua
_viewportSizeUniform = uniformLocation("viewportSize");
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId)) {
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId)) {
_colorMapOffsetScaleUniform = uniformLocation("colorMapOffsetScale");
setUniform(uniformLocation("colorMapTexture"), ColorMapTextureUnit);
}
@ -516,7 +521,7 @@ MeshVisualizer3D::MeshVisualizer3D(const Flags flags): Implementation::MeshVisua
setSmoothness(2.0f);
}
#ifndef MAGNUM_TARGET_GLES2
if(flags & (Flag::InstancedObjectId|Flag::PrimitiveIdFromVertexId))
if(flags & (Flag::InstancedObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId))
setColorMapTransformation(1.0f/512.0f, 1.0f/256.0f);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
@ -602,6 +607,7 @@ Debug& operator<<(Debug& debug, const MeshVisualizer2D::Flag value) {
_c(Wireframe)
#ifndef MAGNUM_TARGET_GLES2
_c(InstancedObjectId)
_c(VertexId)
#ifndef MAGNUM_TARGET_WEBGL
_c(PrimitiveId)
#endif
@ -630,6 +636,7 @@ Debug& operator<<(Debug& debug, const MeshVisualizer3D::Flag value) {
#endif
#ifndef MAGNUM_TARGET_GLES2
_c(InstancedObjectId)
_c(VertexId)
#ifndef MAGNUM_TARGET_WEBGL
_c(PrimitiveId)
#endif
@ -649,6 +656,7 @@ Debug& operator<<(Debug& debug, const MeshVisualizer2D::Flags value) {
MeshVisualizer2D::Flag::NoGeometryShader,
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizer2D::Flag::InstancedObjectId,
MeshVisualizer2D::Flag::VertexId,
MeshVisualizer2D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */
#ifndef MAGNUM_TARGET_WEBGL
MeshVisualizer2D::Flag::PrimitiveId
@ -670,6 +678,7 @@ Debug& operator<<(Debug& debug, const MeshVisualizer3D::Flags value) {
#endif
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizer3D::Flag::InstancedObjectId,
MeshVisualizer3D::Flag::VertexId,
MeshVisualizer3D::Flag::PrimitiveIdFromVertexId, /* Superset of PrimitiveId */
#ifndef MAGNUM_TARGET_WEBGL
MeshVisualizer3D::Flag::PrimitiveId

52
src/Magnum/Shaders/MeshVisualizer.frag

@ -44,7 +44,7 @@
#extension GL_NV_shader_noperspective_interpolation: require
#endif
#if (defined(WIREFRAME_RENDERING) || defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)) && !defined(TBN_DIRECTION)
#if (defined(WIREFRAME_RENDERING) || defined(INSTANCED_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
@ -95,12 +95,14 @@ uniform lowp float smoothness
;
#endif
#if defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#ifdef EXPLICIT_TEXTURE_LAYER
layout(binding = 4)
#endif
uniform lowp sampler2D colorMapTexture;
#endif
#if defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6)
#endif
@ -127,6 +129,9 @@ in lowp vec3 barycentric;
#ifdef INSTANCED_OBJECT_ID
flat in highp uint interpolatedInstanceObjectId;
#endif
#ifdef VERTEX_ID
in highp float interpolatedMappedVertexId;
#endif
#ifdef PRIMITIVE_ID_FROM_VERTEX_ID
flat in highp uint interpolatedPrimitiveId;
#endif
@ -144,21 +149,34 @@ out lowp vec4 fragmentColor;
#endif
void main() {
/* Map object/primitive ID to a color. Will be either combined with the
wireframe background color (if wireframe is enabled), ignored (if
/* 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(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
lowp vec4 faceColor = texture(colorMapTexture, vec2(colorMapOffset + float(
#ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId
#elif defined(PRIMITIVE_ID)
gl_PrimitiveID
#elif defined(PRIMITIVE_ID_FROM_VERTEX_ID)
interpolatedPrimitiveId
#if defined(INSTANCED_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)
colorMapOffset + float(
#ifdef INSTANCED_OBJECT_ID
interpolatedInstanceObjectId
#elif defined(PRIMITIVE_ID)
gl_PrimitiveID
#elif defined(PRIMITIVE_ID_FROM_VERTEX_ID)
interpolatedPrimitiveId
#else
#error mosra messed up
#endif
)*colorMapScale
/* Vertex ID changes, so the offset/scale mapping was done already in
a VS/GS and we just pass the interpolated result to a texture */
#elif defined(VERTEX_ID)
interpolatedMappedVertexId
#else
#error mosra messed up
#error mosra messed up, again
#endif
)*colorMapScale, 0.0));
, 0.0));
#endif
/* 1. For wireframe the line is on the triangle edges, thus dist = 0 at
@ -195,7 +213,7 @@ void main() {
#else
fragmentColor = backgroundColor;
#endif
#if defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
#if defined(INSTANCED_OBJECT_ID) || defined(VERTEX_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
fragmentColor *= faceColor;
#endif
@ -244,8 +262,8 @@ void main() {
fragmentColor = mix(wireframeColor, fragmentColor, nearest);
#endif
/* Object / Primitive ID visualization using a colormap */
#elif defined(INSTANCED_OBJECT_ID) || defined(PRIMITIVE_ID) || defined(PRIMITIVE_ID_FROM_VERTEX_ID)
/* 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)
fragmentColor = color*faceColor;
#else

12
src/Magnum/Shaders/MeshVisualizer.geom

@ -103,6 +103,10 @@ out lowp vec3 dist;
flat in highp uint interpolatedVsInstanceObjectId[];
flat out highp uint interpolatedInstanceObjectId;
#endif
#ifdef VERTEX_ID
in highp float interpolatedVsMappedVertexId[];
out highp float interpolatedMappedVertexId;
#endif
#ifdef PRIMITIVE_ID_FROM_VERTEX_ID
flat in highp uint interpolatedVsPrimitiveId[];
flat out highp uint interpolatedPrimitiveId;
@ -180,7 +184,7 @@ void main() {
gl_PrimitiveID = gl_PrimitiveIDIn;
#endif
/* Screen position of each vertex */
/* Screen position of each vertex + TBN direction */
vec2 p[3];
#ifdef TANGENT_DIRECTION
vec2 t[3];
@ -216,7 +220,8 @@ void main() {
const float area = abs(dot(vec2(-v[1].y, v[1].x), v[2]));
/* If wireframe is enabled, add distance to opposite side to each vertex.
Otherwise make all distances the same to avoid any lines being drawn. */
Otherwise make all distances the same to avoid any lines being drawn.
Propagate also mapped vertex ID, since that changes per-vertex also. */
for(int i = 0; i != 3; ++i) {
dist = vec3(0.0, 0.0, 0.0);
#ifdef WIREFRAME_RENDERING
@ -224,6 +229,9 @@ void main() {
#else
dist = vec3(area/length(v[i]));
#endif
#ifdef VERTEX_ID
interpolatedMappedVertexId = interpolatedVsMappedVertexId[i];
#endif
#if defined(TANGENT_DIRECTION) || defined(BITANGENT_DIRECTION) || defined(NORMAL_DIRECTION)
backgroundColor = color;
lineColor = wireframeColor;

74
src/Magnum/Shaders/MeshVisualizer.h

@ -51,8 +51,9 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerBase: public GL::AbstractShaderProgram
NoGeometryShader = 1 << 1,
#ifndef MAGNUM_TARGET_GLES2
InstancedObjectId = 1 << 2,
PrimitiveId = 1 << 3,
PrimitiveIdFromVertexId = (1 << 4)|PrimitiveId
VertexId = 1 << 3,
PrimitiveId = 1 << 4,
PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId
#endif
};
typedef Containers::EnumSet<FlagBase> FlagsBase;
@ -189,16 +190,19 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer2D: public Implementation::MeshVisuali
/** @copydoc MeshVisualizer3D::Flag::InstancedObjectId */
InstancedObjectId = 1 << 2,
/** @copydoc MeshVisualizer3D::Flag::VertexId */
VertexId = 1 << 3,
#ifndef MAGNUM_TARGET_WEBGL
/** @copydoc MeshVisualizer3D::Flag::PrimitiveId */
PrimitiveId = 1 << 3,
PrimitiveId = 1 << 4,
#endif
/** @copydoc MeshVisualizer3D::Flag::PrimitiveIdFromVertexId */
#ifndef MAGNUM_TARGET_WEBGL
PrimitiveIdFromVertexId = (1 << 4)|PrimitiveId
PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId
#else
PrimitiveIdFromVertexId = (1 << 4)|(1 << 3)
PrimitiveIdFromVertexId = (1 << 5)|(1 << 4)
#endif
#endif
};
@ -447,7 +451,7 @@ Rendering setup:
@snippet MagnumShaders.cpp MeshVisualizer-usage-tbn2
@section Shaders-MeshVisualizer-object-id Object and primitive ID visualization
@section Shaders-MeshVisualizer-object-id Object, vertex and primitive ID visualization
If the mesh contains a per-vertex (or instanced) @ref ObjectId, it can be
visualized by enabling @ref Flag::InstancedObjectId. For the actual
@ -458,14 +462,19 @@ the @f$ [0, 1] @f$ texture range. Various colormap presets are in the
@snippet MagnumShaders.cpp MeshVisualizer-usage-object-id
If you enable @ref Flag::PrimitiveId instead, the shader will use the color map
to visualize the order in which primitives are drawn. That's useful for example
to see how well is the mesh optimized for a post-transform vertex cache. This
by default relies on the @glsl gl_PrimitiveID @ce GLSL builtin; with
@ref Flag::PrimitiveIdFromVertexId it's emulated using @glsl gl_VertexID @ce,
expecting you to draw a non-indexed triangle mesh. You can use
@ref MeshTools::duplicate() (and potentially @ref MeshTools::generateIndices())
to conveniently convert the mesh to a non-indexed @ref MeshPrimitive::Triangles.
If you enable @ref Flag::VertexId, the shader will use the color map to
visualize how are vertices shared among primitives. That's useful for
inspecting mesh connectivity --- primitives sharing vertices will have a smooth
color map transition while duplicated vertices will cause a sharp edge. This
relies on the @glsl gl_VertexID @ce GLSL builtin.
The @ref Flag::PrimitiveId then visualizes the order in which primitives are
drawn. That's useful for example to see to see how well is the mesh optimized
for a post-transform vertex cache. This by default relies on the @glsl gl_PrimitiveID @ce GLSL builtin; with @ref Flag::PrimitiveIdFromVertexId it's
emulated using @glsl gl_VertexID @ce, expecting you to draw a non-indexed
triangle mesh. You can use @ref MeshTools::duplicate() (and potentially
@ref MeshTools::generateIndices()) to conveniently convert the mesh to a
non-indexed @ref MeshPrimitive::Triangles.
@requires_gl32 The `gl_PrimitiveID` shader variable is not available on OpenGL
3.1 and lower.
@ -606,7 +615,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
/**
* Visualize instanced object ID. You need to provide the
* @ref ObjectId attribute in the mesh. Mutually exclusive with
* @ref Flag::PrimitiveId.
* @ref Flag::VertexId and @ref Flag::PrimitiveId.
* @requires_gl30 Extension @gl_extension{EXT,gpu_shader4}
* @requires_gles30 Object ID output requires integer support in
* shaders, which is not available in OpenGL ES 2.0 or WebGL
@ -615,10 +624,27 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
*/
InstancedObjectId = 1 << 2,
/**
* Visualize vertex ID (@cpp gl_VertexID @ce). Useful for
* visualizing mesh connectivity --- primitives sharing vertices
* will have a smooth color map transition while duplicated
* vertices will cause a sharp edge. Mutually exclusive with
* @ref Flag::InstancedObjectId and @ref Flag::PrimitiveId.
* @requires_gl30 The `gl_VertexID` shader variable is not
* available on OpenGL 2.1.
* @requires_gles30 The `gl_VertexID` shader variable is not
* available on OpenGL ES 2.0.
* @requires_webgl20 `gl_VertexID` is not available in WebGL 1.0.
* @m_since_latest
*/
VertexId = 1 << 3,
#ifndef MAGNUM_TARGET_WEBGL
/**
* Visualize primitive ID (@cpp gl_PrimitiveID @ce). Mutually
* exclusive with @ref Flag::InstancedObjectId. See also
* Visualize primitive ID (@cpp gl_PrimitiveID @ce). Useful for
* visualizing how well is the mesh optimized for a post-transform
* vertex cache. Mutually exclusive with
* @ref Flag::InstancedObjectId and @ref Flag::VertexId. See also
* @ref Flag::PrimitiveIdFromVertexId.
* @requires_gl32 The `gl_PrimitiveID` shader variable is not
* available on OpenGL 3.1 and lower.
@ -628,7 +654,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
* @requires_gles `gl_PrimitiveID` is not available in WebGL.
* @m_since_latest
*/
PrimitiveId = 1 << 3,
PrimitiveId = 1 << 4,
#endif
/**
@ -646,9 +672,9 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
* @m_since_latest
*/
#ifndef MAGNUM_TARGET_WEBGL
PrimitiveIdFromVertexId = (1 << 4)|PrimitiveId,
PrimitiveIdFromVertexId = (1 << 5)|PrimitiveId,
#else
PrimitiveIdFromVertexId = (1 << 4)|(1 << 3),
PrimitiveIdFromVertexId = (1 << 5)|(1 << 4),
#endif
#endif
@ -666,7 +692,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
* @requires_gles Geometry shaders are not available in WebGL.
* @m_since_latest
*/
TangentDirection = 1 << 5,
TangentDirection = 1 << 6,
/**
* Visualize bitangent direction with green lines pointing out of
@ -683,7 +709,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
* @requires_gles Geometry shaders are not available in WebGL.
* @m_since_latest
*/
BitangentFromTangentDirection = 1 << 6,
BitangentFromTangentDirection = 1 << 7,
/**
* Visualize bitangent direction with green lines pointing out of
@ -700,7 +726,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
* @requires_gles Geometry shaders are not available in WebGL.
* @m_since_latest
*/
BitangentDirection = 1 << 7,
BitangentDirection = 1 << 8,
/**
* Visualize normal direction with blue lines pointing out of
@ -714,7 +740,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer3D: public Implementation::MeshVisuali
* @requires_gles Geometry shaders are not available in WebGL.
* @m_since_latest
*/
NormalDirection = 1 << 8
NormalDirection = 1 << 9
#endif
};

29
src/Magnum/Shaders/MeshVisualizer.vert

@ -62,6 +62,19 @@ uniform highp mat4 projectionMatrix
#error
#endif
#ifdef VERTEX_ID
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 6)
#endif
uniform lowp vec2 colorMapOffsetScale
#ifndef GL_ES
= vec2(1.0/512.0, 1.0/256.0)
#endif
;
#define colorMapOffset colorMapOffsetScale.x
#define colorMapScale colorMapOffsetScale.y
#endif
#if defined(TANGENT_DIRECTION) || defined(BITANGENT_FROM_TANGENT_DIRECTION) || defined(BITANGENT_DIRECTION) || defined(NORMAL_DIRECTION)
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 8)
@ -139,6 +152,14 @@ flat out highp uint interpolatedVsInstanceObjectId;
#endif
#endif
#ifdef VERTEX_ID
#ifdef NO_GEOMETRY_SHADER
out highp float interpolatedMappedVertexId;
#else
out highp float interpolatedVsMappedVertexId;
#endif
#endif
#ifdef PRIMITIVE_ID_FROM_VERTEX_ID
#ifdef NO_GEOMETRY_SHADER
flat out highp uint interpolatedPrimitiveId;
@ -206,6 +227,14 @@ void main() {
#endif
= instanceObjectId;
#endif
#ifdef VERTEX_ID
#ifdef NO_GEOMETRY_SHADER
interpolatedMappedVertexId
#else
interpolatedVsMappedVertexId
#endif
= colorMapOffset + float(gl_VertexID)*colorMapScale;
#endif
#ifdef PRIMITIVE_ID_FROM_VERTEX_ID
#ifdef NO_GEOMETRY_SHADER
interpolatedPrimitiveId

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

@ -159,6 +159,8 @@ if(BUILD_GL_TESTS)
MeshVisualizerTestFiles/defaults-primitiveid2D.tga
MeshVisualizerTestFiles/defaults-primitiveid3D.tga
MeshVisualizerTestFiles/defaults-tbn.tga
MeshVisualizerTestFiles/defaults-vertexid2D.tga
MeshVisualizerTestFiles/defaults-vertexid3D.tga
MeshVisualizerTestFiles/defaults-wireframe2D.tga
MeshVisualizerTestFiles/defaults-wireframe3D.tga
MeshVisualizerTestFiles/objectid2D.tga
@ -168,6 +170,8 @@ if(BUILD_GL_TESTS)
MeshVisualizerTestFiles/primitiveid3D.tga
MeshVisualizerTestFiles/tbn-wide.tga
MeshVisualizerTestFiles/tbn.tga
MeshVisualizerTestFiles/vertexid2D.tga
MeshVisualizerTestFiles/vertexid3D.tga
MeshVisualizerTestFiles/wireframe-nogeo2D.tga
MeshVisualizerTestFiles/wireframe-nogeo3D.tga
MeshVisualizerTestFiles/wireframe-nogeo-objectid2D.tga
@ -175,6 +179,8 @@ if(BUILD_GL_TESTS)
MeshVisualizerTestFiles/wireframe-perspective.tga
MeshVisualizerTestFiles/wireframe-primitiveid-tn.tga
MeshVisualizerTestFiles/wireframe-tn-smooth.tga
MeshVisualizerTestFiles/wireframe-vertexid2D.tga
MeshVisualizerTestFiles/wireframe-vertexid3D.tga
MeshVisualizerTestFiles/wireframe-wide2D.tga
MeshVisualizerTestFiles/wireframe-wide3D.tga
MeshVisualizerTestFiles/wireframe2D.tga

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

@ -106,6 +106,8 @@ struct MeshVisualizerGLTest: GL::OpenGLTester {
#ifndef MAGNUM_TARGET_GLES2
void renderDefaultsObjectId2D();
void renderDefaultsObjectId3D();
void renderDefaultsVertexId2D();
void renderDefaultsVertexId3D();
void renderDefaultsPrimitiveId2D();
void renderDefaultsPrimitiveId3D();
#endif
@ -115,8 +117,8 @@ struct MeshVisualizerGLTest: GL::OpenGLTester {
void renderWireframe2D();
void renderWireframe3D();
#ifndef MAGNUM_TARGET_GLES2
void renderObjectPrimitiveId2D();
void renderObjectPrimitiveId3D();
void renderObjectVertexPrimitiveId2D();
void renderObjectVertexPrimitiveId3D();
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void renderWireframe3DPerspective();
@ -140,10 +142,11 @@ struct MeshVisualizerGLTest: GL::OpenGLTester {
- Mesa Intel
- Mesa AMD
. Mesa llvmpipe
- SwiftShader ES2/ES3
- ARM Mali (Huawei P10) ES2/ES3 (except TBN visualization)
- WebGL 1 / 2 (on Mesa Intel) (except primitive/object ID)
- iPhone 6 w/ iOS 12.4 (except primitive/object ID)
- WebGL 1 / 2 (on Mesa Intel) (except primitive/vertex/object ID)
- iPhone 6 w/ iOS 12.4 (except primitive/vertex/object ID)
*/
using namespace Math::Literals;
@ -155,6 +158,7 @@ constexpr struct {
{"wireframe w/o GS", MeshVisualizer2D::Flag::Wireframe|MeshVisualizer2D::Flag::NoGeometryShader},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", MeshVisualizer2D::Flag::InstancedObjectId},
{"vertex ID", MeshVisualizer2D::Flag::VertexId},
#ifndef MAGNUM_TARGET_WEBGL
{"primitive ID", MeshVisualizer2D::Flag::PrimitiveId},
#endif
@ -169,6 +173,7 @@ constexpr struct {
{"wireframe w/o GS", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::NoGeometryShader},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", MeshVisualizer3D::Flag::InstancedObjectId},
{"vertex ID", MeshVisualizer3D::Flag::VertexId},
#ifndef MAGNUM_TARGET_WEBGL
{"primitive ID", MeshVisualizer3D::Flag::InstancedObjectId},
#endif
@ -188,8 +193,10 @@ constexpr struct {
{"normal direction", MeshVisualizer3D::Flag::NormalDirection},
{"tbn direction", MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::BitangentDirection|MeshVisualizer3D::Flag::NormalDirection},
{"tbn direction with bitangent from tangent", MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::BitangentFromTangentDirection|MeshVisualizer3D::Flag::NormalDirection},
{"wireframe + vertex id", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::VertexId},
{"wireframe + t/n direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::NormalDirection},
{"wireframe + object id + t/n direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::NormalDirection}
{"wireframe + object id + t/n direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::NormalDirection},
{"wireframe + vertex id + t/b direction", MeshVisualizer3D::Flag::Wireframe|MeshVisualizer3D::Flag::VertexId|MeshVisualizer3D::Flag::TangentDirection|MeshVisualizer3D::Flag::BitangentDirection}
};
#endif
@ -209,7 +216,10 @@ constexpr struct {
#ifndef MAGNUM_TARGET_GLES2
{"both object and primitive id",
MeshVisualizer2D::Flag::InstancedObjectId|MeshVisualizer2D::Flag::PrimitiveIdFromVertexId,
": Flag::InstancedObjectId and Flag::PrimitiveId are mutually exclusive"}
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both object and vertex id",
MeshVisualizer2D::Flag::InstancedObjectId|MeshVisualizer2D::Flag::VertexId,
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"}
#endif
};
@ -229,7 +239,10 @@ constexpr struct {
#ifndef MAGNUM_TARGET_GLES2
{"both object and primitive id",
MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::PrimitiveIdFromVertexId,
": Flag::InstancedObjectId and Flag::PrimitiveId are mutually exclusive"}
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"},
{"both vertex and primitive id",
MeshVisualizer3D::Flag::VertexId|MeshVisualizer3D::Flag::PrimitiveIdFromVertexId,
": Flag::InstancedObjectId, Flag::VertexId and Flag::PrimitiveId are mutually exclusive"}
#endif
};
@ -293,11 +306,15 @@ constexpr struct {
MeshVisualizer3D::Flags flags3D;
const char* file2D;
const char* file3D;
} ObjectPrimitiveIdData[] {
} ObjectVertexPrimitiveIdData[] {
{"object ID",
MeshVisualizer2D::Flag::InstancedObjectId,
MeshVisualizer3D::Flag::InstancedObjectId,
"objectid2D.tga", "objectid3D.tga"},
{"vertex ID",
MeshVisualizer2D::Flag::VertexId,
MeshVisualizer3D::Flag::VertexId,
"vertexid2D.tga", "vertexid3D.tga"},
#ifndef MAGNUM_TARGET_WEBGL
{"primitive ID",
MeshVisualizer2D::Flag::PrimitiveId,
@ -317,7 +334,11 @@ constexpr struct {
MeshVisualizer2D::Flag::NoGeometryShader,
MeshVisualizer3D::Flag::InstancedObjectId|MeshVisualizer3D::Flag::Wireframe|
MeshVisualizer3D::Flag::NoGeometryShader,
"wireframe-nogeo-objectid2D.tga", "wireframe-nogeo-objectid3D.tga"}
"wireframe-nogeo-objectid2D.tga", "wireframe-nogeo-objectid3D.tga"},
{"wireframe + vertex ID",
MeshVisualizer2D::Flag::VertexId|MeshVisualizer2D::Flag::Wireframe,
MeshVisualizer3D::Flag::VertexId|MeshVisualizer3D::Flag::Wireframe,
"wireframe-vertexid2D.tga", "wireframe-vertexid3D.tga"}
};
#endif
@ -438,6 +459,8 @@ MeshVisualizerGLTest::MeshVisualizerGLTest() {
#ifndef MAGNUM_TARGET_GLES2
addTests({
&MeshVisualizerGLTest::renderDefaultsVertexId2D,
&MeshVisualizerGLTest::renderDefaultsVertexId3D,
&MeshVisualizerGLTest::renderDefaultsPrimitiveId2D,
&MeshVisualizerGLTest::renderDefaultsPrimitiveId3D,
#ifndef MAGNUM_TARGET_WEBGL
@ -459,9 +482,9 @@ MeshVisualizerGLTest::MeshVisualizerGLTest() {
&MeshVisualizerGLTest::renderTeardown);
#ifndef MAGNUM_TARGET_GLES2
addInstancedTests({&MeshVisualizerGLTest::renderObjectPrimitiveId2D,
&MeshVisualizerGLTest::renderObjectPrimitiveId3D},
Containers::arraySize(ObjectPrimitiveIdData),
addInstancedTests({&MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D,
&MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D},
Containers::arraySize(ObjectVertexPrimitiveIdData),
&MeshVisualizerGLTest::renderSetup,
&MeshVisualizerGLTest::renderTeardown);
#endif
@ -778,7 +801,7 @@ void MeshVisualizerGLTest::setWireframeNotEnabled2D() {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/primitive ID enabled\n");
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled\n");
#else
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe enabled\n");
@ -813,7 +836,7 @@ void MeshVisualizerGLTest::setWireframeNotEnabled3D() {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/primitive ID enabled\n");
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe or object/vertex/primitive ID enabled\n");
#else
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizer::setColor(): the shader was not created with wireframe enabled\n");
@ -846,8 +869,8 @@ void MeshVisualizerGLTest::setColorMapNotEnabled2D() {
.bindColorMapTexture(texture);
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/primitive ID enabled\n"
"Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/primitive ID enabled\n");
"Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled\n"
"Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled\n");
}
void MeshVisualizerGLTest::setColorMapNotEnabled3D() {
@ -864,8 +887,8 @@ void MeshVisualizerGLTest::setColorMapNotEnabled3D() {
.bindColorMapTexture(texture);
CORRADE_COMPARE(out.str(),
"Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/primitive ID enabled\n"
"Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/primitive ID enabled\n");
"Shaders::MeshVisualizer::setColorMapTransformation(): the shader was not created with object/vertex/primitive ID enabled\n"
"Shaders::MeshVisualizer::bindColorMapTexture(): the shader was not created with object/vertex/primitive ID enabled\n");
}
#endif
@ -1133,6 +1156,61 @@ void MeshVisualizerGLTest::renderDefaultsObjectId3D() {
(DebugTools::CompareImageToFile{_manager, 150.67f, 0.165f}));
}
void MeshVisualizerGLTest::renderDefaultsVertexId2D() {
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found.");
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL300)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES300)
#endif
) CORRADE_SKIP("gl_VertexID not supported.");
#endif
MeshVisualizer2D{MeshVisualizer2D::Flag::VertexId}
.bindColorMapTexture(_colorMapTexture)
.draw(MeshTools::compile(Primitives::circle2DSolid(16)));
MAGNUM_VERIFY_NO_GL_ERROR();
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-vertexid2D.tga"),
(DebugTools::CompareImageToFile{_manager, 1.0f, 0.017f}));
}
void MeshVisualizerGLTest::renderDefaultsVertexId3D() {
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found.");
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL300)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES300)
#endif
) CORRADE_SKIP("gl_VertexID not supported.");
#endif
MeshVisualizer2D{MeshVisualizer2D::Flag::VertexId}
.bindColorMapTexture(_colorMapTexture)
.draw(MeshTools::compile(Primitives::icosphereSolid(0)));
MAGNUM_VERIFY_NO_GL_ERROR();
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-vertexid3D.tga"),
(DebugTools::CompareImageToFile{_manager, 1.0f, 0.012f}));
}
void MeshVisualizerGLTest::renderDefaultsPrimitiveId2D() {
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
@ -1461,8 +1539,8 @@ void MeshVisualizerGLTest::renderWireframe3D() {
}
#ifndef MAGNUM_TARGET_GLES2
void MeshVisualizerGLTest::renderObjectPrimitiveId2D() {
auto&& data = ObjectPrimitiveIdData[testCaseInstanceId()];
void MeshVisualizerGLTest::renderObjectVertexPrimitiveId2D() {
auto&& data = ObjectVertexPrimitiveIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
@ -1519,15 +1597,23 @@ void MeshVisualizerGLTest::renderObjectPrimitiveId2D() {
/* Shouldn't assert (nor warn) when wireframe is not enabled */
.setViewportSize({80, 80})
.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f}))
/* Should cover the first half of the colormap, in reverse order; for
primitive ID the whole colormap due to the repeat wrapping */
.setColorMapTransformation(0.5f, -1.0f/16.0f)
.bindColorMapTexture(_colorMapTexture);
/* OTOH the wireframe color should stay at full channels, not mixed */
if(data.flags3D & MeshVisualizer3D::Flag::Wireframe)
shader.setWireframeColor(0xffffff_rgbf);
/* 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 & MeshVisualizer2D::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 */
else
shader.setColorMapTransformation(0.5f, -1.0f/16.0f);
shader.draw(circle);
MAGNUM_VERIFY_NO_GL_ERROR();
@ -1545,8 +1631,8 @@ void MeshVisualizerGLTest::renderObjectPrimitiveId2D() {
(DebugTools::CompareImageToFile{_manager, 4.0f, 0.141f}));
}
void MeshVisualizerGLTest::renderObjectPrimitiveId3D() {
auto&& data = ObjectPrimitiveIdData[testCaseInstanceId()];
void MeshVisualizerGLTest::renderObjectVertexPrimitiveId3D() {
auto&& data = ObjectVertexPrimitiveIdData[testCaseInstanceId()];
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
@ -1605,15 +1691,22 @@ void MeshVisualizerGLTest::renderObjectPrimitiveId3D() {
Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf))
.setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f))
/* Should cover the first half of the colormap, in reverse order; for
primitive ID the whole colormap due to the repeat wrapping */
.setColorMapTransformation(0.5f, -1.0f/40.0f)
.bindColorMapTexture(_colorMapTexture);
/* OTOH the wireframe color should stay at full channels, not mixed */
if(data.flags2D & MeshVisualizer2D::Flag::Wireframe)
shader.setWireframeColor(0xffffff_rgbf);
/* 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.flags2D & MeshVisualizer2D::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 */
else
shader.setColorMapTransformation(0.5f, -1.0f/40.0f);
shader.draw(circle);
MAGNUM_VERIFY_NO_GL_ERROR();

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.
Loading…
Cancel
Save