Hi,
I’m struggling trying to correctly implement a custom draw_ID for glMultiDrawElementsIndirect.
I’m actually succeeding a first time, everything displays correctly.
But when I modify my scene, I produce a new buffer of commands together with new draw_IDs, and this time the draw_IDs do not seem to be correct. When I print them with shaderprinter, many draw_IDs are 0, even though I checked that the values I sent are not 0.
I tried with both a dedicated draw_id buffer, or through the baseInstance field of the commands, to no avail.
A note: the first time, the draw_IDs are an incremental sequence (0, 1, 2… max). And I call glMultiDrawElementsIndirect with ‘max’ as the number of commands.
The second time, the draw_IDs are much more randoms, as they access newly created objects (I keep the not-rendered-anymore data such as vertices in various buffers).
This is the setup code:
glGenBuffers( 1, &_commands_bo ); CHKGL;
glBindBuffer( GL_DRAW_INDIRECT_BUFFER, _commands_bo ); CHKGL;
glBufferData( GL_DRAW_INDIRECT_BUFFER, sizeof(gl2d::draw_cmd_t) * w->_commands_num, nullptr, GL_DYNAMIC_DRAW ); CHKGL;
//feed the draw id to the shader.
#if USE_DRAW_ID_BUFFER
glGenBuffers( 1, &_draw_id_bo ); CHKGL;
glBindBuffer( GL_ARRAY_BUFFER, _draw_id_bo ); CHKGL;
glBufferData( GL_ARRAY_BUFFER, sizeof(GLuint) * w->_commands_num, nullptr, GL_DYNAMIC_DRAW ); CHKGL;
glVertexAttribIPointer(w->draw_id_loc, 1, GL_UNSIGNED_INT, 0, (GLvoid*)0 ); CHKGL;
#else
glBindBuffer(GL_ARRAY_BUFFER, _commands_bo); CHKGL;
glVertexAttribIPointer(
w->draw_id_loc,
1,
GL_UNSIGNED_INT,
sizeof(gl2d::draw_cmd_t),
(void*)(offsetof(gl2d::draw_cmd_t, baseInstance))); CHKGL;
#endif
glEnableVertexAttribArray(w->draw_id_loc); CHKGL;
glVertexAttribDivisor(w->draw_id_loc, 1); CHKGL; //only once per instance
and the rendering:
glBindBuffer( GL_DRAW_INDIRECT_BUFFER, _cur_bos->_commands_bo ); CHKGL;
_cur_bos->_commands_map = glMapBufferRange (GL_DRAW_INDIRECT_BUFFER, 0, _commands_num * sizeof(gl2d::draw_cmd_t), MAP_OPTIONS ); CHKGL;
assert (_cur_bos->_commands_map);
_cmd_it = _commands;
draw_children (parent);
_commands_size = _cmd_it - _commands;
memcpy ( (char*) (_cur_bos->_commands_map), _commands, sizeof(gl2d::draw_cmd_t) * _commands_size);
#if GL2D_USE_DRAW_ID_BUFFER
glBindBuffer( GL_ARRAY_BUFFER, _cur_bos->_draw_id_bo ); CHKGL;
GLuint* draw_id_map = (GLuint*) glMapBufferRange (GL_ARRAY_BUFFER, 0, _commands_num * sizeof(GLuint), MAP_OPTIONS ); CHKGL;
assert (draw_id_map);
for (size_t i=0; i<_commands_size;++i) {
draw_id_map[i] = _commands[i].baseInstance;
//commands[i].baseInstance = 0;
}
assert (glUnmapBuffer (GL_ARRAY_BUFFER)); CHKGL;
#endif
glBindBuffer( GL_DRAW_INDIRECT_BUFFER, _cur_bos->_commands_bo ); CHKGL;
glMultiDrawElementsIndirect (GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, nullptr, _commands_size, 0); CHKGL;