The following code works fine in Nvidia, but fail with AMD when VertexColorMix is equal to 0 and the vertex attribute of color (glDisableVertexAttribArray) is disabled.
#version 330
uniform mat4 MVP_Matrix;
uniform vec3 Diffuse;
uniform float VertexColorMix;
in vec4 VertexPosition;
in vec3 VertexColor;
out vec3 Color;
void main()
{
if (VertexColorMix > 0 )
Color = mix ( Diffuse, VertexColor, VertexColorMix );
else
Color = Diffuse;
gl_Position = MVP_Matrix * VertexPosition;
}
Why it works with Nvidia and not with AMD.
Thanks,
Carlos.
PS. If I declare the attributes using layout, it works in Amd too:
layout(location = 0) in vec4 VertexPosition;
layout(location = 3) in vec3 VertexColor;
AMD alphabetizes their vertex attributes when assigning vertex attribute locations, while Nvidia assigns them in the order they are declared in the shader. In the Compatibility profile, you must have attribute location zero enabled. This is why AMD failed - VertexColor was assigned location zero and it was disabled.
If you are going to disable some attributes, it is a good idea to explicitly assign them locations to avoid this problem. Always assign location zero to an attribute that will not be disabled. Note that is is not a problem in the Core profile - attribute zero can be disabled.
How does it fail? Error message, incorrect drawing, …?
Are you expecting VertexColor to be (0,0,0) when the attribute is disabled, because that’s not necessarily true. If a vertex attribute is disabled, then OpenGL uses the current value for that attribute. The current value for an attribute can be set using for example: glVertexAttrib3f(index, 0.5f, 0.5f, 0.5f)
Prior to OpenGL 4.1 the current value of an attribute was indeterminate after a draw call was made if the corresponding array was enabled, so you’d have to reset it each time you then wanted to use it as a default value for a disabled attribute array in a shader. I’ve seen implementations leave the current value for correspondingly enabled attribute arrays untouched by draw calls + other implementations change the current value to the value of the last item in the attribute array.
Since OpenGL 4.1, draw calls must leave the current values untouched.