you mean the “s” in “TexCoords”: no, glGetProgramiv() doesnt throw an linking error, as a result the vertexshader passes the coords to the fragmentshader, but the fragmentshader doesnt care about it, it want (and receives) “TexCoords” which isnt provided by the vertexshader, so its undefined (or 0)
to avoid such errors, you can make use of “interface blocks”:
this will give you a linking error, saying that the “interface blocks dont match”
changing TexCoords to TexCoord in the fragmentshader will eliminate the error, that means only the variables withing the { block } brackets have to match as well as the block name “SomeNameHere”, the “instance names” (here: vs_out and fs_in) dont have to match. that way you can be sure that the fragmentshader actually receives what the vertexshader passes through
mismatching interfaces between stages are linker errors. However, the interface between separable programs in a pipeline can only be checked at runtime, when the pipeline is used.
[…]
For loose variables, an output matches with an input if:
The two variables represent the same interface. This is determined by checking the following, in order (the first overrides the second):
If both of the variables are given a layout(location) setting that is equivalent.
If both variables have the same name (and neither variable has a layout(location) qualifier).
The two variables have types which match (separate program allow for some slight mismatching). If they are arrays, the element counts must match.
Have type qualifiers which match, as described below.
Since you (apparently) don’t use separable programs, errors should be reported during link-time, but only for mismatching interfaces.
Since you don’t use blocks, you end up with loose variables.
Since the two variables don’t have the same name, they don’t represent the same interface. Thus you don’t end-up with any interface mismatch.
I’ve taken John Connor’s advice and now use interface blocks for my shaders.
It will be a couple of days before I get to the tutorial that introduces more advanced GLSL topics. I’ve learned so much about OpenGL, and I have so far to go.
I am curious about what you and the wiki are referring to as “separable programs”.
However, I’m consumed right now by getting my first framebuffer code working. An understanding of the details of shader compilation is valuable, and probably necessary to become competent in the use of OpenGL, but I need to focus on one task.
In OpenGL with GLSL you take a vertex shader, a fragment shader, and optionally other shaders, compile them, then link them together into a single program object. From that point onwards you operate using the program object.
The thing is, the linking step is purely a software construct of OpenGL with GLSL; other APIs don’t have it and even OpenGL with older assembly language vertex and fragment programs didn’t have it. In these APIs there is no program object, and you are free to change vertex shaders without also changing fragment shaders, for example. Shader stages are separate and independent of each other, and behaviour is well-defined for cases where a stage expects an input that the previous stage doesn’t provide (or provides an output that the next stage doesn’t consume). You can freely mix-and-match shaders and avoid some of the inevitable shader combination explosion.
Oddly enough, other APIs manage to do all of this without incurring any performance penalty, thereby indicating that the program object enforced by GLSL is not actually an optimization.