PDA

View Full Version : glVertexAttrib* ignored on AMD



heberle
12-07-2012, 09:39 AM
In programs I write using strictly forward compatible, core profiles (and typically 4.2), I have noticed that per-vertex attributes specified using glVertexAttrib* seem to be ignored on devices with an AMD card, while they work exactly as expected on NVIDIA devices. On both, I disable the corresponding per-vertex attribute array and then specify the fixed attribute I want with glVertexAttrib*. But on AMD, it seems to just use the last attribute specified with a real per-vertex attribute array and ignores the one set with glvertexAttrib. Is this a known problem? Is there a workaround or planned fix?

thokra
12-07-2012, 09:45 AM
Are you talking about the glVertexAttrib{1,2,3,4}* family of functions or the glVertexAttribPointer* family of functions?

Edit: Duh, should have read it better.

So you basically do something like



// assuming a vec4 attrib here
glDisableVertexAttribArray(index);
glVertexAttrib4f(index, x, y, z, 1.0);


and you expect the shader variable associated with index to assume the fixed value. Is that correct?

heberle
12-07-2012, 10:47 AM
Yes, that is correct. I re-read the OpenGL spec, and it suggests that that is exactly how should work. And it does on NVIDIA.

Dan Bartlett
12-07-2012, 11:13 AM
This behaviour is only guaranteed on recent OpenGL versions. Prior to OpenGL 4.1 implementors were free to leave the current value of an attribute corresponding to an enabled attribute array at any value after a draw call, so after this code:

glVertexAttrib4f(index, ...);
glEnableVertexAttribArray(index, ...);
glVertexAttribPointer(index, ...);
glDrawElements(...);

the vertex attrib could be any value, so you would need to reset it:

glDisableVertexAttribArray(index);
glVertexAttrib4f(index, ...);
glDrawElements(...);

From OpenGL 4.1 onwards the draw call can't affect it, so you can just use:


glVertexAttrib4f(index, ...);
glEnableVertexAttribArray(index, ...);
glVertexAttribPointer(index, ...);
glDrawElements(...);

// note: no glVertexAttrib4f required here
glDisableVertexAttribArray(index);
glDrawElements(...);

heberle
12-07-2012, 11:48 AM
Thank you both for your quick replies. Unfortunately I think I am doing it as you suggest. I am running using OpenGL 4.2. So for example if I have a large number of vertices for a triangle strip, all of which are in the same plane, I want to specify the plane normal once and render as:
glDisableVertexAttribArray(normalVectorIndex);
glVertexAttrib3f(normalVectorIndex, fixedNormalDx, fixedNormalDy, fixedNormalDz);
glDrawArrays(GL_TRIANGLE_STRIP, 0, numPoints);

I get exactly the results I expect on NVIDIA platforms; on AMD platforms, the glVertexAttrib3f call seems to have no effect.

thokra
12-07-2012, 11:58 AM
Well it may always be a driver bug. If you'r 100% sure you're doing it right, file a bug with AMD.