Skip to main content
gamedev.net
🔒 Locked

Drawing a 2D Triangle? [solved]

Started by amnesiasoft Dec 9, 2005 at 11:01 PM 2 replies 800+ views
Original Post
amnesiasoft
amnesiasoft
My friend and I have been working on figuring out how to draw a triangle for the past week and a half or so, and have yet to find a way that works. Some requirements for writing this are that it must be in C and is limited to the C Standard Library and anything else we write ourselves, meaning absolutely NO third party libraries. Thus far we have made three attempts, one is a slightly altered version of the method from Tricks of the Windows Game Programming Gurus, Our own from-scratch method, and converting some Delphi code (Most successful so far, still incorrect). The points I have sent are (0,0), (255,128), (0,255) which has an intended output like: # ### ##### ### # results in: # ## ### ### ### The original triangle delphi code Ported code:
void DrawTriangle(Triangle *t, Image *dst) {
	int x, y;
	int height;
	float dx_r, dx_l;
	float xs, xe;
	int xl, xr;
	int tx, ty;
	int minx, maxx, miny, maxy;
	
	//will the triangle even show up?
	//...Removed to shorten code...
	//guess so...
	
	//rearrange the points
	//...Sorting removed as it has been checked to work...

	
	xl = t->p2.x;
	
	/*
	if(t->p3.y == t->p1.y) {
		xr = 10000;
	} else {
		xr = round(t->p1.x + (t->p2.y - t->p1.y) * (t->p3.y - t->p1.y) / (t->p3.y - t->p1.y));
	} //This code caused a square on the bottom right of the output
	*/
	
	xr = min(t->p1.x, t->p3.x); //works better
	
	if(xr < xl) { //make sure the right is really on the right
		tx = xr;
		xr = xl;
		xl = tx;
	}
	
	if(t->p1.y != t->p2.y) {
		height = t->p2.y - t->p1.y;
		xs = t->p1.x;
		xe = xs;
		dx_l = (xl - t->p1.x) / height;
		dx_r = (xr - t->p1.x) / height;
		miny = max(0, t->p1.y);
		maxy = min(255,t->p2.y);
		
		for(y = miny; y <= maxy; y++) {
			minx = max(0, (int)xs);
			maxx = min(dst->w, (int)xe);
			memset(dst->r + C2to1(minx, y, dst->w), brush.r, maxx - minx); //C2to1 just converts a 2D array index into a 1D index, it works, I've used it everywhere else
			memset(dst->g + C2to1(minx, y, dst->w), brush.g, maxx - minx);
			memset(dst->b + C2to1(minx, y, dst->w), brush.b, maxx - minx);
			xs += dx_l;
			xe += dx_r;
		}
	}
	
	if(t->p2.y != t->p3.y) {
		height = t->p3.y - t->p2.y;
		dx_l = (t->p3.x - xl) / height;
		dx_r = (t->p3.x - xr) / height;
		xs = xl;
		xe = xr;
		
		if(t->p3.y >= dst->h) {
			t->p3.y = dst->h - 1;
		}
		
		miny = max(0, t->p2.y + 1);
		maxy = min(255, t->p3.y);
		
		for(y = miny; y <= maxy; y++) {
			minx = max(0, (int)xs);
			maxx = min(255, (int)xe);
			memset(dst->r + C2to1(minx, y, dst->w), brush.r, maxx - minx);
			memset(dst->g + C2to1(minx, y, dst->w), brush.g, maxx - minx);
			memset(dst->b + C2to1(minx, y, dst->w), brush.b, maxx - minx);
		}
		xs += dx_l;
		xe += dx_r;
	}
}


the structures of use in this situation we have written so far are:
typedef struct {
	Uint8 *r;	//Array containing all the red information about each pixel
	Uint8 *g;	//Array containing all the green information about each pixel
	Uint8 *b;	//Array containing all the blue information about each pixel
	//Yes I know parallel arrays are bad, but that's not the problem here
	int w;	//width of the image
	int h;	//height of the image
} Image;

typedef struct {
	int x;
	int y;
} Point;

typedef struct {
	Point p1, p2, p3;
} Triangle;


Please take note, this is not a "My code is broken, fix it post," well, it sort of is, but I've actually made attempts at fixing it before posting here. All I need is either someone to point out a stupid mistake (most likely cause) or a better example of how to draw a triangle in 2D (almost all google results are related to OpenGL in some way). Thanks in advance. [Edited by - amnesiasoft on December 10, 2005 11:05:25 PM]
intransigent-seal
intransigent-seal
Look into scan conversion (here's a link for you).

Edit: Also, Googling for "rendering triangle filling" turned up this.

John B
The best thing about the internet is the way people with no experience or qualifications can pretend to be completely superior to other people who have no experience or qualifications.
amnesiasoft
amnesiasoft
Well, from your reply, I assume you didn't even take a look at the code, as that's what I was already doing.

But, as I'd guessed, it was stupid errors. Forgot to change xs and xe inside the loop for the bottom half of the triangle.

Then just had to add a little typecasting cause I was doing some int division to calculate dx_r and dx_l. (typecast the numerator and denominator to float, and make p3.x an int)

I declare this problem solved.
intransigent-seal
intransigent-seal
Quote:
Original post by amnesiasoft
Well, from your reply, I assume you didn't even take a look at the code, as that's what I was already doing.

True (well, I skimmed it extremely briefly). I considered mentioning that in my post actually, but didn't in the end.
Mostly, I was going by "almost all google results are related to OpenGL in some way", and therefore assumed you would find some more pertinent links helpful.
Anyway, sorry I didn't help. I'm glad you managed to fix your problem.

John B
The best thing about the internet is the way people with no experience or qualifications can pretend to be completely superior to other people who have no experience or qualifications.

Topic Locked

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

Sign in to reply to this topic.