The man page for glBindAttribLocation states that it can be called on a program object before any shader objects have been added to it. However, the new OpenGL SuperBible goes a bit farther. On page 246, it says, “The binding of attribute locations in this way must be done before linking.” Must is different from can.
Am I doing something wrong if I call glBindAttribLocation after glLinkProgram? I understand that default locations will be assigned for me, and by updating them, I will be wasting some computation. But if my shader program is constructed once, does it really matter?
The quote from the man page just states, that you don’t need those attributes declared in any shader objects when calling glBindAttribLocation for them on a program. It says nothing about the linking stage, so there is no conflict with SuperBible. The latter doesn’t forbid calling glBindAttribLocation after linking. You should just be aware that the actual binding will be done with linking, so I advice you to relink the program when the attribute locations change.
Am I doing something wrong if I call glBindAttribLocation after glLinkProgram?
If you expect that function call to do something useful, then yes, you are wrong. If you do not expect it to do something useful, then why are you calling it?
But if my shader program is constructed once, does it really matter?
It could. By calling the function, the driver may assume that you intend to re-link the program (bad form). Which may force the driver to do things that it ordinarily wouldn’t.
In general, it is a bad idea to make API calls when you don’t plan to follow through on them.
Ah, I understand now. It seems I’ve assumed binding after linking was valid. Probably the defaults have been assigned in the same order that I bind them manually, and the problem has just not manifested itself.
To make things more clear…
By binding attribute location, you tell linker where to locate that particular attribute, so that you can access it by its address (i.e. index). The other two ways of addressing attributes is:
- by querying it with glGetAttribLocation() (if we didn’t specify the location by glBindAttribLocation and let linker assign it)
- by defining in the shader explicitly by layout(location = x).
So it is true that glBindAttribLocation() can be called even before a vertex shader is attached to a program object, but it must be done before linking the program. If you want to change the location you need to relink the program.