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?
A vertex attribute is an input variable to a shader that is supplied with per-vertex data. In OpenGL core profile, they are specified as in variables in a vertex shader and are backed by a GL_ARRAY_BUFFER . These variable can contain, for example, positions, normals or texture coordinates.
Attributes are GLSL variables which are only available to the vertex shader (as variables) and the JavaScript code. Attributes are typically used to store color information, texture coordinates, and any other data calculated or retrieved that needs to be shared between the JavaScript code and the vertex shader.
Layout qualifiers are sometimes used to define various options for different shader stages. These shader stage options apply to the input of the shader stage or the output. In these definitions, variable definition will just be in or out.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With