To learn to create shadow

In the last few classes we talked about different views and we
learned how
projection can be used to create shadow. To cast a shadow of a polygon,
we move
the origin to the light source (L_{x},L_{y},L_{z}),
find
the coordinates of x and z when y is -L_{y} along the ray from
the light
source to a given vertex, then translate back to where we were. We
calculated
our own projection matrix, as shown in 5.10. You can use your own
4x4
matrices in OpenGL by creating a one-dimensional array *m* with
the
4x4
array entries listed in column-major order (ordered by columns rather
than the
usual order by rows). Then *glMultMatrix(m)* will apply the
transformation.

Following is a short program which illustrates shadows by having a light source rotate around a cube. Every time the light makes a complete circle, it is raised by a short distance (thus casting shorter shadows). Here's the program:

// By Late Dr. Mark Harris#include <math.h>

#include <GL/glut.h>

typedef GLfloat point3[3];

GLfloat LightRadius=4;

GLfloat LightHeight=2;

GLfloat Lx=LightRadius,Ly=LightHeight,Lz=0;

double PI,PI2;

GLfloat m[16]={

1,0,0,0,

0,1,0,0,

0,0,1,0,

0,0,0,0};

GLfloat t=0;

// List all vertices in array and reference later by index

point3 p[8]={

{0,0,0},

{0,0,1},

{1,0,1},

{1,0,0},

{0,1,0},

{0,1,1},

{1,1,1},

{1,1,0}

};

void drawPoint(int i,int shadow){

// Draw point i in color i

if(shadow)glColor3f(0,0,0);

else glColor3fv(p[i]);

glVertex3fv(p[i]);

}

void drawFace(int i1,int i2,int i3,int i4, int shadow){

// draw a face of the cube

glBegin(GL_POLYGON);

drawPoint(i1,shadow);

drawPoint(i2,shadow);

drawPoint(i3,shadow);

drawPoint(i4,shadow);

glEnd();

}

void myinit(void)

{

PI=atan(1.0)*4;

PI2=2*PI;

m[7]=-1/Ly;

/* attributes */

glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */

glColor3f(0.0, 0.0, 0.0); /* draw in black */

/* set up viewing */

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

double w=.1;

glFrustum(-w,w,-w,w,.2,10);

}

void drawCube(int shadow)

{

drawFace(0,3,2,1,shadow); //bottom

drawFace(1,2,6,5,shadow); //front

drawFace(2,3,7,6,shadow); //right side

drawFace(0,1,5,4,shadow); //left side

drawFace(3,0,4,7,shadow); //back side

drawFace(4,5,6,7,shadow); //top

}

void display( void )

{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); /*clear the window */

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(4,2,4,0,0,0,0,1,0);

drawCube(0);

glTranslatef(Lx,Ly,Lz); //translate back

glMultMatrixf(m);

glTranslatef(-Lx,-Ly,-Lz);

drawCube(1);

glFlush(); /* clear buffers */

glutSwapBuffers();

}

void idle()

{

t+=.1;

Lx=LightRadius*cos(t);

Ly=LightHeight;

Lz=LightRadius*sin(t);

m[7]=-1/Ly;

if(t>=PI2){

t-=PI2;

LightHeight+=.5;

}

glutPostRedisplay();

}

void main(int argc, char** argv)

{

/* Standard GLUT initialization */

glutInit(&argc,argv);

glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH);

glutInitWindowSize(500,500); /* 500 x 500 pixel window */

glutInitWindowPosition(0,0); /* place window top left on display */

glutCreateWindow("Cube"); /* window title */

glutDisplayFunc(display); /* display callback invoked when window opened */

glutIdleFunc(idle);

myinit(); /* set attributes */

glEnable(GL_DEPTH_TEST); /* Enable hidden--surface--removal */

glEnable(GL_SMOOTH); /* Enable smooth shading and color interpolation */

glutMainLoop(); /* enter event loop */

}

Here's a sample image from the resulting animation:

We have talked about lighting models in class and will work on = matrieces that heps us set the lighting soon.

A real light source is very complex. A light bulb emits light of = various wavelengths from various points, and the cumulative effect at a target = involves lots of integral calculus.

We approximate light sources using one of three types:

- point sources
- spot lights, in which a a point on the object is proportional to = the angle between the surface normal and the light source. If we have both = directions available as unit vectors, we can find this cosine as just the dot = product of the vectors, which is a very fast operation.

Ambient lighting is a global approximation to uniform lighting. For = example, if we have many fluorescent bulbs in the ceiling, the net effect might = be uniform lighting. It is much faster to simply set a given light = intensity at all points than to integrate over all the light sources.