Spec. clarification: gl_VertexID, is the generation by glDrawElements optional?

The Specification defines:

gl_VertexID is a vertex language input variable that holds an integer index for the vertex. The index is impliclty generated by glDrawArrays and other commands that do not reference the content of the GL_ELEMENT_ARRAY_BUFFER,

or explicitly generated from the content of the GL_ELEMENT_ARRAY_BUFFER by commands such as glDrawElements.

I would like to know, if the “or” part of the specification is optional. Since this is ignored by a server released few days ago. Also I would like to know if re-indexing with random ordering is allowed e.g:

index[SUB]x[/SUB] < index[SUB]y[/SUB] => gl_VertexID[SUB]x[/SUB] > gl_VertexID[SUB]y[/SUB] == true

The “or” there is not optional. glDrawArrays uses implicit indices, because they don’t read them from an index array. glDrawElements uses explicit indices, taken from the index array. So if you use non-indexed rendering functions, the index is implicitly generated. If you use indexed rendering functions, then the index will be taken from the index array.

Since this is ignored by a server released few days ago.

What “server” are you referring to?

indexx < indexy => gl_VertexIDx > gl_VertexIDy == true

I’m not sure what this equation could possibly mean.

I think the OP wants to know whether gl_VertexID of vertex x could still be larger than gl_VertexID of vertex y even though the index of x is smaller than the index of y after indices have been somehow rearranged. The answer would be: no, this implication does not hold. (EDIT: And I’m not sure if this implication is even correct logically speaking.)

So my understanding is correct:

It is not allowed to use the index from the vertex-array if an index-array is assigned.

Thanks.

The second part of my question is unclear but already answered. (=> := implication)

I was wandering if only an offset is allowed.

For example:
(x, x+1, x+2 …) could be mapped to (x+10, x+20, x+21…)

or a random re-ordering is allowed:

(x, x+1, x+2 …) could be mapped to (x+10, x-15, x+20…)

That statement doesn’t make any sense. O_o You don’t use indices from a vertex buffer - you use the vertex attributes stored in it’s data store. And index arrays (or buffers or whatever you want to call it) aren’t assigned, they are sourced during vertex submission with glDrawElements*() calls if a non-zero element array buffer is bound and reference one unique set of attributes per index. The value of gl_VertexID may be very different for the same set of vertex data depending on whether you source it with indices(DrawElements*) or directly (DrawArrays*). That’s it.

I was wandering if only an offset is allowed.

For example:
(x, x+1, x+2 …) could be mapped to (x+10, x+20, x+21…)

or a random re-ordering is allowed:

(x, x+1, x+2 …) could be mapped to (x+10, x-15, x+20…)

You can’t do that with a draw call. The only offset you can add to indices is the so called base vertex which is constant, however.

Please help me to understand:

If I have a vbo: (p0, p1, p2, p3)

And an IBO with indices
(
0, 2, 1, // triangle one
2, 3, 0 // triangle two
)

OpenGL Server A creates:

gl_VertexID == 0 for p0
gl_VertexID == 1 for p1
gl_VertexID == 2 for p2
gl_VertexID == 3 for p3

and OpenGL Server B creates:

gl_VertexID == 0, 5 for p0
gl_VertexID == 2 for p1
gl_VertexID == 1,3 for p2
gl_VertexID == 4 for p3

Which one is correct?

They both are - please clarify what “server” means in this context!

The first case is simply drawing two triangles using indices. Therefore the vertex ID is equal to the index and the vertex buffer is layed out like this: [p0, p1, p2, p3].

The second uses a DrawArrays* call, since the vertices of both triangles are stored sequentially you get IDs in the range [0, 5]. Just look at the sequence of indices. You need p0, p2, p1 and then p2, p3, p0. The buffer is layed out exactly like this: [p0, p2, p1, p2, p3, p0] which maps to IDs [0, 1, 2, 3, 4, 5]. Everything zero-based of course!

See it now?

Server A is correct, according to the spec.

They both are

He’s drawing with glDrawElements both times.

Server A is correct, according to the spec. He’s drawing with glDrawElements both times.

If he is drawing both times with DrawElements then yes. However, the second sequence is correct for glDrawArrays. Who would implement it like that? I guess “server” means implementation so it would be nice to know what’s actually in play here.

I’m using the term OpenGL server as synonym for the graphics driver. It is more or less the same binary but the GPUs are very different (several generations difference 5xxx - 7xxx).

Since I adressed an index buffer object, I was referring to a drawElements call (with an ELEMENT_ARRAY_BUFFER or index buffer object) and not a drawArray call.
(Server A is correct.)

I’m using this index to reference several attributes from a TPO (skeletal, softbody). The new hardware creates “inexplicable” results.
My statement above was mistakable, but I don’t want to change it because of the other replies.

Are we talking Radeons or GeForces here? 5xxx and 7xxx are ambigous.

Radeon HD5700 OK
Radeon HD6600 OK (But different OS and driver)
Radeon HD7970 Not OK

Got some source code? I have a 7970 on my current machine and I’d like to test this if possible.

Radeon HD5700 OK
Radeon HD6600 OK (But different OS and driver)
Radeon HD7970 Not OK

At first I was going to say that that’s surprising. But then I remembered that the HD-7xxx line uses very different hardware from the HD-6600. So this seems very much like a driver bug.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.