Magnum::Shaders::MeshVisualizer class

Mesh visualization shader.

Uses geometry shader to visualize wireframe of 3D meshes. You need to provide Position attribute in your triangle mesh and call at least setTransformationProjectionMatrix() to be able to render.

Image

Wireframe visualization

Wireframe visualization is done by enabling Flag::Wireframe. It is done either using geometry shaders or with help of additional vertex information.

If you have geometry shaders available, you don't need to do anything else.

If you don't have geometry shaders, you need to set Flag::NoGeometryShader (it's enabled by default in OpenGL ES 2.0) and use only non-indexed triangle meshes (see MeshTools::duplicate() for possible solution). Additionaly, if you have OpenGL < 3.1 or OpenGL ES 2.0, you need to provide also VertexIndex attribute.

If using geometry shaders on OpenGL ES, NV_shader_noperspective_interpolation is optionally used for improving line appearance.

Example usage

Wireframe visualization with geometry shader (desktop GL)

Common mesh setup:

struct Vertex {
    Vector3 position;
};
Vertex data[60]{
    // ...
};

GL::Buffer vertices;
vertices.setData(data, GL::BufferUsage::StaticDraw);

GL::Mesh mesh;
mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer::Position{});

Common rendering setup:

Matrix4 transformationMatrix = Matrix4::translation(Vector3::zAxis(-5.0f));
Matrix4 projectionMatrix = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f);

Shaders::MeshVisualizer shader{Shaders::MeshVisualizer::Flag::Wireframe};
shader.setColor(0x2f83cc_rgbf)
    .setWireframeColor(0xdcdcdc_rgbf)
    .setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()})
    .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix);

mesh.draw(shader);

Wireframe visualization without geometry shader on older hardware

You need to provide also the VertexIndex attribute. Mesh setup in addition to the above:

constexpr std::size_t vertexCount = Containers::arraySize(data);
Float vertexIndex[vertexCount];
std::iota(vertexIndex, vertexIndex + vertexCount, 0.0f);

GL::Buffer vertexIndices;
vertexIndices.setData(vertexIndex, GL::BufferUsage::StaticDraw);

mesh.addVertexBuffer(vertexIndices, 0, Shaders::MeshVisualizer::VertexIndex{});

Rendering setup:

Matrix4 transformationMatrix, projectionMatrix;

Shaders::MeshVisualizer shader{Shaders::MeshVisualizer::Flag::Wireframe|
                               Shaders::MeshVisualizer::Flag::NoGeometryShader};
shader.setColor(0x2f83cc_rgbf)
    .setWireframeColor(0xdcdcdc_rgbf)
    .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix);

mesh.draw(shader);

Wireframe visualization of indexed meshes without geometry shader

The vertices must be converted to non-indexed array. Mesh setup:

std::vector<UnsignedInt> indices{
    // ...
};
std::vector<Vector3> indexedPositions{
    // ...
};

/* De-indexing the position array */
GL::Buffer vertices;
vertices.setData(MeshTools::duplicate(indices, indexedPositions),
                 GL::BufferUsage::StaticDraw);

GL::Mesh mesh;
mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer::Position{});

Rendering setup the same as above.

Base classes

class Magnum::GL::AbstractShaderProgram
Base for shader program implementations.

Public types

enum class Flag: UnsignedByte { Wireframe = 1 << 0, NoGeometryShader = 1 << 1 }
Flag.
using Position = GL::Attribute<0, Vector3>
Vertex position.
using VertexIndex = GL::Attribute<3, Float>
Vertex index.
using Flags = Containers::EnumSet<Flag>
Flags.

Constructors, destructors, conversion operators

MeshVisualizer(Flags flags = {}) explicit
Constructor.
MeshVisualizer(NoCreateT) explicit noexcept
Construct without creating the underlying OpenGL object.

Public functions

auto setTransformationProjectionMatrix(const Matrix4& matrix) -> MeshVisualizer&
Set transformation and projection matrix.
auto setViewportSize(const Vector2& size) -> MeshVisualizer&
Set viewport size.
auto setColor(const Color4& color) -> MeshVisualizer&
Set base object color.
auto setWireframeColor(const Color4& color) -> MeshVisualizer&
Set wireframe color.
auto setWireframeWidth(Float width) -> MeshVisualizer&
Set wireframe width.
auto setSmoothness(Float smoothness) -> MeshVisualizer&
Set line smoothness.

Enum documentation

enum class Magnum::Shaders::MeshVisualizer::Flag: UnsignedByte

Flag.

Enumerators
Wireframe

Visualize wireframe. On OpenGL ES 2.0 this also enables Flag::NoGeometryShader.

NoGeometryShader

Don't use geometry shader for wireframe visualization. If enabled, you might need to provide also VertexIndex attribute in the mesh. In OpenGL ES enabled alongside Flag::Wireframe.

Typedef documentation

typedef GL::Attribute<0, Vector3> Magnum::Shaders::MeshVisualizer::Position

Vertex position.

Generic attribute, Vector3.

typedef GL::Attribute<3, Float> Magnum::Shaders::MeshVisualizer::VertexIndex

Vertex index.

Float, used only in OpenGL < 3.1 and OpenGL ES 2.0 if Flag::Wireframe is enabled. This attribute (modulo 3) specifies index of given vertex in triangle, i.e. 0.0f for first, 1.0f for second, 2.0f for third. In OpenGL 3.1, OpenGL ES 3.0 and newer this value is provided by the shader itself, so the attribute is not needed.

Function documentation

Magnum::Shaders::MeshVisualizer::MeshVisualizer(Flags flags = {}) explicit

Constructor.

Parameters
flags Flags

Magnum::Shaders::MeshVisualizer::MeshVisualizer(NoCreateT) explicit noexcept

Construct without creating the underlying OpenGL object.

The constructed instance is equivalent to moved-from state. Useful in cases where you will overwrite the instance later anyway. Move another object over it to make it useful.

This function can be safely used for constructing (and later destructing) objects even without any OpenGL context being active.

MeshVisualizer& Magnum::Shaders::MeshVisualizer::setTransformationProjectionMatrix(const Matrix4& matrix)

Set transformation and projection matrix.

Returns Reference to self (for method chaining)

MeshVisualizer& Magnum::Shaders::MeshVisualizer::setViewportSize(const Vector2& size)

Set viewport size.

Returns Reference to self (for method chaining)

Has effect only if Flag::Wireframe is enabled and geometry shaders are used.

MeshVisualizer& Magnum::Shaders::MeshVisualizer::setColor(const Color4& color)

Set base object color.

Returns Reference to self (for method chaining)

Initial value is fully opaque white.

MeshVisualizer& Magnum::Shaders::MeshVisualizer::setWireframeColor(const Color4& color)

Set wireframe color.

Returns Reference to self (for method chaining)

Initial value is fully opaque black. Has effect only if Flag::Wireframe is enabled.

MeshVisualizer& Magnum::Shaders::MeshVisualizer::setWireframeWidth(Float width)

Set wireframe width.

Returns Reference to self (for method chaining)

Initial value is 1.0f. Has effect only if Flag::Wireframe is enabled.

MeshVisualizer& Magnum::Shaders::MeshVisualizer::setSmoothness(Float smoothness)

Set line smoothness.

Returns Reference to self (for method chaining)

Initial value is 2.0f. Has effect only if Flag::Wireframe is enabled.