glDrawElements of GL_TRIANGLES with a stride for indices, not vertices?

Hi,

I’m generating a VBO and EBO from a compute shader, after which I’m issuing a call to glDrawElements. Every vertex data is aligned on a 16-byte boundary making it convenient for the compute program to operate.

However, my triangle indices do not follow a 16-byte alignment. Each vertex index is 4 byte, with 3 indices per triangle this gives a 12-byte boundary. Is there an extension to glDrawElements that provides a stride for vertex indices?

Thanks and happy new year to everybody,

Fred

I don’t see why you need one. A compute shader is perfectly capable of writing to a GL_R32UI image via image load/store. Just write 3 separate values.

It’s a bit more effort to write a batch of 3 indices on a 12-byte boundary than it is on a 16-byte (ie. vec4) boundary.

Unless you’ve benchmarked it and found that the “more effort” translates directly into lower performance, I’d just do it. Especially since you don’t have an alternative; you can’t have a primitive stride in your index array.

Though since you’re using triangles, I supposed you could use primitive restart and just write the restart index into the 4th component.

Do you mean the following:

triangle1_vertex_index1
triangle1_vertex_index2
triangle1_vertex_index3
dummy
triangle2_vertex_index1
triangle2_vertex_index2
triangle2_vertex_index3
dummy
and so on

glPrimitiveRestartIndex(3);
glDrawElements(GL_TRIANGLES, number_of_triangles / 4, …);

This seems to be a nice idea, thank you.

Right now, since I’m only generating triangle strips (in fact) with 4 vertices, I’m generating GL_QUADs instead. Nvidia’s implementation does not seem to require that the 4 vertices be coplanar. This is very bad I know.

The primitive restart is an index, a value that you write into the list of indices. It’s not a “skip every X indices” parameter. So you have:


triangle1_vertex_index1
triangle1_vertex_index2
triangle1_vertex_index3
0xFFFFFFFF
triangle2_vertex_index1
triangle2_vertex_index2
triangle2_vertex_index3
0xFFFFFFFF
...


glPrimitiveRestartIndex(0xFFFFFFFF);
glEnable(GL_PRIMITIVE_RESTART);
glDrawElements(GL_TRIANGLES, number_of_triangles * 4, ...); 

Also, since you’re in a compute shader, you should probably be doing indirect rendering. Use an imageBuffer or atomic counter to write the number of elements you need to render, then use glDrawIndirect.

Nvidia’s implementation does not seem to require that the 4 vertices be coplanar.

Nobody’s implementation requires that the vertices are coplanar. However, the results you get when you do so are undefined.

Thanks again for your suggestion of using primitive restart. This is quite interesting.
I have read the spec and I am not sure I can specify multiple consecutive restart indices, eg.

triangle1_vertex_index1
triangle1_vertex_index2
triangle1_vertex_index3
0xFFFFFFFF
0xFFFFFFFF
0xFFFFFFFF <-- I output 3 values here, just as an example
triangle2_vertex_index1
triangle2_vertex_index2
triangle2_vertex_index3
0xFFFFFFFF

It seems to work and it seems to me that it is supported by the spec.
Not 100% sure though! Any idea?

I’m interested in this feature as on the paper it allows me to delete selected triangles in a buffer, without having to pack/condense the buffer after my deletions (and with no real noticeable performance penalty I think).

Regards,
Fred

Why are you not sure you can specify multiple restart indices consecutively? It’s not a good idea generally, but it does function. The restart index simply ends the current primitive, such that the next index would be taken as the beginning of a new glDrawElements* call.

Primitives can be zero length. It isn’t an error to call glDrawElements* with zero indices.