Archived

This topic is now archived and is closed to further replies.

Plain projected shadows problem

This topic is 5245 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a problem..again. This time with projective shadows. The problem is that my shadow just doesn't look like a shadow but rather than a black 3d cube. Also, if I move camera around (with gluLookAt) shadow changes position. I am almost sure that the problem occurs because of wrong-placed glPushMatrix/glPopMatrix functions. Yet, I don't know what exactly is wrong. Please help. Here is the code which draws a plain (floor):
// draw floor
void str_Render::rSurface (const float pos [3], const float size [3], const float rot [3], float deg)
{
	glBindTexture (GL_TEXTURE_2D, floor_tex->Tex);
	
        glPushMatrix ();

	glTranslatef (pos [0], pos [1], pos [2]);
	glRotatef (deg, rot [0], rot [1], rot [2]);
	glScalef (size [0], size [1], size [2]);

	// draw....

	glPopMatrix ();
}
    
The next code draws shadow-casting cube - notice the "shadow" parameter (if set to true later -> glMultMatrixf()):
///// rObject () /////
void str_Render::rObject (const float pos [3], const float size [3], float rot [3], float deg, bool shadow)
{
	glBindTexture (GL_TEXTURE_2D, obj_tex->Tex);

	glPushMatrix ();

	if (shadow) 
	{
		glMultMatrixf (shd_matrix);
	}

	glTranslatef (pos [0], pos [1], pos [2]);
	glRotatef (deg, rot [0], rot [1], rot [2]);
	glScalef (size [0], size [1], size [2]);
	
	glBegin (GL_TRIANGLE_STRIP);
        ...// draw

	glPopMatrix ();
}
    
And finally, function that displays scene:
///// fncRender () Function /////
void fncRender ()
{
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	glLoadIdentity ();

	gluLookAt (x_p, y_p, z_p, x_l, y_l, z_l, 0.0f, 1.0f, 0.0f);
	fncGetInput (); // irrelevant here


	glEnable (GL_STENCIL_TEST);


	glStencilFunc (GL_ALWAYS, 1, 1);
	glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE);
	

	glColorMask (0, 0, 0, 0);
	glDepthMask (0);
        

        // specify drawing area
	Render.rSurface (floor_pos, floor_size, floor_rot, 90.0f);


	glColorMask (1, 1, 1, 1);
	glDepthMask (1);


	glStencilFunc (GL_EQUAL, 1, 1);
	glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
        

        // draw "real" floor
	Render.rSurface (floor_pos, floor_size, floor_rot, 90.0f);


	glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);


	glEnable (GL_BLEND);
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDisable (GL_DEPTH_TEST);
	glDisable (GL_TEXTURE_2D);
	glColor4f (0.0f, 0.0f, 0.0f, 0.5f);
        
        // draw shadow - because the last parameter is set to true, glMultMatrixf () is called
	Render.rObject  (cube_pos,  cube_size,  cube_rot, cube_degrot, true);


	glColor3f (1.0f, 1.0f, 1.0f);
	glDisable (GL_BLEND);
	glEnable (GL_DEPTH_TEST);
	glEnable (GL_TEXTURE_2D);
	

	glDisable (GL_STENCIL_TEST);


	// draw rotatin cube
	Render.rObject  (cube_pos,  cube_size,  cube_rot, cube_degrot, false);

}
    
[edited by - Wingman on August 7, 2003 12:41:20 PM]

Share this post


Link to post
Share on other sites
What does you shadow matrix look like?

--------------------------------------------------------

"If it looks good, it is good"
"If it looks like computer graphics, it is not good computer graphics"

Corrail
corrail@gmx.at
ICQ#59184081

Share this post


Link to post
Share on other sites
///// fncShadowMatrix () /////
void fncShadowMatrix (float shd_matrix [16], float plane [4], float light_pos [4])
{
float dot;
dot = plane [0] * light_pos [0] + plane [1] * light_pos [1] + plane [1] * light_pos [2] + plane [3] * light_pos [3];


shd_matrix [0] = dot - light_pos [0] * plane [0];
shd_matrix [4] = 0.0f - light_pos [0] * plane [1];
shd_matrix [8] = 0.0f - light_pos [0] * plane [2];
shd_matrix [12] = 0.0f - light_pos [0] * plane [3];


shd_matrix [1] = 0.0f - light_pos [1] * plane [0];
shd_matrix [5] = dot - light_pos [1] * plane [1];
shd_matrix [9] = 0.0f - light_pos [1] * plane [2];
shd_matrix [13] = 0.0f - light_pos [1] * plane [3];


shd_matrix [2] = 0.0f - light_pos [2] * plane [0];
shd_matrix [6] = 0.0f - light_pos [2] * plane [1];
shd_matrix [10] = dot - light_pos [2] * plane [2];
shd_matrix [14] = 0.0f - light_pos [2] * plane [3];


shd_matrix [3] = 0.0f - light_pos [3] * plane [0];
shd_matrix [7] = 0.0f - light_pos [3] * plane [1];
shd_matrix [11] = 0.0f - light_pos [3] * plane [2];
shd_matrix [15] = dot - light_pos [3] * plane [3];
}



///// fncCalcDValue () /////
float fncCalcDValue (float floor_normal [3], const float floor_pos [3])
{
// A*x + B*y + C*z + D = 0; - calculates D value

float D;
D = floor_normal [0] * floor_pos [0] +
floor_normal [1] * floor_pos [1] +
floor_normal [2] * floor_pos [2];

return -D;
}

...
// these are globals:
const float floor_pos [] = { 0.0f, -2.0f, -20.0f};
float light_pos [] = { 0.0f, 15.0f, -20.0f, 1.0f};
float shd_matrix [16];
float plane [4];
float d_value;
float floor_normal [] = { 0.0f, 0.0f, 1.0f};

// called at the initialization
d_value = fncCalcDValue (floor_normal, floor_pos);
plane [0] = floor_normal [0];
plane [1] = floor_normal [1];
plane [2] = floor_normal [2];
plane [3] = d_value;

fncShadowMatrix (shd_matrix, plane, light_pos);


[edited by - Wingman on August 7, 2003 3:48:36 PM]

Share this post


Link to post
Share on other sites
Your shadow matrix looks ok...
Don''t know, sorry

--------------------------------------------------------

"If it looks good, it is good computer graphics"
"If it looks like computer graphics, it is bad computer graphics"

Corrail
corrail@gmx.at
ICQ#59184081

Share this post


Link to post
Share on other sites
I've found out what's wrong, but don't know how to fully fix it.
The problem is here, in the function which renders the cube:

....
glTranslatef (pos [0], pos [1], pos [2]);
glRotatef (deg, rot [0], rot [1], rot [2]);
glScalef (size [0], size [1], size [2]);
...

These transformations are applied to a shadow and thus it's wrong.

The cube-rendering function now looks like:

void str_Render::rObject (const float pos [3], const float size [3], float rot [3], float deg, bool shadow)
{
glBindTexture (GL_TEXTURE_2D, obj_tex->Tex);

if (shadow)
{
glPushMatrix ();
glMultMatrixf (shd_matrix);
}

glPushMatrix ();

if (shadow)
{
glTranslatef (pos [0], pos [1], pos [2]);
glRotatef (deg, rot [0], rot [1], rot [2]);
glScalef (size [0], 0.0f, size [2]);
}
else
{
glTranslatef (pos [0], pos [1], pos [2]);
glRotatef (deg, rot [0], rot [1], rot [2]);
glScalef (size [0],size [1], size [2]);
}

glBegin (GL_TRIANGLE_STRIP);
...
glPopMatrix ();

if (shadow)
{
glPopMatrix ();
}
}


The shadow looks better (2D at least), but is still very wrong. Should I change my calculations?
How to avoid wrong shadows when using transformations? Anyone?



[edited by - Wingman on August 8, 2003 6:52:26 AM]

Share this post


Link to post
Share on other sites