A Simple Shadow
The idea is based on a situation where we position a light source in origo.
The plane (P!,P2,P3) is described with the equation: Ax+By+Cz=D.
private void CalculatePlane()
{
double[] v1={floor[3]-floor[0], //x
floor[4]-floor[1], //y
floor[5]-floor[2]}; //z
double[] v2={floor[6]-floor[0], //x
floor[7]-floor[1], //y
floor[8]-floor[2]}; //z
// crossproduct: (ay*bz-az*by, az*bx-ax*bz, ax*by-ay*bx)
A = v1[1] * v2[2] - v1[2] * v2[1];
B = v1[2] * v2[0] - v1[0] * v2[2];
C = v1[0] * v2[1] - v1[1] * v2[0];
// using a point on the floor to find D
D = -(A * floor[0] + B * floor[1] + C * floor[2]);
}
Based on this we render the scene with;
public void display(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
GLU glu=new GLU();
// Clear the drawing area
gl.glClear(GL.GL_COLOR_BUFFER_BIT |
GL.GL_DEPTH_BUFFER_BIT|
GL.GL_ACCUM_BUFFER_BIT);
gl.glLoadIdentity();
// watch this
glu.gluLookAt(25.0,25.0,20.0,
0.0,0.0,-10.0,
0.0,0.0,1.0);
//gl.glRotatef(view_rotx,1.0f,0.0f,0.0f);
//gl.glRotatef(view_roty,0.0f,1.0f,0.0f);
// draw axes
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(0.0, 0.0, 0.0); gl.glVertex3d(20.0, 0.0, 0.0);
gl.glVertex3d(0.0, 0.0, 0.0); gl.glVertex3d(0.0, 20.0, 0.0);
gl.glVertex3d(0.0, 0.0, -20.0); gl.glVertex3d(0.0, 0.0, 0.0);
gl.glEnd();
// draw the light as a sphere
// set bulb material
stdMaterials.setMaterial(gl,stdMaterials.MAT_YELLOW_PLASTIC,GL.GL_FRONT);
GLUquadric q=glu.gluNewQuadric();
q=glu.gluNewQuadric();
glu.gluSphere(q,0.5f,20,20);
glu.gluDeleteQuadric(q);
// draw the floor
//set floormaterial
stdMaterials.setMaterial(gl,stdMaterials.MAT_GREEN_RUBBER,GL.GL_FRONT);
gl.glBegin(GL.GL_POLYGON);
gl.glNormal3d(0.0, 0.0, 1.0);
for (int ix = 0; ix < 12; ix += 3)
gl.glVertex3d(floor[ix], floor[ix + 1], floor[ix + 2] - 0.1);
gl.glEnd();
// draw the form that casts the shadow
gl.glRotatef(ZRotation, 0.0f, 0.0f, 1.0f);
// set form material
stdMaterials.setMaterial(gl,stdMaterials.MAT_RUBY,GL.GL_FRONT);
DrawForm(gl);
// since light is in origo
double[] mpx = {D, 0.0f,0.0f,-A,
0.0f,D, 0.0f,-B,
0.0f,0.0f,D, -C,
0.0f,0.0f,0.0f,0.0f};
gl.glPushMatrix();
gl.glMultMatrixd(mpx,0);
// set shadow material
stdMaterials.setMaterial(gl,stdMaterials.MAT_BLACK_RUBBER,GL.GL_FRONT);
// draw the shadow
DrawForm(gl);
gl.glPopMatrix();
// Flush all drawing operations to the graphics card
gl.glFlush();
}
The form casting the shadow is rendered like this;
private void DrawForm(GL gl)
{
double[] triangle ={5.0,0.0,0.0,
0.0,5.0,0.0,
5.0,5.0,0.0};
int Radius = 7;
GLU glu=new GLU();
GLUT glut=new GLUT();
GLUquadric glpQ=glu.gluNewQuadric();
gl.glTranslatef(0.0f,0.0f,ZElevation);
switch (SelectedForm)
{
case 1:glu.gluSphere(glpQ,Radius/3.0f,20,20);break;
case 2:theTorus.drawTorus(Radius, Radius/10.0f, 50, 50);break;
case 3:glut.glutSolidTeapot(1.0);break;
default:
gl.glBegin(GL.GL_POLYGON);
gl.glNormal3d(A, B, C);
for (int ix = 0; ix < 9; ix += 3)
gl.glVertex3d(triangle[ix],
triangle[ix + 1],
triangle[ix + 2]);
gl.glEnd();
break;
}
gl.glTranslatef(0.0f,0.0f,-ZElevation);
glu.gluDeleteQuadric(glpQ);
}












