I have a situation where I want all of the objects in my landscape to be static while I move a “camera” around. Thus far I have done this, but when I implement shadows they don’t stay with the landscape as I move. When the program first starts out and I haven’t moved the shadows are fine. But when I move the shadows move too; they sort of move with me, but not completely. Here’s what I do (if you’re familiar with NeHe’s tutorials it is adapted from that)

int DrawGLScene(GLvoid) // Here’s Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear The Screen And The Depth Buffer

GLfloat x_m, y_m, z_m, u_m, v_m, nx, ny, nz;
GLfloat width, depth;
GLfloat radius, height, bangle, eangle, divisions;
int sangle, arclength, division, face;
GLfloat xtrans = -xpos; //Set the x-axis position by the opposite (move camera not scene) of the incriment designated by pressing the key
GLfloat ztrans = -zpos; //"" with z-axis
GLfloat ytrans = -0.5f-ypos; //bounce up and down as if walking
GLfloat sceneroty = 360.0f - yrot;
GLfloat newlightpos[4];

GLmatrix16f Minv;
GLvector4f lp;

int numtrans, looptrans;
float tx = 0;
float ty = 0;
float tz = 0;
float magnitude = 0;
float rx = 0;
float ry = 0;
float rz = 0;

glRotatef(lookupdown, 1.0f, 0.0f, 0.0f); //Enables looking up and down on x-axis
glRotatef(sceneroty, 0.0f, 1.0f, 0.0f); //Enables left and right turning on y-axis

glTranslatef(xtrans, ytrans, ztrans); //Move to new position after changing by increment

//create light source
glTranslatef (l_x, l_y, l_z);
glColor4f(0.7f, 0.4f, 0.0f, 1.0f);

glDisable (GL_LIGHTING);

glEnable(GL_LIGHTING); // Enable Lighting

glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
newlightpos[0] = LightPosition[0] + l_x; // store new light position
newlightpos[1] = LightPosition[1] + l_y; // " "
newlightpos[2] = LightPosition[2] + l_z; // " "
newlightpos[3] = LightPosition[3];
glTranslatef (-l_x, -l_y, -l_z);

{
for (looptrans = 0; looptrans < numtrans; ++looptrans)
{

``````  	glPushMatrix();

if (looptrans)
{
glTranslatef (tx, ty, tz);
}

for (int loopvertex = 0; loopvertex < 4; ++loopvertex)
{
glNormal3f(nx, ny, nz);
glTexCoord2f(u_m, v_m); glVertex3f(x_m, y_m, z_m);
}

glEnd();

lp[0] = newlightpos[0];								// Store Light Position X In lp[0]
lp[1] = newlightpos[1];								// Store Light Position Y In lp[1]
lp[2] = newlightpos[2];								// Store Light Position Z In lp[2]
lp[3] = newlightpos[3];								// Store Light Direction In lp[3]

glPopMatrix();
}
``````

}

glFlush();
return TRUE;
}

void doShadowPass (const VERTEX& c_v1, const VERTEX& c_v2, const VERTEX& c_v3, const VERTEX& c_v4, GLfloat *lightPosition)
{
VERTEX v3, v4;

//go through each edge

//edge 1
//edge vertices
const VERTEX& v1 = c_v1;
const VERTEX& v2 = c_v2;
//distant vertices
v3.x = (v1.x - lightPosition[0]) * INFINITY;
v3.y = (v1.y - lightPosition[1]) * INFINITY;
v3.z = (v1.z - lightPosition[2]) * INFINITY;

v4.x = (v2.x - lightPosition[0]) * INFINITY;
v4.y = (v2.y - lightPosition[1]) * INFINITY;
v4.z = (v2.z - lightPosition[2]) * INFINITY;

glBegin (GL_TRIANGLE_STRIP);
glVertex3f( v1.x, v1.y, v1.z );
glVertex3f( v1.x+v3.x, v1.y+v3.y, v1.z+v3.z );
glVertex3f( v2.x, v2.y, v2.z );
glVertex3f( v2.x+v4.x, v2.y+v4.y, v2.z+v4.z );
glEnd();

//edge 2
//edge vertices
const VERTEX& v1_2 = c_v2;
const VERTEX& v2_2 = c_v3;
//distant vertices
v3.x = (v1_2.x - lightPosition[0]) * INFINITY;
v3.y = (v1_2.y - lightPosition[1]) * INFINITY;
v3.z = (v1_2.z - lightPosition[2]) * INFINITY;

v4.x = (v2_2.x - lightPosition[0]) * INFINITY;
v4.y = (v2_2.y - lightPosition[1]) * INFINITY;
v4.z = (v2_2.z - lightPosition[2]) * INFINITY;

glBegin (GL_TRIANGLE_STRIP);
glVertex3f( v1_2.x, v1_2.y, v1_2.z );
glVertex3f( v1_2.x+v3.x, v1_2.y+v3.y, v1_2.z+v3.z );
glVertex3f( v2_2.x, v2_2.y, v2_2.z );
glVertex3f( v2_2.x+v4.x, v2_2.y+v4.y, v2_2.z+v4.z );
glEnd();

//edge 3
//edge vertices
const VERTEX& v1_3 = c_v3;
const VERTEX& v2_3 = c_v4;
//distant vertices
v3.x = (v1_3.x - lightPosition[0]) * INFINITY;
v3.y = (v1_3.y - lightPosition[1]) * INFINITY;
v3.z = (v1_3.z - lightPosition[2]) * INFINITY;

v4.x = (v2_3.x - lightPosition[0]) * INFINITY;
v4.y = (v2_3.y - lightPosition[1]) * INFINITY;
v4.z = (v2_3.z - lightPosition[2]) * INFINITY;

glBegin (GL_TRIANGLE_STRIP);
glVertex3f( v1_3.x, v1_3.y, v1_3.z );
glVertex3f( v1_3.x+v3.x, v1_3.y+v3.y, v1_3.z+v3.z );
glVertex3f( v2_3.x, v2_3.y, v2_3.z );
glVertex3f( v2_3.x+v4.x, v2_3.y+v4.y, v2_3.z+v4.z );
glEnd();

//edge 4
//edge vertices
const VERTEX& v1_4 = c_v4;
const VERTEX& v2_4 = c_v1;
//distant vertices
v3.x = (v1_4.x - lightPosition[0]) * INFINITY;
v3.y = (v1_4.y - lightPosition[1]) * INFINITY;
v3.z = (v1_4.z - lightPosition[2]) * INFINITY;

v4.x = (v2_4.x - lightPosition[0]) * INFINITY;
v4.y = (v2_4.y - lightPosition[1]) * INFINITY;
v4.z = (v2_4.z - lightPosition[2]) * INFINITY;

glBegin (GL_TRIANGLE_STRIP);
glVertex3f( v1_4.x, v1_4.y, v1_4.z );
glVertex3f( v1_4.x+v3.x, v1_4.y+v3.y, v1_4.z+v3.z );
glVertex3f( v2_4.x, v2_4.y, v2_4.z );
glVertex3f( v2_4.x+v4.x, v2_4.y+v4.y, v2_4.z+v4.z );
glEnd();
}

void castShadow (const VERTEX& v1, const VERTEX& v2, const VERTEX& v3, const VERTEX& v4, GLfloat *lightPosition)
{
GLfloat a, b, c, d, side;
bool visible;

//calculate plane equation in the form: ax + by + cz + d
a = v1.y*(v2.z-v3.z) + v2.y*(v3.z-v1.z) + v3.y*(v1.z-v2.z);
b = v1.z*(v2.x-v3.x) + v2.z*(v3.x-v1.x) + v3.z*(v1.x-v2.x);
c = v1.x*(v2.y-v3.y) + v2.x*(v3.y-v1.y) + v3.x*(v1.y-v2.y);
d = -( v1.x*( v2.yv3.z - v3.yv2.z ) + v2.x*(v3.yv1.z - v1.yv3.z) + v3.x*(v1.yv2.z - v2.yv1.z) );

side = alightPosition[0]+
b
lightPosition[1]+
c*lightPosition[2]+
d;

if (side > 0)
visible = true;
else
visible = false;

//Preserve attributes that get changed
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT );

glDisable( GL_LIGHTING ); // Turn Off Lighting
glDepthMask( GL_FALSE ); // Turn Off Writing To The Depth-Buffer
glDepthFunc( GL_LEQUAL );

glEnable( GL_STENCIL_TEST ); // Turn On Stencil Buffer Testing
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); // Don’t Draw Into The Colour Buffer
glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFFL );

if (visible)
{
glFrontFace( GL_CCW );
glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
doShadowPass( v1, v2, v3, v4, lightPosition );

``````  // second shadow pass. Decrease stencil value in the shadow
glFrontFace( GL_CW );
glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
doShadowPass( v1, v2, v3, v4, lightPosition );
``````

}

glFrontFace( GL_CCW );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); // Enable rendering to colour buffer for all components

// Draw A Shadowing Rectangle Covering The Entire Screen
glColor4f( 0.0f, 0.0f, 0.0f, 0.4f );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
glPushMatrix();