Jump to content
  • Advertisement

Archived

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

Cestps

Triangle drawing malfunction

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


  
void DrawTriangle(SDL_Surface* screen, line* pLine[3])
{
	bool good, xor1, xor2;
	unsigned char valid[2];
	int over, under;

	for(int y=0;y<480;y++)		//	This loops through every

	{							//	single pixel on the screen,

		for(int x=0;x<640;x++)	//	it  r e a l l y  should be

		{						//	optimized.

			good=0;
			valid[0]=0;
			valid[1]=0;
			over=0; under=0;

			for(int n=0;n<3;n++)
			{
				xor1=0;
				xor2=0;

				if(pLine[n]->ax < x)	//	Custom XOR-

					xor1 = 1;			//	function,

				if(pLine[n]->bx < x)	//	kind of.

					xor2 = 1;

				if(xor1 - xor2 != 0)	//	Proceed if the point

				{						//	is to the right of one

					valid[good]=n;		//	and only one of the lines

					good=1;				//	ends.

				}
			}
			
			if(good==1)	//	Did We Have A Winner?

			{
				if((pLine[valid[0]]->ax + pLine[valid[0]]->bx)/2 > (pLine[valid[1]]->ax + pLine[valid[1]]->bx)/2)
				{					//	Î Long if-statement, checks if A is over B or vice versa.

					over=valid[1];
					under=valid[0];
				}
				else
				{
					over=valid[0];
					under=valid[1];
				}

				pLine[over]->k = (pLine[over]->bx - pLine[over]->ax)/(pLine[over]->by - pLine[over]->ay);
				pLine[under]->k = (pLine[under]->bx - pLine[under]->ax)/(pLine[under]->by - pLine[over]->ay);
									//	Calculate the "inclination coefficient" of the lines


				if(y < pLine[over]->k*x + pLine[over]->ay && y > pLine[under]->k*x + pLine[under]->ay)
					DrawPixel(screen, x, y, 255, 255, 255);
									//	Finally check if it is between the two lines, and draw it.

			}	//	Only 640*480-1 to go..

		}	
	}			
	return;		
}				
  
Now, let me explain what this is. It is a polygon drawing function for a software renderer thingy I''m working on (I know, this one is horribly slow), it takes two arguments: The surface to draw on, and a pointer array to a struct called line. THe definition of line is as follows:
  
struct line{
	int ax;  //Left X coordinate

	int ay;  //Left Y coordinate

	int bx;  //Right X coordinate

	int by;  //Right Y coordinate

	double k;  //Inclination coefficient

};
  
The function works (or rather, is supposed to work) like this: 1. We know the positions of three points. These we bind together with three lines, to create a triangle. We call the lines A, B, and C, and their ends A1, A2, B1.. 2. We then loop through all points. For each point we check: a. Is the point to the right of one, but only one, of the ends of each line? b. If a was true for no lines, abort and go to next point. c. If a was true for two lines, remember those. (As they will have the point over/under them) d. Check if the middlepoint of one of those lines is higher than the other. Remember which is upper. e. Using the formula y=kx+m, where ''k'' is the inclination coefficient, ''m'' the y position of the left end of the line, ''x'' the x position of the point, and ''y'' the y position of the part of the line diretly under/over the point, check if the point is under the upper line and over the under line. f. If e is false, abort and go to next point. g. Otherwise, plot a pixel at the point, abort, and go to next point. Now for the problem: When run the program looks like this:
  
XXXXXOOOXXXXXXX
XXXXXOOOXXXXXXX
XXXXXOOÖXXXXXXX
XXXXXÖOOXXXXXXX
XXXXXOOÖXXXXXXX
XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX
  
X=Background O=The triangle! ¨=Where the triangles vertices Should Have Been. I''m really stumped on this problem. Can someone who is good in maths (Or at spotting that stupid little mistakes that ruin things like this) help me out?

Share this post


Link to post
Share on other sites
Advertisement
I may have found where your problem is and can offer you some optimization tips as well.

Your problem is where you calculate your "inclination coefficients" (please use the correct term, slopes). You are dividing two ints together, which means that the result will be truncated no matter what type the variable you are assigning to is. You could have a slope of 0.15 but it will still show up as 0. To fix the problem, typecast your ax, bx, etc. to double before doing the divide.

pLine[over]->k = (double)(pLine[over]->bx - pLine[over]->ax)/(double)(pLine[over]->by - pLine[over]->ay);
pLine[under]->k = (double)(pLine[under]->bx - pLine[under]->ax)/(double)(pLine[under]->by - pLine[over]->ay);

For optimization purposes:
1) C has an exclusive-OR operator which is the caret (^). You would rather do this in hardware than software.
2) When you compare if A is over B or vice versa, take out the divide-by-two''s. Comparing if (x/2 > y/2) is the same as comparing if (x > y).

These are just off the top of my head.

Share this post


Link to post
Share on other sites
Sorry for being a newbie, but is ''^'' not *bit-level* XOR?

We drink milk in Sweden! And we osthyvlar our own ost!

Share this post


Link to post
Share on other sites
Oh, and now it outputs this:

  
XXXXXOOOXXXXXXX
XXXXXOOOXXXXXXX
XXXXXOOÖXXXXXXX
XXXXXÖOOXXXXXXX
XXXXXXXÖXXXXXXX
XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX


The lower part is perfectly rendered, however the upper is obviously not.

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!