Shader syntax

We will use GLSL as our shading language. It has C style syntax with flexible graphics data types and functions. Loop and conditional constructs are similar to C: if, for, while, etc. Here is an example vertex and fragment shader in GLSL. Vertex shader:

in vec2 pos;
in vec3 color;
out vec4 smoothColor;

void main()
{
    gl_Position=vec4(pos.xy, 0, 1);
    smoothColor=vec4(color.xyz, 1);
}

Fragment shader:

in vec4 smoothColor;
out vec4 fragColor;

void main()
{
    fragColor = smoothColor;
}

Types

GLSL supports scalars such as:

float f; //single precision float
int i;   //signed int
uint u;  //unsigned int
bool b;  //boolean

It also supports vector types in the format [type]vec{n} where type is the datatype and n is the size:

vec4  a; //vector of 4 float
ivec3 b; //vector of 3 signed int
uvec2 c; //vector of 2 unsigned int vector
bvec2 d; //vector of 2 boolean vector

Vectors components are accessed with the .xyzw, rgba, or stpq members:

vec4 a
a.x = 4.0;     //set first component to 4
vec2 b = a.yz; //make vec2 from the middle components
vec2 c = a.gb; //make vec2 from the middle components

Vectors and scalar can be used naturally:

vec4 a;
vec4 b;
vec4 c = a * b; //component wise multiply of a and b

float d;
vec4 c;
vec4 e = d * c; //scale c by d

Variables can be created with constructors:

float a = float(4);
vec4 b = vec4(1, 2, 3, a);
vec4 c = vec4(1, b.yz, a);

Input and output variables require qualifiers to describe their use. Vertex shader input and output:

in type x;  //an input attribute
out type y; //an output attribute for interpolation stage

Fragment shader:

in type z;  //an input interpolated fragment (matches vertex output)
out type w; //an output color

Making shaders

Shaders are created with the following OpenGL functions:

I provide a class that will use these to create shaders for you: ShaderManager. Invoke it like this: shaderHandle = ShaderManager::shaderFromFile(vertPath[], fragPath[], vertPathCount, fragPathCount).

After creating a shader, you may then use the returned handle:

glUseProgram(shaderHandle); //activate a shader program
... draw stuff ...
glUseProgram( 0 );          //deactivate all shader programs

Attribute values

Attribute values are the values set for each vertex. These are often things like position and color, but they can be anything. Large arrays of these are uploaded (the Buffer objects) to the GPU. They are then processed by the vertex shader.

Uniform values

Uploading data to the GPU is time consuming, but you can upload small values that change rarely without too much cost. These small values are generally constant and are called 'uniform' values. You can specify uniforms in shaders with the uniform qualifier. You can get and use uniforms on the host as follows:

GLint uniformSlot = glGetUniformLocation(shaderHandle, "uniform name in shader");
glUniform1f(uniformSlot, single_value_to_upload);

The suffix on glUniform controls the details of type and size of the upload.