nele lesson 27 stencil

Started by
3 comments, last by xycsoscyx 8 years, 5 months ago

Hello i am new here and in opengl programming. I recently add nehe's stencil shadows to my project and its works great. No problem at all when i load ONE obj from the txt. When i load TWO objects from 2 different txt's, the shadow of the FIRST obj becomes darker and it is not blended with second's obj shadow.

I 'll appreciate any help...

Here is the pic of my problem...[attachment=29528:??????????? ?????? (11).png]

Advertisement

Here is the code of the shadow rendering.


void  CastShadow(glObject *o, float *lp){
	
	unsigned int	i, j, k, jj;
	unsigned int	p1, p2;
	sPoint			v1, v2;
	float			side;

	//set visual parameter
	for (i=0;i<o->nPlanes;i++){
		// chech to see if light is in front or behind the plane (face plane)
		side =	o->planes[i].PlaneEq.a*lp[0]+
				o->planes[i].PlaneEq.b*lp[1]+
				o->planes[i].PlaneEq.c*lp[2]+
				o->planes[i].PlaneEq.d*lp[3];
		if (side >0) o->planes[i].visible = TRUE;
				else o->planes[i].visible = FALSE;
	}
	glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT );
 	glDisable(GL_LIGHTING);
	glDepthMask(GL_FALSE);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_STENCIL_TEST);
	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); 
	glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFFL );

	// first pass, stencil operation decreases stencil value
	glFrontFace(GL_CCW);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
	for (i=0; i<o->nPlanes;i++){
		if (o->planes[i].visible)
			for (j=0;j<3;j++){
				k = o->planes[i].neigh[j];
				if ((!k) || (!o->planes[k-1].visible)){
					// here we have an edge, we must draw a polygon
					p1 = o->planes[i].p[j];
					jj = (j+1)%3;
					p2 = o->planes[i].p[jj];

					//calculate the length of the vector
					v1.x = (o->points[p1].x - lp[0])*100;
					v1.y = (o->points[p1].y - lp[1])*100;
					v1.z = (o->points[p1].z - lp[2])*100;

					v2.x = (o->points[p2].x - lp[0])*100;
					v2.y = (o->points[p2].y - lp[1])*100;
					v2.z = (o->points[p2].z - lp[2])*100;
					
					//draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
						glVertex3f(o->points[p1].x,
									o->points[p1].y,
									o->points[p1].z);
						glVertex3f(o->points[p1].x + v1.x,
									o->points[p1].y + v1.y,
									o->points[p1].z + v1.z);

						glVertex3f(o->points[p2].x,
									o->points[p2].y,
									o->points[p2].z);
						glVertex3f(o->points[p2].x + v2.x,
									o->points[p2].y + v2.y,
									o->points[p2].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<o->nPlanes;i++){
		if (o->planes[i].visible)
			for (j=0;j<3;j++){
				k = o->planes[i].neigh[j];
				if ((!k) || (!o->planes[k-1].visible)){
					// here we have an edge, we must draw a polygon
					p1 = o->planes[i].p[j];
					jj = (j+1)%3;
					p2 = o->planes[i].p[jj];

					//calculate the length of the vector
					v1.x = (o->points[p1].x - lp[0])*100;
					v1.y = (o->points[p1].y - lp[1])*100;
					v1.z = (o->points[p1].z - lp[2])*100;

					v2.x = (o->points[p2].x - lp[0])*100;
					v2.y = (o->points[p2].y - lp[1])*100;
					v2.z = (o->points[p2].z - lp[2])*100;
					
					//draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
						glVertex3f(o->points[p1].x,
									o->points[p1].y,
									o->points[p1].z);
						glVertex3f(o->points[p1].x + v1.x,
									o->points[p1].y + v1.y,
									o->points[p1].z + v1.z);

						glVertex3f(o->points[p2].x,
									o->points[p2].y,
									o->points[p2].z);
						glVertex3f(o->points[p2].x + v2.x,
									o->points[p2].y + v2.y,
									o->points[p2].z + v2.z);
					glEnd();
				}
			}
	}

	glFrontFace(GL_CCW);
	glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );

	//draw a shadowing rectangle covering the entire screen
	glColor4f(0.0f, 0.0f, 0.0f, 0.6f);
	
	
	glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
	glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
	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();
	
	glDepthFunc(GL_LEQUAL);
	glDepthMask(GL_TRUE);
	glEnable(GL_LIGHTING);
	glDisable(GL_STENCIL_TEST);
	glShadeModel(GL_SMOOTH);
	glPopAttrib();
}

to explain sth. The object data( vertices, texture coordinates, normals) are saved in txt file and a loader loads it to the project. The cross and the pavemnt in the pic are two fifferent objects saved in two different txt files. If i put them together in the same txt file there is not shadow problem...

What does your scene look like when you turn shadows off for object 1 and just leave shadows on for object 2 (the cross)? I wonder if this is an artifact of you compounding the shadows which are rendered with an alpha value of 0.6.

Basically, you're currently using alpha to darken the shadow areas, instead of using additive blending to lighten the lit areas. You treat each shadow as it's own volume, and then blend that volume onto the screen darkening the area. To prevent darker darkening with the overlapped areas, you need to flip it around a bit. Separate the passes per light, render the shadow volume into the stencil buffer, then render the each light with it's stencil so that you only lighten the areas that aren't shadowed. This lets you use additive blending and increase the luminosity of lit areas, rather than increasing the darkness of shadowed areas.

This topic is closed to new replies.

Advertisement