Originally posted by bgl:
Cass: I meant not the static (per invocation)
attributes, but the per-vertex data arrays.
The spec says that changing the value of
argument 0 provokes the program, but the
wording about when the other vertex data is
updated is loose enough that a conforming
but broken implementation could conceivably
update argument 0 FIRST, and then the other
arguments out of the argument arrays, resulting
in early provocation. I’m sure nobody in their
right mind would actually design hardware or
a driver that did that, but it seems like a
hole nevertheless.
bgl, I’m not sure what problem you see with the wording. The only possible problem would occur in immediate mode, as calls to glDrawArrays, glDrawElements or even glArrayElement inherently keep things “in sync”. So, in immediate mode, there’s always the concept of “current data”, whether that applies to vertex, normal, color, texcoord or whatever. You make a call to glColor3fv, it sets the current color. You make a call to glNormal3fv, it sets the current normal, and so on. Same goes for the vertex attributes. You call glVertexAttrib3fNV(1, 1., 1., 1.) and it merely sets the current value for the index 1 vertex attribute, with no invocation of the vertex program. In fact, it’ll do this even if the vertex program mode is disabled. Everything “syncs” when a glVertex call is made (like glVertex3fv) or when a glVertexAttrib call is made with an index of 0. Then, the vertex program is invoked (assuming the vertex program mode is enabled, a valid program is bound, etc.) with the “current” vertex attributes used for arguments.
When using vertex programs with immediate mode (which, BTW, is ill-advised for performance purposes), always call the index 0 vertex attribute last, like so:
glBegin(GL_TRIANGLES);
glVertexAttrib3fv(1, u[0]);
glVertexAttrib3fv(0, v[0]);
glVertexAttrib3fv(1, u[1]);
glVertexAttrib3fv(0, v[1]);
glVertexAttrib3fv(1, u[2]);
glVertexAttrib3fv(0, v[2]);
glEnd();
It may look backwards, but that’s the only way it’ll work correctly.