Magnum::GL::Mesh class

Mesh.

Mesh configuration

You have to specify at least primitive and vertex/index count using setPrimitive() and setCount(). Then fill your vertex buffers with data, add them to the mesh and specify shader attribute layout inside the buffers using addVertexBuffer(). You can also use MeshTools::interleave() to conveniently interleave vertex data.

If you want indexed mesh, fill your index buffer with data and specify its layout using setIndexBuffer(). You can also use MeshTools::compressIndices() to conveniently compress the indices based on the range used.

There is also MeshTools::compile() function which operates directly on Trade::MeshData2D / Trade::MeshData3D and returns fully configured mesh and vertex/index buffers for use with stock shaders.

Note that neither vertex buffers nor index buffer is managed (e.g. deleted on destruction) by the mesh, so you have to manage them on your own and ensure that they are available for whole mesh lifetime. On the other hand it allows you to use one buffer for more meshes (each mesh for example configured for different usage) or store data for more meshes in one buffer.

If vertex/index count or instance count is zero, the mesh is empty and no draw commands are issued when calling draw().

Example mesh configuration

Basic non-indexed mesh

/* Custom shader, needing only position data */
class MyShader: public GL::AbstractShaderProgram {
    public:
        typedef GL::Attribute<0, Vector3> Position;

    // ...
};

/* Fill vertex buffer with position data */
Vector3 positions[30]{
    // ...
};
GL::Buffer vertexBuffer;
vertexBuffer.setData(positions, GL::BufferUsage::StaticDraw);

/* Configure the mesh, add vertex buffer */
GL::Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles)
    .addVertexBuffer(vertexBuffer, 0, MyShader::Position{})
    .setCount(30);

Interleaved vertex data

/* Non-indexed primitive with positions and normals */
Trade::MeshData3D plane = Primitives::planeSolid();

/* Fill a vertex buffer with interleaved position and normal data */
GL::Buffer buffer;
buffer.setData(MeshTools::interleave(plane.positions(0), plane.normals(0)), GL::BufferUsage::StaticDraw);

/* Configure the mesh, add the vertex buffer */
GL::Mesh mesh;
mesh.setPrimitive(plane.primitive())
    .setCount(plane.positions(0).size())
    .addVertexBuffer(buffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{});

Indexed mesh

/* Custom shader */
class MyShader: public GL::AbstractShaderProgram {
    public:
        typedef GL::Attribute<0, Vector3> Position;

    // ...
};

/* Fill vertex buffer with position data */
Vector3 positions[240]{
    // ...
};
GL::Buffer vertexBuffer;
vertexBuffer.setData(positions, GL::BufferUsage::StaticDraw);

/* Fill index buffer with index data */
UnsignedByte indices[75]{
    // ...
};
GL::Buffer indexBuffer;
indexBuffer.setData(indices, GL::BufferUsage::StaticDraw);

/* Configure the mesh, add both vertex and index buffer */
GL::Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles)
    .setCount(75)
    .addVertexBuffer(vertexBuffer, 0, MyShader::Position{})
    .setIndexBuffer(indexBuffer, 0, GL::MeshIndexType::UnsignedByte, 176, 229);

Or using MeshTools::interleave() and MeshTools::compressIndices():

// Indexed primitive
Trade::MeshData3D cube = Primitives::cubeSolid();

// Fill vertex buffer with interleaved position and normal data
GL::Buffer vertexBuffer;
vertexBuffer.setData(MeshTools::interleave(cube.positions(0), cube.normals(0)), GL::BufferUsage::StaticDraw);

// Compress index data
Containers::Array<char> indexData;
MeshIndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(cube.indices());

// Fill index buffer
GL::Buffer indexBuffer;
indexBuffer.setData(indexData, GL::BufferUsage::StaticDraw);

// Configure the mesh, add both vertex and index buffer
GL::Mesh mesh;
mesh.setPrimitive(cube.primitive())
    .setCount(cube.indices().size())
    .addVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{})
    .setIndexBuffer(indexBuffer, 0, indexType, indexStart, indexEnd);

Or, if you plan to use the mesh with stock shaders, you can just use MeshTools::compile().

Specific formats of vertex data

// Custom shader with colors specified as four floating-point values
class MyShader: public GL::AbstractShaderProgram {
    public:
        typedef GL::Attribute<0, Vector3> Position;
        typedef GL::Attribute<1, Color4> Color;

    // ...
};

/* Initial mesh configuration */
GL::Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles)
    .setCount(30);

/* Fill position buffer with positions specified as two-component XY (i.e.,
   no Z component, which is meant to be always 0) */
Vector2 positions[30]{
    // ...
};
GL::Buffer positionBuffer;
positionBuffer.setData(positions, GL::BufferUsage::StaticDraw);

/* Specify layout of positions buffer -- only two components, unspecified Z
   component will be automatically set to 0 */
mesh.addVertexBuffer(positionBuffer, 0,
    MyShader::Position{MyShader::Position::Components::Two});

/* Fill color buffer with colors specified as four-byte BGRA (i.e., directly
   from a TGA file) */
UnsignedByte colors[4*30]{
    // ...
};
GL::Buffer colorBuffer;
colorBuffer.setData(colors, GL::BufferUsage::StaticDraw);

/* Specify color buffer layout -- BGRA, each component unsigned byte and we
   want to normalize them from [0, 255] to [0.0f, 1.0f] */
mesh.addVertexBuffer(colorBuffer, 0, MyShader::Color{
    MyShader::Color::Components::BGRA,
    MyShader::Color::DataType::UnsignedByte,
    MyShader::Color::DataOption::Normalized});

Dynamically specified attributes

In some cases, for example when the shader code is fully generated at runtime, it's not possible to know attribute locations and types at compile time. In that case, there are overloads of addVertexBuffer() and addVertexBufferInstanced() that take DynamicAttribute instead of Attribute typedefs. Adding a RGB attribute at location 3 normalized from unsigned byte to float with one byte padding at the end could then look like this:

mesh.addVertexBuffer(colorBuffer, 0, 4, GL::DynamicAttribute{
    GL::DynamicAttribute::Kind::GenericNormalized, 3,
    GL::DynamicAttribute::Components::Three,
    GL::DynamicAttribute::DataType::UnsignedByte});

Rendering meshes

Basic workflow is: bind specific framebuffer for drawing (if needed), set up respective shader (see AbstractShaderProgram documentation for more infromation) and call Mesh::draw().

WebGL restrictions

WebGL puts some restrictions on vertex buffer layout, see addVertexBuffer() documentation for details.

Performance optimizations

If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is supported, VAOs are used instead of binding the buffers and specifying vertex attribute pointers in each draw() call. The engine tracks currently bound VAO and currently active shader program to avoid unnecessary calls to glBindVertexArray() and glUseProgram(). Mesh limits and implementation-defined values (such as maxElementIndex()) are cached, so repeated queries don't result in repeated glGet() calls.

If EXT_direct_state_access desktop extension and VAOs are available, DSA functions are used for specifying attribute locations to avoid unnecessary calls to glBindBuffer() and glBindVertexArray(). See documentation of addVertexBuffer() for more information.

If index range is specified in setIndexBuffer(), range-based version of drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also draw() for more information.

Base classes

class AbstractObject
Base for all OpenGL objects.

Public types

using IndexType = Magnum::MeshIndexType deprecated
Index type.

Public static functions

static auto maxElementIndex() -> Long
Max supported index value.
static auto maxElementsIndices() -> Int
Max recommended index count.
static auto maxElementsVertices() -> Int
Max recommended vertex count.
static auto indexSize(Magnum::MeshIndexType type) -> std::size_t deprecated
Size of given mesh index type.
static auto wrap(GLuint id, MeshPrimitive primitive = MeshPrimitive::Triangles, ObjectFlags flags = {}) -> Mesh
Wrap existing OpenGL vertex array object.
static auto wrap(GLuint id, ObjectFlags flags) -> Mesh

Constructors, destructors, conversion operators

Mesh(MeshPrimitive primitive = MeshPrimitive::Triangles) explicit
Constructor.
Mesh(Magnum::MeshPrimitive primitive) explicit
Mesh(NoCreateT) explicit noexcept
Construct without creating the underlying OpenGL object.
Mesh(const Mesh&) deleted
Copying is not allowed.
Mesh(Mesh&& other) noexcept
Move constructor.
~Mesh()
Destructor.

Public functions

auto operator=(const Mesh&) -> Mesh& deleted
Copying is not allowed.
auto operator=(Mesh&& other) -> Mesh& noexcept
Move assignment.
auto id() const -> GLuint
OpenGL vertex array ID.
auto release() -> GLuint
Release OpenGL object.
auto label() -> std::string
Mesh label.
auto setLabel(const std::string& label) -> Mesh&
Set mesh label.
template<std::size_t size>
auto setLabel(const char(&label)[size]) -> Mesh&
auto isIndexed() const -> bool
Whether the mesh is indexed.
auto indexType() const -> MeshIndexType
Index type.
auto indexTypeSize() const -> UnsignedInt
Index type size.
auto indexSize() const -> std::size_t deprecated
Index size.
auto primitive() const -> MeshPrimitive
Primitive type.
auto setPrimitive(MeshPrimitive primitive) -> Mesh&
Set primitive type.
auto setPrimitive(Magnum::MeshPrimitive primitive) -> Mesh&
auto count() const -> Int
Vertex/index count.
auto setCount(Int count) -> Mesh&
Set vertex/index count.
auto baseVertex() const -> Int
Base vertex.
auto setBaseVertex(Int baseVertex) -> Mesh&
Set base vertex.
auto instanceCount() const -> Int
Instance count.
auto setInstanceCount(Int count) -> Mesh&
Set instance count.
auto baseInstance() const -> UnsignedInt
Base instance.
auto setBaseInstance(UnsignedInt baseInstance) -> Mesh&
Set base instance.
template<class ... T>
auto addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes) -> Mesh&
Add buffer with (interleaved) vertex attributes for use with given shader.
template<class ... T>
auto addVertexBufferInstanced(Buffer& buffer, UnsignedInt divisor, GLintptr offset, const T&... attributes) -> Mesh&
Add instanced vertex buffer.
auto addVertexBuffer(Buffer& buffer, GLintptr offset, GLsizei stride, const DynamicAttribute& attribute) -> Mesh&
Add buffer with dynamic vertex attributes for use with given shader.
auto addVertexBufferInstanced(Buffer& buffer, UnsignedInt divisor, GLintptr offset, GLsizei stride, const DynamicAttribute& attribute) -> Mesh&
Add buffer with dynamic vertex attributes for use with given shader.
auto setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type, UnsignedInt start, UnsignedInt end) -> Mesh&
Set index buffer.
auto setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type, UnsignedInt start, UnsignedInt end) -> Mesh&
auto setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type) -> Mesh&
Set index buffer.
auto setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type) -> Mesh&
void draw(AbstractShaderProgram& shader)
Draw the mesh.
void draw(AbstractShaderProgram&& shader)
void draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream = 0)
Draw the mesh with vertices coming out of transform feedback.
void draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream = 0)

Typedef documentation

typedef Magnum::MeshIndexType Magnum::GL::Mesh::IndexType

Index type.

Function documentation

static Long Magnum::GL::Mesh::maxElementIndex()

Max supported index value.

The result is cached, repeated queries don't result in repeated OpenGL calls. If extension ARB_ES3_compatibility (part of OpenGL 4.3) is not available, returns max representable 32-bit value (0xffffffffu).

static Int Magnum::GL::Mesh::maxElementsIndices()

Max recommended index count.

The result is cached, repeated queries don't result in repeated OpenGL calls.

static Int Magnum::GL::Mesh::maxElementsVertices()

Max recommended vertex count.

The result is cached, repeated queries don't result in repeated OpenGL calls.

static std::size_t Magnum::GL::Mesh::indexSize(Magnum::MeshIndexType type)

Size of given mesh index type.

static Mesh Magnum::GL::Mesh::wrap(GLuint id, MeshPrimitive primitive = MeshPrimitive::Triangles, ObjectFlags flags = {})

Wrap existing OpenGL vertex array object.

Parameters
id OpenGL vertex array ID
primitive Primitive type
flags Object creation flags

The id is expected to be of an existing OpenGL vertex array object. Unlike vertex array created using constructor, the OpenGL object is by default not deleted on destruction, use flags for different behavior.

static Mesh Magnum::GL::Mesh::wrap(GLuint id, ObjectFlags flags)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Magnum::GL::Mesh::Mesh(MeshPrimitive primitive = MeshPrimitive::Triangles) explicit

Constructor.

Parameters
primitive Primitive type

If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is available, vertex array object is created. If ARB_direct_state_access (part of OpenGL 4.5) is not available, the vertex array object is created on first use.

Magnum::GL::Mesh::Mesh(Magnum::MeshPrimitive primitive) explicit

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Magnum::GL::Mesh::Mesh(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.

Magnum::GL::Mesh::~Mesh()

Destructor.

If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is available, associated vertex array object is deleted.

GLuint Magnum::GL::Mesh::id() const

OpenGL vertex array ID.

If neither ARB_vertex_array_object (part of OpenGL 3.0) nor OpenGL ES 3.0 / WebGL 2.0 nor OES_vertex_array_object in OpenGL ES 2.0 / OES_vertex_array_object in WebGL 1.0 is available, returns 0.

GLuint Magnum::GL::Mesh::release()

Release OpenGL object.

Releases ownership of OpenGL vertex array object and returns its ID so it is not deleted on destruction. The internal state is then equivalent to moved-from state.

std::string Magnum::GL::Mesh::label()

Mesh label.

The result is not cached, repeated queries will result in repeated OpenGL calls. If OpenGL 4.3 / OpenGL ES 3.2 is not supported and neither KHR_debug (covered also by ANDROID_extension_pack_es31a) nor EXT_debug_label desktop or ES extension is available, this function returns empty string.

Mesh& Magnum::GL::Mesh::setLabel(const std::string& label)

Set mesh label.

Returns Reference to self (for method chaining)

Default is empty string. If OpenGL 4.3 / OpenGL ES 3.2 is not supported and neither KHR_debug (covered also by ANDROID_extension_pack_es31a) nor EXT_debug_label desktop or ES extension is available, this function does nothing.

template<std::size_t size>
Mesh& Magnum::GL::Mesh::setLabel(const char(&label)[size])

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool Magnum::GL::Mesh::isIndexed() const

Whether the mesh is indexed.

MeshIndexType Magnum::GL::Mesh::indexType() const

Index type.

Expects that the mesh is indexed.

UnsignedInt Magnum::GL::Mesh::indexTypeSize() const

Index type size.

Expects that the mesh is indexed.

std::size_t Magnum::GL::Mesh::indexSize() const

Index size.

Mesh& Magnum::GL::Mesh::setPrimitive(MeshPrimitive primitive)

Set primitive type.

Returns Reference to self (for method chaining)

Default is MeshPrimitive::Triangles.

Mesh& Magnum::GL::Mesh::setPrimitive(Magnum::MeshPrimitive primitive)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Mesh& Magnum::GL::Mesh::setCount(Int count)

Set vertex/index count.

Returns Reference to self (for method chaining)

If the mesh is indexed, the value is treated as index count, otherwise the value is vertex count. If set to 0, no draw commands are issued when calling draw(AbstractShaderProgram&). Ignored when calling draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). Default is 0.

Mesh& Magnum::GL::Mesh::setBaseVertex(Int baseVertex)

Set base vertex.

Returns Reference to self (for method chaining)

Sets number of vertices of which the vertex buffer will be offset when drawing. Ignored when calling draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). Default is 0.

Mesh& Magnum::GL::Mesh::setInstanceCount(Int count)

Set instance count.

Returns Reference to self (for method chaining)

If set to 1, non-instanced draw commands are issued when calling draw(AbstractShaderProgram&) or draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). If set to 0, no draw commands are issued at all. Default is 1.

Mesh& Magnum::GL::Mesh::setBaseInstance(UnsignedInt baseInstance)

Set base instance.

Returns Reference to self (for method chaining)

Ignored when calling draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). Default is 0.

template<class ... T>
Mesh& Magnum::GL::Mesh::addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes)

Add buffer with (interleaved) vertex attributes for use with given shader.

Returns Reference to self (for method chaining)

Parameter offset is offset of the array from the beginning, attribute list is combination of attribute definitions (specified in implementation of given shader) and offsets between interleaved attributes.

See class documentation for simple usage example. For more involved example imagine that you have a buffer with 76 bytes of some other data at the beginning (possibly material configuration) and then the interleaved vertex array. Each vertex consists of a weight, position, texture coordinate and a normal. You want to draw it with Shaders::Phong, but it accepts only a position and a normal, so you have to skip the weight and the texture coordinate in each vertex:

GL::Buffer buffer;
GL::Mesh mesh;
mesh.addVertexBuffer(buffer, 76,    /* initial array offset */
    4,                              /* skip vertex weight (Float) */
    Shaders::Phong::Position(),     /* vertex position */
    8,                              /* skip texture coordinates (Vector2) */
    Shaders::Phong::Normal());      /* vertex normal */

You can also achieve the same effect by calling addVertexBuffer() more times with explicitly specified gaps before and after the attributes. This can be used for e.g. runtime-dependent configuration, as it isn't dependent on the variadic template:

mesh.addVertexBuffer(buffer, 76, 4, Shaders::Phong::Position{}, 20)
    .addVertexBuffer(buffer, 76, 24, Shaders::Phong::Normal{}, 0);

If specifying more than one attribute, the function assumes that the array is interleaved. Adding non-interleaved vertex buffer can be done by specifying one attribute at a time with specific offset. Above example with weight, position, texture coordinate and normal arrays one after another (non-interleaved):

Int vertexCount = 352;
mesh.addVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::Phong::Position{})
    .addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::Phong::Normal{});

If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is available, the vertex array object is used to hold the parameters.

template<class ... T>
Mesh& Magnum::GL::Mesh::addVertexBufferInstanced(Buffer& buffer, UnsignedInt divisor, GLintptr offset, const T&... attributes)

Add instanced vertex buffer.

Returns Reference to self (for method chaining)

Similar to the above function, the divisor parameter specifies number of instances that will pass until new data are fetched from the buffer. Setting it to 0 is equivalent to calling addVertexBuffer().

If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is available, the vertex array object is used to hold the parameters.

Mesh& Magnum::GL::Mesh::addVertexBuffer(Buffer& buffer, GLintptr offset, GLsizei stride, const DynamicAttribute& attribute)

Add buffer with dynamic vertex attributes for use with given shader.

Returns Reference to self (for method chaining)

Equivalent to addVertexBuffer(Buffer&, GLintptr, const T&... attributes) but with the possibility to fully specify the attribute properties at runtime, including base type and location. See class documentation for usage example.

Mesh& Magnum::GL::Mesh::addVertexBufferInstanced(Buffer& buffer, UnsignedInt divisor, GLintptr offset, GLsizei stride, const DynamicAttribute& attribute)

Add buffer with dynamic vertex attributes for use with given shader.

Returns Reference to self (for method chaining)

Equivalent to addVertexBufferInstanced(Buffer&, UnsignedInt, GLintptr, const T&... attributes) but with the possibility to fully specify the attribute properties at runtime, including base type and location. See class documentation for usage example.

Mesh& Magnum::GL::Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type, UnsignedInt start, UnsignedInt end)

Set index buffer.

Parameters
buffer Index buffer
offset Offset into the buffer
type Index data type
start Minimum array index contained in the buffer
end Maximum array index contained in the buffer
Returns Reference to self (for method chaining)

The smaller range is specified with start and end the less memory operations are needed (and possibly some optimizations), improving draw performance. Specifying 0 for both parameters behaves the same as setIndexBuffer(Buffer&, GLintptr, MeshIndexType). On OpenGL ES 2.0 this function behaves always as setIndexBuffer(Buffer&, GLintptr, MeshIndexType), as this functionality is not available there.

If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is available, the vertex array object is used to hold the parameters.

Ignored when calling draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt).

Mesh& Magnum::GL::Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type, UnsignedInt start, UnsignedInt end)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Mesh& Magnum::GL::Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type)

Set index buffer.

Parameters
buffer Index buffer
offset Offset into the buffer
type Index data type
Returns Reference to self (for method chaining)

Alternative to setIndexBuffer(Buffer&, GLintptr, MeshIndexType, UnsignedInt, UnsignedInt) with unspecified index limits, see its documentation for more information. Prefer to set index limits for better performance.

Mesh& Magnum::GL::Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::GL::Mesh::draw(AbstractShaderProgram& shader)

Draw the mesh.

Parameters
shader Shader to use for drawing

Expects that the shader is compatible with this mesh and is fully set up. If vertex/index count or instance count is 0, no draw commands are issued. See also AbstractShaderProgram documentation for more information. If ARB_vertex_array_object (part of OpenGL 3.0), OpenGL ES 3.0, WebGL 2.0, OES_vertex_array_object in OpenGL ES 2.0 or OES_vertex_array_object in WebGL 1.0 is available, the associated vertex array object is bound instead of setting up the mesh from scratch.

void Magnum::GL::Mesh::draw(AbstractShaderProgram&& shader)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void Magnum::GL::Mesh::draw(AbstractShaderProgram& shader, TransformFeedback& xfb, UnsignedInt stream = 0)

Draw the mesh with vertices coming out of transform feedback.

Parameters
shader Shader to use for drawing
xfb Transform feedback to use for vertex count
stream Transform feedback stream ID

Expects that the shader is compatible with this mesh, is fully set up and that the output buffer(s) from xfb are used as vertex buffers in this mesh. Everything set by setCount(), setBaseInstance(), setBaseVertex() and setIndexBuffer() is ignored, the mesh is drawn as non-indexed and the vertex count is taken from the xfb object. If stream is 0, non-stream draw command is used. If ARB_vertex_array_object (part of OpenGL 3.0) is available, the associated vertex array object is bound instead of setting up the mesh from scratch.

void Magnum::GL::Mesh::draw(AbstractShaderProgram&& shader, TransformFeedback& xfb, UnsignedInt stream = 0)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.