Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL default value for unbuffered vertex attribute when using layout qualifiers

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?

like image 712
kbirk Avatar asked Jul 23 '13 19:07

kbirk


People also ask

What is vertex attribute in OpenGL?

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.

What is a shader attribute?

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.

What is GLSL layout?

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.


2 Answers

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.

like image 82
Nicol Bolas Avatar answered Oct 13 '22 00:10

Nicol Bolas


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.

like image 23
derhass Avatar answered Oct 12 '22 22:10

derhass