DrawingGL 4.0

glDrawArraysIndirect

glDrawArrays whose counts are read from a GPU buffer, so a shader can decide how much to draw.

Signature

void glDrawArraysIndirect(GLenum mode, const void *indirect);

How it works

Instead of passing count and instance count as arguments, you put them in a buffer bound to GL_DRAW_INDIRECT_BUFFER:

struct { GLuint count, instanceCount, first, baseInstance; };

The point is who writes them. A compute shader that simulates particles knows how many are alive; it writes that number into the command, and the draw uses it without the CPU ever reading it back (which would stall).

Parameters

modeGLenum

Primitive type.

indirectconst void *

Byte offset of the command inside the GL_DRAW_INDIRECT_BUFFER, cast to a pointer.

Tips & pitfalls

  • Between the compute dispatch and the draw, call glMemoryBarrier(GL_COMMAND_BARRIER_BIT) so the draw sees the new counts.

Errors

When the call is invalid it does nothing and sets an error, which glGetError returns:

GL_INVALID_OPERATION
No buffer bound to GL_DRAW_INDIRECT_BUFFER, or the command goes past its end.

Example

example.cpp
1glDispatchCompute(groups, 1, 1);               // writes alive count into cmdBuffer
2glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
3glBindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBuffer);
4glDrawArraysIndirect(GL_POINTS, nullptr);
Official Khronos documentation