local viewing and specular lighting

so I learned about how to establish a local viewer, which I understand, considers not only the angle between a surface normal and the light source(s), but also the angle between the viewer and the surface. So I decided to try to test it out, but can’t seem to obtain any noticeable results.

My intent with the following program, is to draw a sierpinski gasket, at (0,0,-20), give it high specular reflectance, set it rotating about (1,0,0), and place a light source directly above it at (0,10,-20). I hope then, when the object has been rotated 45 degrees, i will see a spotlike reflection of the light on the surface of the object, or at least, see the object reach maximum illumination at that point. I am seeing neither, and getting some odd results.

Here is the full program, it uses glut:


#include "stdafx.h" // for visual C++

#include "glut.h"
#include <gl/gl.h>
#include <gl/glu.h>

float spinAngle = 0; // used for spinning rendered object


// properties for light0
float ambientLight0[] = { 1, 1, 1, 1.0f };	
float diffuseLight0[] = { 1, 1, 1, 1.0f };	
float specularLight0[] = {1, 1, 1, 1.0f};
float lightLocation0[] = {0, 10.0f, -20.0f, 1.0f }; /* intended to be directly above the object */

// Material light properties for the object
float matAmbient[] = { 0.1f, 0.1f, 0.4f, 1.0f }; // blueish
float matDiff[] = { 0.1f, 0.1f, 0.1f, 1.0f};
float matSpec[] = {0.5f, 0.5f, 0.5f, 1.0f}; // high specular

static void _Timer(int value)
{
  // increment angle 
    spinAngle += 0.5;
	while (spinAngle > 360)
		spinAngle -= 360;

  // send redisplay event
  glutPostRedisplay();

  // call this function again in 10 milliseconds
  glutTimerFunc(10, _Timer, 0);
}


void initLighting()
{
		// enable lighting
		glEnable(GL_LIGHTING);
	    glPushMatrix(); /* push and clear modelview matrix to ensure light0's location is not transformed */ 
		glLoadIdentity(); 
										
		// use a local view
        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); 
		
		// Setup the material properties for the object
        glMaterialfv(GL_FRONT, GL_AMBIENT, matAmbient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
        glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);

        glMaterialfv(GL_BACK, GL_AMBIENT, matAmbient);
        glMaterialfv(GL_BACK, GL_DIFFUSE, matDiff);
        glMaterialfv(GL_BACK, GL_SPECULAR, matSpec);

        // Now setup LIGHT0
        glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight0);		
        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight0);		
        glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight0);
        glLightfv(GL_LIGHT0, GL_POSITION, lightLocation0);	

        // enable light0
        glEnable(GL_LIGHT0);

}

void init()
{

  glClearColor (0.0, 0.0, 0.0, 0.0);
  glShadeModel (GL_SMOOTH);
  					 
  
  // initialize lighting
  initLighting();
	
}

void drawSquare(float x, float y, float length)
{
        // a simple square drawing routine 

	length /= 2; // halve the length so the square is centered at (x,y) 
	glNormal3f(0,0,1);
	glBegin(GL_QUADS);
	glVertex3f(x-length, y-length, 0);
	glVertex3f(x+length, y-length, 0);
	glVertex3f(x+length, y + length, 0);
	glVertex3f(x -length, y + length,0);
	glEnd();
}

void drawGasket(float x, float y, float length, int depth)
{
   // draw a sierpinski gasket

if (depth <= 1) 
{
  drawSquare(x,y, length);
  return;
}
//else

depth--;

drawGasket(x, y, length/3, depth);
drawGasket(x + length/3,	y,length/3, depth);
drawGasket(x + 2*length/3, y,length/3, depth);
drawGasket(x, y - length/3, length/3, depth);
drawGasket(x + 2*length/3, y - length/3, length/3, depth);
drawGasket(x, y- 2*length/3, length/3, depth);
drawGasket(x + length/3, y- 2*length/3, length/3, depth);
drawGasket(x + 2*length/3, y-2*length/3,length/3, depth);

}


void display(void)
{
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glLoadIdentity();
	glTranslatef(-4,0,-20); // place the object at z = -20 so it is under light0, nudge left to center 
	glRotatef(spinAngle, 1,0,0);
	
	drawGasket(0,0,8,5); // an 8x8 sierpinski gasket with a recursize depth of 5 at (0,0)

   glutSwapBuffers();

}

void reshape (int w, int h)
{ 


   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();

   gluPerspective(30.0f, w/(float)h, 1, 100);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}


int main(int argc, char** argv)
{
 
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
   glutInitWindowSize (500, 500);
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutTimerFunc(10, _Timer, 0);
   glutMainLoop();

   return 0;
}


the results don’t make sense. The object abruptly becomes fully lit when its at 45 degrees off the zy plane, and goes dark again when it reaches -270, as shown below:

doesn’t seem to be behaving at all how i’d expect. Can anyone explain why?

(edit) my diagram is dumb, pivot point and light0 should be horizontally aligned, but you get the idea.

Nevermind, it seems I needed to enable front and back lighting, and I had to adjust the shininess attribute of the material. Its working now, though I still don’t understand why I was getting those results.