12

I'm assuming this will be one of those things that is "undefined", but I can't seem to find a concrete answer from google.

Let's say in my vertex shader I have:

layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec4 vColour;

But there is nothing buffered to location 2 with glEnableVertexAttribArray() or glVertexAttribPointer(). Can I expect the value to be anything particular?

I was assuming for a vec4 that it would be along the lines of {0,0,0,0}, {0,0,0,1} or {1,1,1,1}, but in my case it is {0,0,1,1}.

When I previously used glBindAttribLocation() to specify the locations, it defaulted to {1,1,1,1} on 4 different machines using 3 different operating systems (ubuntu 12.04, windows 7, and ubuntu 10.04).

Is it safe to assume the value will be {0,0,1,1} across machines? or was this simply a coincidence?

Cœur
  • 32,421
  • 21
  • 173
  • 232
kbirk
  • 3,687
  • 5
  • 38
  • 66

2 Answers2

14

Can I expect the value to be anything particular?

Yes, it is a particular value.

Assuming that you correctly turned off the attribute array (ie: with glDisableVertexAttribArray on that attribute index), the value you get comes from the in-context vertex attribute, as set by the glVertexAttrib suite of functions. These are global context state, not stored within the VAO.

By default, they all start at (0, 0, 0, 1). However, if you have rendered with a particular attribute using an array in that attribute index, the context value is effectively destroyed. So you should reset the context value if you want to use it.

Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829
  • So i have set glDisableVertexAttribArray() for the particular location number, but it still is read in the shader as {0,0,1,1}. I'm using a VAO, so I only make the call once. Should I disable them right before I my glDrawElements() call instead? – kbirk Jul 23 '13 at 19:56
  • @Pondwater: If the VAO disables it, then it's disabled. You don't have to disable it again. Also, I made an addendum to the answer. – Nicol Bolas Jul 23 '13 at 19:58
  • Ahh that makes sense! Thank you for the clarification! – kbirk Jul 23 '13 at 20:34
1

They are kind of undefined here, but that might not be a problem. There GL state consists of the CURRENT_VERTEX_ATTRIB values. Initially, they are (0,0,0,1). You can explicitely set the attribute values for those attribs where no array is enabled via the glVertexAttrib() family of functions.

The only thing to worry is what happens to the current values when the attribute array is actually enabled during drawing. To quote the Spec (Version 3.3), Section 2.8.3 Vertex Arrays - Drawing Command:

If an array corresponding to a generic attribute required by a vertex shader is not enabled, then the corresponding element is taken from the current generic attribute state (see section 2.7).

If an array corresponding to a generic attribute required by a vertex shader is enabled, the corresponding current generic attribute value is undefined after the execution of DrawArraysOneInstance.

So jou just have to specify a useful value after you had drawn with an array enabled for that particular attribute.

UPDATE

This behavior has actually changed beginning with OpenGL 4.2:

If an array corresponding to a generic attribute required by a vertex shader is not enabled, then the corresponding element is taken from the current generic attribute state (see section 2.7). Otherwise, if an array is enabled, the corresponding current generic attribute value is unaffected by the execution of DrawArraysOneInstance.

So now, a glDraw*() call will never modify the currently set attribute values.

derhass
  • 38,787
  • 2
  • 42
  • 61
  • "*They are kind of undefined here, but that might not be a problem. There GL state consists of the CURRENT_VERTEX_ATTRIB values.*" So how does that make them "kind of undefined"? It isn't undefined if the spec *defines them*. – Nicol Bolas Jul 23 '13 at 19:37
  • 1
    @NicolBolas: I was refering to the fact that the values are undefined after you render with the attrib array enabled (as by the spec), which I assume the OP was doing, since otherwise they would have been on the default values if he does not even know about `glVertexAttrib`. – derhass Jul 23 '13 at 19:45