=== modified file 'data/shaders/light-advanced.frag'
--- data/shaders/light-advanced.frag	2010-07-08 09:08:36 +0000
+++ data/shaders/light-advanced.frag	2010-07-09 09:48:40 +0000
@@ -1,94 +1,31 @@
-// Make sure you remember to add the varying variables:
-// varying vec3 Normal;
-// varying vec3 Light;
-// varying vec3 HalfVector;
-// To the fragment shader so that we can read them in.
-
-// First off here, we have to make sure that our Normal
-// has been normalized so to make sure, we are just going
-// to normalize it with the line:
-// Normal = normalize(Normal);
-
-// Next off we want to calculate our diffuse portion of 
-// the lighting. Now unlike the basic lighting tutorial,
-// I am going to take into account the materials we have
-// attached to the object, and the settings we have applied
-// to our light.
-
-// Now for our diffuse portion of our equation we get the line:
-// float Diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * max(dot(Normal, Light),0.0);
-// Now the variable gl_FrontMaterial.diffuse is the diffuse
-// material we have assigned to the front face of our object,
-// and to get the diffuse portion of our light, we call the 
-// variable gl_LightSource[0].diffuse. Then to take into account
-// how intense this should be, we multiply it by:
-// max(dot(Normal, Light),0.0)
-// Which from our previous tutorial, we used to calculate how
-// intense the light should be, using the angle of the surface
-// compared to the position of the light.
-
-// Seeing as though we now have the diffuse part of our lighting
-// we now need the Ambient term. In this term there are no real
-// calculations like the dot product, used in the diffuse term.
-// Here we are just taking values set inside our OpenGL program
-// and applying them to our object. The variables that we need
-// to use are:
-// gl_FrontMaterial.ambient
-// gl_LightSource[0].ambient
-// gl_LightModel.ambient
-// For our Ambient term to work, we need to multiply
-// gl_FrontMaterial.ambient and gl_LightSource[0].ambient
-// and then add the product of gl_LightModel.ambient and
-// gl_FrontMaterial.ambient
-// So our equation looks like:
-// float Ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
-// Ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;
-
-// In this tutorial, I am not going to cover the emissive term
-// that OpenGL supports (I will in a later tutorial), so I am 
-// going to jump straight to the most complicated term in the
-// lighting equation. Which is the specular term. The reason
-// that this term is the most complicated, is that it needs
-// to find the reflection of the lighting from the surface of
-// the object, to the 'camera'. The first part of the equation
-// is similar to the start of the previous equations and takes
-// the materials specular term, and the lights specular term
-// and multiplies them together to look like:
-// gl_FrontMaterial.specular * gl_LightSource[0].specular
-// and then comes the tricky part, we need to multiply this by
-// pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess);
-// This takes the dot product of our Normal and HalfVector, and as
-// we have seen in the diffuse term, sets a max of 0.0
-// With the number we have just calculated, we need to raise that
-// to the power of our shininess term set inside our OpenGL program.
-
-// Because we are using the halfVector at this stage, we don't need
-// to use the reflect() expression, but we will when we get into
-// normal mapping.
-
-// So in the end our specular expression looks like:
-// float Specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess);
-
-// Now for the combining of all the expressions. We still need to
-// multiply the diffuse term by the objects color. And with that
-// we then need to add the Ambient term and the Specular term.
-// So our final gl_FragColor call looks like:
-// gl_FragColor = Ambient + (Diffuse * vec4(1,0,0,1)) + Specular;
+uniform vec3 LightSourceAmbient;
+uniform vec3 LightSourceDiffuse;
+uniform vec3 LightSourceSpecular;
+uniform vec3 MaterialAmbient;
+uniform vec3 MaterialDiffuse;
+uniform vec3 MaterialSpecular;
 
 varying vec3 Normal;
 varying vec3 Light;
 varying vec3 HalfVector;
 
 void main(void)
-{	
-	vec3 N = normalize(Normal);
-
-	vec4 Diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * max(dot(N, Light),0.0);
-
-	vec4 Ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
-	Ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;
-
-	vec4 Specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess);
-
-	gl_FragColor = Ambient + (Diffuse * vec4(0,0,1,1)) + Specular;
+{
+    vec3 N = normalize(Normal);
+    vec3 L = normalize(Light);
+    vec3 H = normalize(HalfVector);
+
+    // Calculate the diffuse color according to Lambertian reflectance
+    vec3 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0);
+
+    // Calculate the ambient color
+    vec3 ambient = MaterialAmbient * LightSourceAmbient;
+
+    // Calculate the specular color according to the Blinn-Phong model
+    vec3 specular = MaterialSpecular * LightSourceSpecular *
+                    pow(max(dot(N,H), 0.0), 100.0);
+
+    // Calculate the final color
+    gl_FragColor = vec4(ambient, 1.0) + vec4(specular, 1.0) +
+                   vec4(diffuse, 1.0) * vec4(0.0, 0.0, 1.0, 1.0);
 }

=== modified file 'data/shaders/light-advanced.vert'
--- data/shaders/light-advanced.vert	2010-07-07 10:32:18 +0000
+++ data/shaders/light-advanced.vert	2010-07-09 09:48:40 +0000
@@ -1,39 +1,11 @@
-// First off, I am going to explain a little thing
-// with shaders, that will help you to optimize them
-// in the future. Vertex shaders are called for every
-// vertex passed through, and Fragment shaders are
-// called for every pixel on the screen. Because of this
-// it is wise to do as many calculations in the vertex
-// shader as possible, as they are called less, and if
-// the calculation does not need to be called on a per
-// pixel basis, why do it?
-
-// Now as for the tutorial, you will see that I have
-// removed the variable Diffuse from our vertex shader.
-// This is because we are now going to calculate that in
-// the fragment shader so we can get per pixel lighting.
-
-// In our vertex shader, I have added the varying variables:
-// varying vec3 Normal;
-// varying vec3 Light;
-// varying vec3 HalfVector;
-// These hold the surface normal of our vertex, the direction
-// vector of the light source, and the half vector of the
-// light source (you may want to look into the maths behind
-// lighting, I may add something in the maths section at a 
-// later date).
-
-// These variables are going to be calculated here, and passed
-// through to our fragment shader. This is because these variables
-// will not change, so there is no need calculating them on a
-// per pixel basis.
-
-// Now that we have these variables, we need to calculate them.
-// Our Normal and Light variables stay exactly the same
-// as in the previous tutorial. The only new one is the HalfVector
-// which is called similar to our Light variable, just replace
-// position with halfVector, and we get the light sources half
-// vector supplied by OpenGL.
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec2 texture;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+uniform vec4 LightSourcePosition;
+uniform vec3 LightSourceHalfVector;
 
 varying vec3 Normal;
 varying vec3 Light;
@@ -41,11 +13,16 @@
 
 void main(void)
 {			
-	Normal = normalize(gl_NormalMatrix * gl_Normal);
-
-	Light = normalize(gl_LightSource[0].position.xyz);
-
-	HalfVector = normalize(gl_LightSource[0].halfVector.xyz);
-
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-}
\ No newline at end of file
+    // Transform the normal to eye coordinates
+	Normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+    // The LightSourcePosition is actually its direction for directional light
+    Light = normalize(LightSourcePosition.xyz);
+
+	// The HalfVector is used in the Blinn-Phong shading model for calculating
+	// specular lighting.
+	HalfVector = normalize(LightSourceHalfVector);
+
+    // Transform the position to clip coordinates
+	gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}

=== modified file 'sceneshading.cpp'
--- sceneshading.cpp	2010-07-08 15:17:11 +0000
+++ sceneshading.cpp	2010-07-09 09:48:40 +0000
@@ -49,26 +49,14 @@
 
 void SceneShading::start()
 {
-    GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f};
+    GLfloat lightAmbient[] = {0.1f, 0.1f, 0.1f, 1.0f};
     GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
+    GLfloat lightSpecular[] = {0.8f, 0.8f, 0.8f, 1.0f};
     GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f};
 
-    float no_mat[] = {0.0f, 0.0f, 0.0f, 1.0f};
-    float mat_diffuse[] = {0.1f, 0.5f, 0.8f, 1.0f};
+    float mat_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
+    float mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
     float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
-    float high_shininess = 100.0f;
-
-    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
-    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
-    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
-    glMaterialf(GL_FRONT, GL_SHININESS, high_shininess);
-    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
-
-    glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
-    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
-    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-    glEnable(GL_LIGHT0);
-    glEnable(GL_LIGHTING);
 
     switch(mCurrentPart)
     {
@@ -82,15 +70,24 @@
         break;
     }
 
-    if (mCurrentPart == 0) {
-        glUniform4fv(mShader[mCurrentPart].mLocations.LightSourcePosition, 1,
-                lightPosition);
-        glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceDiffuse, 1,
-                lightDiffuse);
-        glUniform3fv(mShader[mCurrentPart].mLocations.MaterialDiffuse, 1,
-                mat_diffuse);
-    }
-
+    // Load lighting and material uniforms
+    glUniform4fv(mShader[mCurrentPart].mLocations.LightSourcePosition, 1, lightPosition);
+
+    glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceAmbient, 1, lightAmbient);
+    glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceDiffuse, 1, lightDiffuse);
+    glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceSpecular, 1, lightSpecular);
+
+    glUniform3fv(mShader[mCurrentPart].mLocations.MaterialAmbient, 1, mat_ambient);
+    glUniform3fv(mShader[mCurrentPart].mLocations.MaterialDiffuse, 1, mat_diffuse);
+    glUniform3fv(mShader[mCurrentPart].mLocations.MaterialSpecular, 1, mat_specular);
+
+    // Calculate and load the half vector
+    Vector3f halfVector = Vector3f(lightPosition[0], lightPosition[1], lightPosition[2]);
+    halfVector.normalize();
+    halfVector += Vector3f(0.0, 0.0, 1.0);
+    halfVector.normalize();
+    glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceHalfVector, 1,
+                 (GLfloat *)&halfVector);
 
     mCurrentFrame = 0;
     mRunning = true;
@@ -134,32 +131,22 @@
 
 void SceneShading::draw()
 {
-    glTranslatef(0.0f, 0.0f,-5.0f);
-    glRotated(mRotation, 0.0f, 1.0, 0.0f);
-
-    glColor3f(0.0f, 1.0f, 1.0f);
-
-    if (mCurrentPart == 0) {
-        // Load the ModelViewProjectionMatrix uniform in the shader
-        Matrix4f model_view(1.0f, 1.0f, 1.0f);
-        Matrix4f model_view_proj(mScreen.mProjection);
-
-        model_view.translate(0.0f, 0.0f, -5.0f);
-        model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f);
-        model_view_proj *= model_view;
-
-        glUniformMatrix4fv(mShader[mCurrentPart].mLocations.ModelViewProjectionMatrix, 1,
-                GL_FALSE, model_view_proj.m);
-
-        // Load the NormalMatrix uniform in the shader
-        // The NormalMatrix is the inverse transpose of the model view matrix.
-        model_view.invert().transpose();
-        glUniformMatrix4fv(mShader[mCurrentPart].mLocations.NormalMatrix, 1,
-                GL_FALSE, model_view.m);
-
-        mMesh.render_vbo_attrib();
-    }
-    else {
-        mMesh.render_vbo();
-    }
+    // Load the ModelViewProjectionMatrix uniform in the shader
+    Matrix4f model_view(1.0f, 1.0f, 1.0f);
+    Matrix4f model_view_proj(mScreen.mProjection);
+
+    model_view.translate(0.0f, 0.0f, -5.0f);
+    model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f);
+    model_view_proj *= model_view;
+
+    glUniformMatrix4fv(mShader[mCurrentPart].mLocations.ModelViewProjectionMatrix, 1,
+                       GL_FALSE, model_view_proj.m);
+
+    // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+    // inverse transpose of the model view matrix.
+    model_view.invert().transpose();
+    glUniformMatrix4fv(mShader[mCurrentPart].mLocations.NormalMatrix, 1,
+                       GL_FALSE, model_view.m);
+
+    mMesh.render_vbo_attrib();
 }

