Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit vs Automatic attribute location binding for OpenGL shaders

When setting up attribute locations for an OpenGL shader program, you are faced with two options:

glBindAttribLocation() before linking to explicitly define an attribute location.

or

glGetAttribLocation() after linking to obtain an automatically assigned attribute location.

What is the utility for using one over the other?

And which one, if any, is preferred in practice?

like image 315
Jing Avatar asked Jan 08 '11 20:01

Jing


People also ask

How do shaders work in OpenGL?

A Shader is a user-defined program designed to run on some stage of a graphics processor. Shaders provide the code for certain programmable stages of the rendering pipeline. They can also be used in a slightly more limited form for general, on-GPU computation.

How do I change shaders in OpenGL?

Compile all shader variants at the beginning (or when you need a program) Bind a shader and the relative resources, set uniforms before drawing with that shader. When change shader, re-bind the resources or update uniform values only if different and needed. Release resources and programs at the end of the application.

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 sampler2D?

A sampler2D is used to do lookup in a standard texture image; a samplerCube is used to do lookup in a cubemap texture (Subsection 5.3. 4). The value of a sampler variable is a reference to a texture unit. The value tells which texture unit is invoked when the sampler variable is used to do texture lookup.


1 Answers

I know one good reason to prefer explicit location definition.

Consider that you hold your geometry data in Vertex Array Objects. For a given object, you create a VAO in such way that the indices correspond to, for example:

  • index 0: positions,
  • index 1: normals,
  • index 2: texcoords

Now consider that you want to draw one object with two different shaders. One shader requires position and normal data as input, the other - positions and texture coords.

If you compile those shaders, you will notice that the first shader will expect the positions at attribute index 0 and normals at 1. The other would expect positions at 0 but texture coords at 1.

Quoting https://www.opengl.org/wiki/Vertex_Shader:

Automatic assignment

If neither of the prior two methods assign an input to an attribute index, then the index is automatically assigned by OpenGL when the program is linked. The index assigned is completely arbitrary and may be different for different programs that are linked, even if they use the exact same vertex shader code.

This means that you wouldn't be able to use your VAO with both shaders. Instead of having one VAO per, say, object, you'd need - in the worst case - a separate VAO per object per shader.

Forcing the shaders to use your own attribute numbering convention via glBindAttribLocation can solve this problem easily - all you need to do is to keep a consistent relation between attributes and their estabilished IDs, and force the shaders to use that convention when linking.

(That's not really a big issue if you don't use separate VAOs, but still might make your code clearer.)


BTW:

When setting up attribute locations for an OpenGL shader program, you are faced with two options

There's a third option in OpenGL/GLSL 3.3: Specify the location directly in shader code. It looks like this:

layout(location=0) in vec4 position; 

But this is not present in GLSL ES shader language.

like image 156
Kos Avatar answered Sep 28 '22 21:09

Kos