The storage qualifiers in
and out
actually have a purpose that contains and supersedes that of varying
and attribute
. They define what variables are respectively inputs and outputs for the shader. See the GLSL 4.2 reference card page 7:
in
: linkage into shader from previous stage
out
: linkage out of a shader to next stage
attribute
: same as in
for vertex shader
varying
: same as out
for vertex shader, same as in
for fragment shader (Note: these are erroneously flipped around in the above-mentioned reference card.)
With the side note that the latter two are sort of deprecated: they are not present in the 4.2 core profile, only in the compatibility profile.
What exactly do they do?
As for usage, take the vertex shader from An intro to modern OpenGL. Chapter 2.2: Shaders:
#version 110
attribute vec2 position;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
texcoord = position * vec2(0.5) + vec2(0.5);
}
It should be rewritten in 4.2 core as:
#version 420
in vec2 position;
out vec2 texcoord;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
texcoord = position * vec2(0.5) + vec2(0.5);
}
in
/out
for function parameters
From the Parameters
section in the Khronos wiki:
void MyFunction(in float inputValue, out int outputValue, inout float
inAndOutValue);
Functions in GLSL use a calling convention called "value-return." This
means that values passed to functions are copied into parameters when
the function is called, and outputs are copied out when the function
returns.
The in
, out
, and inout
qualifiers are not the same as type qualifiers,
even though some of them are named the same. These are parameter
qualifiers, and they have a different meaning here.
A parameter declared as in
means that the value given to that
parameter will be copied into the parameter when the function is
called. The function may then modify that parameter as they see fit,
but those changes will not affect the calling code.
A parameter declared as out
will not have its value initialized by the
caller. The function will modify the parameter, and after the
function's execution is complete, the value of the parameter will be
copied out into the variable that the user specified when calling the
function. Note that the initial value of the parameter at the start of
the function being called is undefined, just as if one had simply
created a local variable.
The inout
declaration combines both. The parameter's value will be
initialized by the value supplied by the user, and its final value
will be output
The default if no qualifier is specific is in
.
Unhelpful Tutorials
I'm guessing the main reason you find "outdated" tutorial code is that not everyone has access to GLSL 3.3+ compatible hardware. Regardless, for a good and more up to date tutorial I'll gladly point you in the direction of Nicol Bolas' Learning Modern 3D Graphics Programming.