Behavior of a non enabled vertex attribute

Hi all,

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 );
       Color = Diffuse;
    gl_Position = MVP_Matrix * VertexPosition;

Why it works with Nvidia and not with AMD.



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.

Hi all, thanks for the replies.

Could you please explain to me what means ‘location zero’ and how could I assign it to an attribute ?.

The object painted with this shader wasn’t visualized, no glError. Other objects with different shaders are painted as usual.

No, I expect nothing from the attribute, because when it is disabled, I set VertexColorMix to zero, so that I don’t use VertexColor at all.

For instance:

  glBindAttribLocation( pgm_handle, 0, "my_attribute_0" );

Vertex attributes are a limited resource, and they are indexed by attribute locations 0…(N-1).

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