Can anyone help me to understand why the Shadow is not vislble?

I’m currently working on Shadow casting by referring to NeHe’s example.
Problem I have are

  • No shadow is drawn at all
  • Every time I add a new object, screen gets darker and darker

so I would like to get your help to fix the issue I have.

Below is part of source codes…

 void DrawRoom() {
	glBegin(GL_QUADS);									// Begin Drawing Quads
		// Floor
		glNormal3f(0.0f, 1.0f, 0.0f);					// Normal Pointing Up
		glVertex3f(-10.0f, -10.0f, -20.0f);				// Back Left
		glVertex3f(-10.0f, -10.0f, 20.0f);				// Front Left
		glVertex3f(10.0f, -10.0f, 20.0f);				// Front Right
		glVertex3f(10.0f, -10.0f, -20.0f);				// Back Right

		// Ceiling
		glNormal3f(0.0f, -1.0f, 0.0f);					// Normal Point Down
		glVertex3f(-10.0f, 10.0f, 20.0f);				// Front Left
		glVertex3f(-10.0f, 10.0f, -20.0f);				// Back Left
		glVertex3f(10.0f, 10.0f, -20.0f);				// Back Right
		glVertex3f(10.0f, 10.0f, 20.0f);				// Front Right

		// Front Wall
		glNormal3f(0.0f, 0.0f, 1.0f);					// Normal Pointing Away From Viewer
		glVertex3f(-10.0f, 10.0f, -20.0f);				// Top Left
		glVertex3f(-10.0f, -10.0f, -20.0f);				// Bottom Left
		glVertex3f(10.0f, -10.0f, -20.0f);				// Bottom Right
		glVertex3f(10.0f, 10.0f, -20.0f);				// Top Right

		// Back Wall 
		glNormal3f(0.0f, 0.0f, -1.0f);					// Normal Pointing Towards Viewer
		glVertex3f(10.0f, 10.0f, 20.0f);				// Top Right
		glVertex3f(10.0f, -10.0f, 20.0f);				// Bottom Right
		glVertex3f(-10.0f, -10.0f, 20.0f);				// Bottom Left
		glVertex3f(-10.0f, 10.0f, 20.0f);				// Top Left

		// Left Wall
		glNormal3f(1.0f, 0.0f, 0.0f);					// Normal Pointing Right
		glVertex3f(-10.0f, 10.0f, 20.0f);				// Top Front
		glVertex3f(-10.0f, -10.0f, 20.0f);				// Bottom Front
		glVertex3f(-10.0f, -10.0f, -20.0f);				// Bottom Back
		glVertex3f(-10.0f, 10.0f, -20.0f);				// Top Back

		// Right Wall
		glNormal3f(-1.0f, 0.0f, 0.0f);					// Normal Pointing Left
		glVertex3f(10.0f, 10.0f, -20.0f);				// Top Back
		glVertex3f(10.0f, -10.0f, -20.0f);				// Bottom Back
		glVertex3f(10.0f, -10.0f, 20.0f);				// Bottom Front
		glVertex3f(10.0f, 10.0f, 20.0f);				// Top Front
	glEnd();											// Done Drawing Quads
}

void DrawScene(Object3D &object, Light &light, GL_Window &glView) {
	GLmatrix16f mvMatrix;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	// Enable Light and Lighting
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHTING);

	// Reset the current viewport
	glViewport(0, 0, glView.Width, glView.Height);				

	// Select and reset the Projection Matrix
 	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// Calculate the aspect ratio of the window
	gluPerspective(45.0f, (GLfloat)glView.Width / (GLfloat)glView.Height, 0.001f, 100.0f);

	// Select and reset the Modelview Matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	// Position Light and zoom into screen 20 units
	glLightfv(GL_LIGHT1, GL_POSITION, LightPos);
	glTranslatef(0.0f, 0.0f, -20.0f);

	// Set color to an Orange and position the sphere then draw sphere
	glColor4f(1.0f, 0.2f, 0.0f, 1.0f);
	glTranslatef(SpherePos[0], SpherePos[1], SpherePos[2]);
	gluSphere(light.quadric, 1.5f, 32, 16);

	// Reset Matrix
	glLoadIdentity();

	// Retrieve ModelView Matrix
	glGetFloatv(GL_MODELVIEW_MATRIX, mvMatrix);

	// Store Light vector
	light.data[0].VMatMult(mvMatrix, light.position);

	// Retrieve ModelView Matrix
	glGetFloatv(GL_MODELVIEW_MATRIX, mvMatrix);															

	// World Local Coord X, Y, Z to 0
	light.worldCoordinate[0] = 0.0f;
	light.worldCoordinate[1] = 0.0f;
	light.worldCoordinate[2] = 0.0f;
	light.worldCoordinate[3] = 1.0f;

	// Store the position of world relative to the local Coordinate system
	light.data[0].VMatMult(mvMatrix, light.worldCoordinate);

	// Retrieve position of Light relative to the local coordinate system
	light.position[0] += light.worldCoordinate[0];
	light.position[1] += light.worldCoordinate[1];
	light.position[2] += light.worldCoordinate[2];

	// Reset Modelview Matrix andd zoom into the screen 20 units
	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -20.0f);

	// Draw Room
	DrawRoom();

	// Zoom into screen 20 units
	glTranslatef(0.0f, 0.0f, -20.0f);

	// Draw object
	glBegin(GL_TRIANGLES);
 	for (int i = 0; i < object.vSurfaceCount; i++) {
		glNormal3f(object.vSurfaces[i].normal.x, object.vSurfaces[i].normal.y, object.vSurfaces[i].normal.z);
		glVertex3f(object.vPoints[object.vSurfaces[i].p1].position.x, object.vPoints[object.vSurfaces[i].p1].position.y, object.vPoints[object.vSurfaces[i].p1].position.z);
		glVertex3f(object.vPoints[object.vSurfaces[i].p2].position.x, object.vPoints[object.vSurfaces[i].p2].position.y, object.vPoints[object.vSurfaces[i].p2].position.z);
		glVertex3f(object.vPoints[object.vSurfaces[i].p3].position.x, object.vPoints[object.vSurfaces[i].p3].position.y, object.vPoints[object.vSurfaces[i].p3].position.z);
 	}
	glEnd();

	// Cast Shadow
	CastShadow(light, 0, object);

	// Set Color To Purplish Blue
	glColor4f(0.7f, 0.4f, 0.0f, 1.0f);

	// Disable Lighting and Depth Mask
	glDisable(GL_LIGHTING);
	glDepthMask(GL_FALSE);

	// Translate to Light's position, we're still in local coordinate system
	glTranslatef(light.position[0], light.position[1], light.position[2]);

	// Draw a little yellow sphere (Represents Light)
	gluSphere(light.quadric, 0.2f, 16, 8);

	glLoadIdentity();

	// Enable Lighting and Depth mask
	glEnable(GL_LIGHTING);
	glDepthMask(GL_TRUE);

	// Flush the OpenGL pipeline
	glFlush();

	// Swap buffers (Double buffering)
	SwapBuffers(glView.hDC);
 }

void CalculatePlane(Surface3D &vSurface, Point3D *vPoints) {
	Coordinate3D v1 = vPoints[vSurface.p1].position;
	Coordinate3D v2 = vPoints[vSurface.p2].position;
	Coordinate3D v3 = vPoints[vSurface.p3].position;

	vSurface.pEquation.a = v1.y * (v2.z - v3.z) + v2.y * (v3.z - v1.z) + v3.y * (v1.z - v2.z);
	vSurface.pEquation.b = v1.z * (v2.x - v3.x) + v2.z * (v3.x - v1.x) + v3.z * (v1.x - v2.x);
	vSurface.pEquation.c = v1.x * (v2.y - v3.y) + v2.x * (v3.y - v1.y) + v3.x * (v1.y - v2.y);
	vSurface.pEquation.d = -(v1.x * (v2.y * v3.z - v3.y * v2.z) + v2.x * (v3.y * v1.z - v1.y * v3.z) + v3.x * (v1.y * v2.z - v2.y * v1.z));
}

void Normalize(Surface3D &vSurface, Point3D *vPoints) {
	GLdouble Ux = vPoints[vSurface.p2].position.x - vPoints[vSurface.p1].position.x;
	GLdouble Uy = vPoints[vSurface.p2].position.y - vPoints[vSurface.p1].position.y;
	GLdouble Uz = vPoints[vSurface.p2].position.z - vPoints[vSurface.p1].position.z;

	GLdouble Vx = vPoints[vSurface.p3].position.x - vPoints[vSurface.p1].position.x;
	GLdouble Vy = vPoints[vSurface.p3].position.y - vPoints[vSurface.p1].position.y;
	GLdouble Vz = vPoints[vSurface.p3].position.z - vPoints[vSurface.p1].position.z;

	vSurface.normal.y = (Uz * Vx) - (Ux * Vz);
	vSurface.normal.z = (Ux * Vy) - (Uy * Vx);
	vSurface.normal.x = (Uy * Vz) - (Uz * Vy);
}

// Cast shadow
void CastShadow(Light &light, Object3D &object, int objectIndex) {
	int	i, j, k, jj;
	int	p1, p2;
	Coordinate3D v1, v2;
	float side;

	// Set visual parameter
	for (i = 0; i < object.vSurfaceCount; i++) {
		// Check to see if light is in front or behind the plane (face plane)
		side = object.vSurfaces[i].pEquation.a * light.position[0] +
			   object.vSurfaces[i].pEquation.b * light.position[1] +
			   object.vSurfaces[i].pEquation.c * light.position[2] +
			   object.vSurfaces[i].pEquation.d * light.position[3];

		if (side > 0)
			object.vSurfaces[i].IsShadowed = false;

		else
			object.vSurfaces[i].IsShadowed = true;
	}

	glDisable(GL_LIGHTING);
	glDepthMask(GL_FALSE);
	glDepthFunc(GL_LEQUAL);

	glEnable(GL_STENCIL_TEST); 
	glColorMask(0, 0, 0, 0);
	glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

	// First pass, stencil operation decreases stencil value
	glFrontFace(GL_CCW);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);

	for (i = 0; i < object.vSurfaceCount; i++) {
		if (!object.vSurfaces[i].IsShadowed) {
			for (j = 0; j < 3; j++) {
				k = object.vSurfaces[i].neighbor[j]; 

			if ((k == -1) || (object.vSurfaces[k - 1].IsShadowed)) {
				// Here we have an edge, we must draw a polygon
				p1 = object.vSurfaces[i].index[j];
				jj = (j + 1) % 3;
				p2 = object.vSurfaces[i].index[jj];

				// Calculate the length of the vector
				v1.x = (object.vPoints[p1].position.x - light.position[0]) * 100;
				v1.y = (object.vPoints[p1].position.y - light.position[1]) * 100;
				v1.z = (object.vPoints[p1].position.z - light.position[2]) * 100;

				v2.x = (object.vPoints[p2].position.x - light.position[0]) * 100;
				v2.y = (object.vPoints[p2].position.y - light.position[1]) * 100;
				v2.z = (object.vPoints[p2].position.z - light.position[2]) * 100;

				// Draw the polygon
				glBegin(GL_TRIANGLE_STRIP);
					glVertex3f(object.vPoints[p1].position.x, object.vPoints[p1].position.y, object.vPoints[p1].position.z);
					glVertex3f(object.vPoints[p1].position.x + v1.x, object.vPoints[p1].position.y + v1.y, object.vPoints[p1].position.z + v1.z);
					glVertex3f(object.vPoints[p2].position.x, object.vPoints[p2].position.y, object.vPoints[p2].position.z);
					glVertex3f(object.vPoints[p2].position.x + v2.x, object.vPoints[p2].position.y + v2.y, object.vPoints[p2].position.z + v2.z);
				glEnd();
			}
		}
	}
}

// Second pass, stencil operation increases stencil value
glFrontFace(GL_CW);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);

for (i = 0; i < object.vSurfaceCount; i++) {
	if (!object.vSurfaces[i].IsShadowed) {
		for (j = 0; j < 3; j++) {
			k = object.vSurfaces[i].neighbor[j];

				if ((k == -1) || (object.vSurfaces[k - 1].IsShadowed)) {
					// Here we have an edge, we must draw a polygon
					p1 = object.vSurfaces[i].index[j];
					jj = (j + 1) % 3;
					p2 = object.vSurfaces[i].index[jj];

 				// Calculate the length of the vector
					v1.x = (object.vPoints[p1].position.x - light.position[0]) * 100;
					v1.y = (object.vPoints[p1].position.y - light.position[1]) * 100;
					v1.z = (object.vPoints[p1].position.z - light.position[2]) * 100;

					v2.x = (object.vPoints[p2].position.x - light.position[0]) * 100;
					v2.y = (object.vPoints[p2].position.y - light.position[1]) * 100;
					v2.z = (object.vPoints[p2].position.z - light.position[2]) * 100;

					// Draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
						glVertex3f(object.vPoints[p1].position.x, object.vPoints[p1].position.y, object.vPoints[p1].position.z);
						glVertex3f(object.vPoints[p1].position.x + v1.x, object.vPoints[p1].position.y + v1.y, object.vPoints[p1].position.z + v1.z);
						glVertex3f(object.vPoints[p2].position.x, object.vPoints[p2].position.y, object.vPoints[p2].position.z);
						glVertex3f(object.vPoints[p2].position.x + v2.x, object.vPoints[p2].position.y + v2.y, object.vPoints[p2].position.z + v2.z);
					glEnd();
				}
			}
		}
 	}

   	glFrontFace(GL_CCW);
   	glColorMask(1, 1, 1, 1);

 	// 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, 0xffffffff);
 	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 	glPushMatrix();
 	glLoadIdentity(); 

	glBegin(GL_TRIANGLE_STRIP);
		glVertex3f(-0.1f, 0.1f, -0.1f);
		glVertex3f(-0.1f, -0.1f, -0.1f);
		glVertex3f(0.1f, 0.1f, -0.1f);
		glVertex3f(0.1f, -0.1f, -0.1f);
  	glEnd();

	glPopMatrix();
	glDisable(GL_BLEND);

 	glDepthFunc(GL_LEQUAL);
	glDepthMask(GL_TRUE);
	glEnable(GL_LIGHTING);
	glDisable(GL_STENCIL_TEST);
	glShadeModel(GL_SMOOTH);
}

Below is what I can see when I compile it, so no shadow is drawn…and the screen gets darker


Thanks in advance

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.