I have a really tough time coming up with a good title for this question, so please propose a new one if you can come up with a good one. Perhaps we can do it after solving my problem... Now to it:
I am currently porting code to use glMultiDrawElements instead of several calls to glDrawElements. For this, I am using something I call sequenceList, which is just a std::pair of two vectors, one unsigned int and one int.
// Sequence of vectors defining < StartIndex per primitive, Number of vertices per primitive >
using SequenceList = std::pair< std::vector< unsigned int >, std::vector< GLsizei > >;
To be able to use only one draw function for all variants (ever though there is just one primitive to draw using one index list) I've generalized the function call to always use a sequenceList object, but with only one index value. This means that I use glMultiDrawElements for all indexed draw calls (and glMultiDrawArrays for non-indexed draw calls).
void GLVBOProbe::draw( unsigned startIndex, int numberOfIndicesToDraw ) const
{
VertexArray::SequenceList sequences = { { startIndex }, { numberOfIndicesToDraw } ) };
GLVBOLib::the().draw( name_, sequences );
}
The draw call then binds the array/normal/texture and index (if needed) buffers. The call to glMultiDrawElements then looks like
glMultiDrawElements( info.mode, sequences.second.data(), GL_UNSIGNED_INT, (const GLvoid **)sequences.first.data(), (GLsizei)sequences.second.size() );
In my test case, I am rendering 75000 indices starting at 0. So the sequences.second contains 75000 values, and sequences.first contains only one value: 0.
Now to the problem: This crashes with a
First-chance exception at 0x000000004735E56B in Application.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
I have tried to find the problem in many different ways, and have finally been able to find a variant that doesn't crash, and the variant baffles me.
If I copy the vector to a new local variable, it works. Since the vector is of size 1, it wouldn't be a problem to just to that, but it feels less fun to do it every frame for 3000 index offsets.
// Non crashing version
std::vector< unsigned int > indicesOffset = sequences.first;
// using sequence and indices
glMultiDrawElements( info.mode, sequences.second.data(), GL_UNSIGNED_INT, (const GLvoid **)indicesOffset.data(), (GLsizei)sequences.second.size() );
A colleague of mine says it might have to do with the memory alignment of the vector, saying I have to use boost's boost::aligned_allocator to get it to work.