How does glMultiDrawElementsIndirect *indirect parameter works?


I am trying understand how glMultDrawElementsIndirect ‘indirect’ parameter works. I have searched all over the internet, and I stumbled across this document:, page 370(10.3.10).

Well, I have already drawn with this command using the indirect parameter as the offset, binding the GL_DRAW_INDIRECT_BUFFER, and then calling the glMultiDrawElementsIndirect with NULL into the parameter. I have been studying the apitest from NVidia AZDO presentation, and there is a solution (TexturedQuads - texturearraymultidraw.cpp) where they use the glMultiDrawElementsIndirect to render, passing the pointer to the data and not binding the GL_DRAW_INDIRECT_BUFFER. In their tests, this performed better then with the buffer, but I could not reproduce this usage in my code. I keep getting GL_INVALID_OPERATION error after the glMultiDrawElementsIndirect call. The vao is bound, there is a GL_ELEMENT_ARRAY_BUFFER created under the vao. I have no clue why I cant get it to work.

Below is my pseudo code:

typedef struct
    GLuint count;
    GLuint instanceCount;
    GLuint firstIndex;
    GLuint baseVertex;
    GLuint baseInstance;

mdiCmd* _mdiCmdBuffer = new mdiCmd[_objectCount];

for (uint i = 0; i < _objectCount; i++)
        _mdiCmdBuffer[i].count = indexCount;
        _mdiCmdBuffer[i].instanceCount = _instanceCount;
        _mdiCmdBuffer[i].firstIndex = 0;
        _mdiCmdBuffer[i].baseVertex = i * vertexCount;
        _mdiCmdBuffer[i].baseInstance = i * _instanceCount;

glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)_mdiCmdBuffer, _objectCount, 0);

The document I have linked, says

If zero is bound to DRAW_INDIRECT_BUFFER, the corresponding
DrawIndirect commands instead source their arguments directly from the indirect
pointer in client memory

Am I missing something?


Are you using a core profile context? Sourcing the control structures from client memory rather than GL_DRAW_INDIRECT_BUFFER is only allowed in the compatibility profile.

Thank you! You are right! Their example only works in compat profile. The core profile doesnt let you use the buffer from client memory.