Jump to content
  • Advertisement

Archived

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

Cipher3D

2D Shadow problem

This topic is 5326 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

Hi, I''m trying to implement 2D shadows based on Orangy Tang''s 2D shadow article, and I''ve implemented most of things right, except for the actual shadow generation. his article was good, but I''m somewhat of a noob to vector calculations, and I''ve hacked together an implementation that doesn''t work the way it should. Here is my shadow creation algorithm/code: The part you should focus on is in between the second FOR loop... Sorry, it may seem like a ton of code, but its what i have. Thank you so very much in advance, Cipher3D

void cLightManager::DrawObjectShadows(cLight* light)
{
	if (!light)
		return;

	for (int c=0;c<m_vertexList.size();c++)
	{
		
		int numEdges = sizeof(m_vertexList[c]);
		vector<typVertex> shadowGeometry;
		bool *frontfacing = new bool[numEdges];

		for (int g=0;g<numEdges;g++)
			frontfacing[g] = false;

		for (g=0;g<numEdges;g++)
		{
			if (light->x == 50)
			{
				int body;
    			body++;
			}

			int prev = (g == 0 ? numEdges-1 : g-1);

						//for each edge

			int x,y;

			x = m_vertexList[c][g].x-m_vertexList[c][prev].x;
			y = m_vertexList[c][g].y-m_vertexList[c][prev].y;

			
			if (light->x > m_vertexList[c][g].x)
			{
				x = -x;
			}
			if (light->y > m_vertexList[c][g].y)
			{
				y = -y;
			} //end if


			float dot = (x*light->x)+(y*light->y);

			//check whats the result of dot

			if (dot < 0)
			{
				float vertx,verty,projx,projy;

				//boundary = true;

				frontfacing[g] = true;
				
				//then we add to shadow geometry

				shadowGeometry.push_back(m_vertexList[c][prev]);

				projx = m_vertexList[c][prev].x-light->x;
				projy = m_vertexList[c][prev].y-light->y;

				vertx = m_vertexList[c][prev].x;
				verty = m_vertexList[c][prev].y;

				projx *= light->size/100.0f; projy *= light->size/100.0f;
				vertx+=projx;
				verty+=projy;
				typVertex s = {vertx,verty};

				shadowGeometry.push_back(s);
				
			} //end if

			else
			{
				if (frontfacing[prev])
				{
					shadowGeometry.push_back(m_vertexList[c][prev]);
				} //end if

			} //end else



				
		} //done 


		if (frontfacing)
			delete frontfacing;

		//NOW draw the frickin shadow

		glBlendFunc(GL_ZERO,GL_ZERO);

		glBegin(GL_TRIANGLE_STRIP);
		glColor4f(0,0,0,1.0f);
		for (int ang = 0;ang<shadowGeometry.size();ang++)
		{
			int x = shadowGeometry[ang].x;
			int y = shadowGeometry[ang].y;

			if (x < 0)
				x = 0;
			if (y < 0)
				y = 0;
			if (x > g_pVideo->GetWidth())
				x = g_pVideo->GetWidth();
			if (y > g_pVideo->GetHeight())
				y = g_pVideo->GetHeight();

			glVertex2f(x,y);
		}

	glEnd();

	shadowGeometry.empty();

	} //end for



} //end



Share this post


Link to post
Share on other sites
Advertisement
of all things, i forgot to state the problem...

there are several weird shadow "artifacts..." I''ll post a screen shot tommorow...ugh...

Share this post


Link to post
Share on other sites
Hmm, I''m not totally sure if I''m reading your code right, but the one thing that jumps out at me is in the last drawing loop:
if (x < 0)
x = 0;
if (y < 0)
y = 0;

if (x > g_pVideo->GetWidth())
x = g_pVideo->GetWidth();

if (y > g_pVideo->GetHeight())
y = g_pVideo->GetHeight();

Clamping the x and the y like that will restrict them to the screen edges, but it will mess up the angle of the shadow because you''re changing one but not the other appropriatly.

I don''t actually calculate this accuratly, I just find the distance across the screen diagonal and shift them back by this amount. This way I get something thats guaranteed to be off the screen edges, but not by huge amounts.

If thats not the only problem my suggestion is to start drawing debug geometry like lines to show the intermediate results (like drawing the faces you tag as front facing in wireframe and a different colour).

Share this post


Link to post
Share on other sites
I've decided to explain my code a little bit...

the first FOR loop just loops through all the objects I added in the list so it can create a shadow for each object.

the second for loop is where it creates the actual shadow for the object.

ignore the

if (light->x == 50)
{
int body;
body++;
}

its just a debugging thing..


int prev = (g == 0 ? numEdges-1 : g-1);

this just gets the previous vertex...some mundane boolean stuff..

the

int x,y;
x = m_vertexList[c][g].x-m_vertexList[c][prev].x;
y = m_vertexList[c][g].y-m_vertexList[c][prev].y;

just calculates the normal between a point and the previous point...basiclaly the normal for the edge of the figure..

if (light->x > m_vertexList[c][g].x)
{
x = -x;
}
ditto for Y component

this inverts x..because I have to compute the dot product of the normal and the light vector..and it the normal for the edge has to be in a counterclockwise thingy RELATIVE to the light..

float dot = (x*light->x)+(y*light->y);

here's where I compute the actuall dot

the next if body just adds two vertices to the shadow geometry "array" (a STL vector) to draw.

first it adds the previous point (because the shadow point starts at the previous point, or the first point of the edge),
(if you don't understand what I mean, just imagine a square and run through my algorithm in your head),

then it projects to the end of the screen for the shadow, and adds that vertex

and the else is supposed to account for the last vertex...however it comes up with a bunch of weird shadow artifacts, such as the second picture...

and if I remove that statement, there are no more weird artifacts, except for one thing: its missing the last triangle stip, so it doesn't render the whole shadow...just look at the last screen shot and you'll see what i mean...

[edited by - Cipher3D on January 13, 2004 8:41:13 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!