Attribute locations for shaders matter?

Started by
7 comments, last by noodleBowl 8 years, 6 months ago

I have quick question when it comes to OpenGL ES 2.0 and shader attributes:

What is the best way to deal with the location that OpenGL assigns a shader attribute?

What I mean is when I use glVertexAttribPointer to "map" my vertex buffer / vertex shader the location matters in the sense that if one device returns 1 and 2 for my vertexPosition and color attributes. And then another device decides to returns 20 for the vertexPosition and 10 for the color attribute.

Wont that mess up my mapping? Causing the shader to mess up what should be displayed to the screen.

In this case my vertex buffer is packed like [VC VC VC VC]

Advertisement

You can use glBindAttribLocation before linking to tell GLES which index to put each attribute in.

I'm pretty sure there's also a way of asking GLES where it has put each attribute, but I don't seem to be using that in my codebase, and I can't remember how to do it.


I'm pretty sure there's also a way of asking GLES where it has put each attribute

Yeah, there's glGetAttribLocation(), it behaves same way as in OpenGL.

https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetAttribLocation.xml

If you are using generic vertex attributes, then you should have made the connection between the index being used in the glVertexAttribPointer call and the vertex attribute being used in the shader instead of assuming the shader compiler is going to fill in the blanks. Querying for the indices used by the shader take the guess work out the entire equation.

In general, yes, the indices matter... in that querying for them is a bad idea (you should never need or use glGetAttribLocation).

Use layout qualifiers to hardcode the attribute locations in your shaders.

layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 normal;

The advantage is that now you can guarantee that all your shaders agree on attribute locations (e.g. position is always attribute 0 in all shaders, texture coordinates are always attribute 1 in all shaders that use textures, etc.) and your code can be made more or less completely agnostic to which shaders are in use; you can swap shaders at runtime and the code wont' have to recache attribute indices or anything.

Sean Middleditch – Game Systems Engineer – Join my team!


Use layout qualifiers to hardcode the attribute locations in your shaders.

That's not the case for OpenGL ES 2.0

I knew about the glGetAttribLocation() call, but I was more worried about the attributes location and my vertex buffer

For example if I pack my vertex buffer like this: [ VertPos Color | VertPos Color | VertPos Color | VertPos Color ]
Then a call using glVertexAttribPointer() looking like this:


glVertexAttribPointer(currentAttrib.location, currentAttrib.size, currentAttrib.type, currentAttrib.normalized, vertexAttribsStride, currentAttrib.offset)

Might mess everything up because of the offset not being the right value. But with the call C0lumbo gave this should no longer be a issue.

Makes me wonder how you specify your vertex buffer correctly without that call

I knew about the glGetAttribLocation() call, but I was more worried about the attributes location and my vertex buffer

For example if I pack my vertex buffer like this: [ VertPos Color | VertPos Color | VertPos Color | VertPos Color ]
Then a call using glVertexAttribPointer() looking like this:


glVertexAttribPointer(currentAttrib.location, currentAttrib.size, currentAttrib.type, currentAttrib.normalized, currentAttrib.offset, vertexAttribsStride)

Might mess everything up because of the offset not being the right value. But with the call C0lumbo gave this should no longer be a issue.

Makes me wonder how you specify your vertex buffer correctly without that call

I don't think it matters. In your glVertexAttribPointer call you're giving two pieces of information, there's the offset and the location.

The location relates to the index given to the attribute in the shader program

The offset relates to the position of the attribute within your interleaved vertices

The two things don't have to be in the same order. Attribute location could be colour then position. Your vertex buffer layout could be position then colour. It'd still work fine (although now you've got me wondering if there might be some performance cost).

I don't think it matters. In your glVertexAttribPointer call you're giving two pieces of information, there's the offset and the location.

The location relates to the index given to the attribute in the shader program
The offset relates to the position of the attribute within your interleaved vertices



At first I was not sure, but then it clicked. That offset param is geared towards the vertex buffer packing. Not the way the attributes are presented in the shader code

This topic is closed to new replies.

Advertisement