Skip to main content
gamedev.net
🔒 Locked

Plain projected shadows problem

Started by celestialVoid Aug 7, 2003 at 11:36 AM 4 replies 1.4k views
Original Post
celestialVoid
celestialVoid
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]
Corrail
Corrail
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
--------------------------------------------------------There is a theory which states that if ever anybody discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable.There is another theory which states that this has already happened...
celestialVoid
celestialVoid
///// 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]
Corrail
Corrail
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
--------------------------------------------------------There is a theory which states that if ever anybody discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable.There is another theory which states that this has already happened...
celestialVoid
celestialVoid
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]
celestialVoid
celestialVoid
Edit: Problem solved.

[edited by - Wingman on August 8, 2003 4:25:54 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.