Jump to content


rendering a triangle in software


26 replies to this topic

#1 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 15 January 2004 - 06:29 PM

just an old code snippet i found on one of my code backup cds. i removed the clipping parts from the code since they don't really belong to the snippet title

void SoftRasta::renderTriangleSolid16(RenderTriangle &t, unsigned char* buffer, unsigned short &pitch)
{
	int i0 = 0, i1 = 1, i2 = 2;
	
	// sort verts by height
	if(t.coords[i0].y > t.coords[i1].y) mySwap(i0, i1);
	if(t.coords[i0].y > t.coords[i2].y) mySwap(i0, i2);
	if(t.coords[i1].y > t.coords[i2].y) mySwap(i1, i2);
	
	int x0 = (int)t.coords[i0].x, y0 = (int)t.coords[i0].y;
	int x1 = (int)t.coords[i1].x, y1 = (int)t.coords[i1].y;
	int x2 = (int)t.coords[i2].x, y2 = (int)t.coords[i2].y;
	
	unsigned short pitch16 = pitch >> 1;
	
	// test for easy cases, else split trinagle in two and render both halfs
	if(y1 == y2){
 
 if(x1 > x2) mySwap(x1, x2);
 renderFlatTriangle16(x1, y1, x2, y2, x0, y0, buffer, pitch16, t.color);
	}
	else if(y0 == y1){
 
 if(x0 > x1) mySwap(x0, x1);
 renderFlatTriangle16(x0, y0, x1, y1, x2, y2, buffer, pitch16, t.color);
	}
	else{
 
 // compute x pos of the vert that builds the splitting line with x1
 int tmp_x = x0 + (int)(0.5f + (float)(y1-y0) * (float)(x2-x0) / (float)(y2-y0));
 
 if(x1 > tmp_x) mySwap(x1, tmp_x);
 renderFlatTriangle16(x1, y1, tmp_x, y1, x0, y0, buffer, pitch16, t.color);
 renderFlatTriangle16(x1, y1, tmp_x, y1, x2, y2, buffer, pitch16, t.color);
	}
}

void SoftRasta::renderFlatTriangle16(int x0, int y0, int x1, int y1, int x2, int y2, unsigned char* buffer, unsigned short pitch16, unsigned short color)
{
	unsigned short* pixel = NULL;
	
	// compute slopes for the two triangle legs
	float dx0 = (float)(x2 - x0) / (y2 - y0);
	float dx1 = (float)(x2 - x1) / (y2 - y1);
	
	int yRange = 0;
	
	float lx = (float) x0, rx = (float) x1;
	
	if(y0 < y2){ yRange = y2 - y0; pixel = (unsigned short*)buffer + y0 * pitch16; }
	else  { yRange = y0 - y2; pixel = (unsigned short*)buffer + y2 * pitch16; lx = rx = (float)x2; }
	
	for(int i=0; i<yRange; ++i){
 	
 for(int j=(int)(lx); j<(int)((rx) + 1.0f); ++j){
  
 	*(pixel + j) = color;
 }
 	
 lx  += dx0;
 rx  += dx1;
 pixel += pitch16;
	}
}

If Prolog is the answer, what is the question ?

#2 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 15 January 2004 - 11:52 PM

on a second thought the textured version might have been more interesting
maybe i can dig them up, too
If Prolog is the answer, what is the question ?

#3 Dia

    DevMaster Staff

  • Administrators
  • 1120 posts

Posted 16 January 2004 - 03:59 AM

Very interesting indeed...is this part of a software renderer you made?

#4 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 16 January 2004 - 11:40 AM

i guess. it was a seperate code file i backed up for some reason. it must be several years old. i was surprised that the cd still worked at all. i'm trying to find more pieces of that renderer
If Prolog is the answer, what is the question ?

#5 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 16 January 2004 - 04:01 PM

which reminds me, is there going to be an update on the software rendering tuts ? maybe i can be of help ???
If Prolog is the answer, what is the question ?

#6 Dia

    DevMaster Staff

  • Administrators
  • 1120 posts

Posted 17 January 2004 - 01:29 AM

That's a good idea! Or maybe you could write your own tutorial on rendering a triangle (with texturing maybe) as well as explaining the math and theory behind it. That would be an excellent tutorial.

#7 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 17 January 2004 - 09:26 AM

i'll consider that
If Prolog is the answer, what is the question ?

#8 Mihail121

    Senior Member

  • Members
  • PipPipPipPip
  • 1059 posts

Posted 20 January 2004 - 10:36 AM

This reminds me something too.... i always wondered how the trick which Chris Hecker discusses in his article actually works. I mean the stuff that you can precalculate the slopes only once and use combinations of them during the rendering process. If someone can point me to an article/tutorials that discusses that in detail and with nice and clean explanations i'll give that person five virtual bucks!!!

#9 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 20 January 2004 - 12:49 PM

i thought the trick he did was not interpolating 1/z every pixel but only every n pixels... anyway, it's also at least 4-5 years since i read that particular article. i'll reread it if i can still find it. a lot of the good old information seems to be disappearing these days. maybe you have a link to it ?

[EDIT] : nm, his own site is still active... [/EDIT]
If Prolog is the answer, what is the question ?

#10 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 20 January 2004 - 12:54 PM

hmmm, just pondered about this. if the difference between the z coords is small enough you might just use affine mapping.
though it's not a very brilliant idea it might speed up rendering by a big margin...
If Prolog is the answer, what is the question ?

#11 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 20 January 2004 - 12:56 PM

sry, i completely misunderstood your post... anways, let me read through that article again...
If Prolog is the answer, what is the question ?

#12 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 20 January 2004 - 09:42 PM

well, the trick you are reffering to is just 9th grade trigonometry. you should take a piece of paper and work it out. it's quite simple actually...
i don't even know how to explain it better than he does. it's all there in his paper.
If Prolog is the answer, what is the question ?

#13 Mihail121

    Senior Member

  • Members
  • PipPipPipPip
  • 1059 posts

Posted 24 January 2004 - 09:44 AM

I'm not having problems with maths but i'm having troubles to translate that article from english :))) . Anyway i'll try some more. 10x

P.S.
The stuff with the dissapearing knowledge is true!!!

#14 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 25 January 2004 - 05:43 PM

sry, i didn't mean to be rude. anyways, if you can't understand the article we would have a hard time explaining it to you in englsih ;)
If Prolog is the answer, what is the question ?

#15 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 07 September 2004 - 09:26 PM

Here's another way to sort vertices conveniently, without using indices:
void Rasterizer::drawTriangle(const Vertex *V1, const Vertex *V2, const Vertex *V3)
{
	if(V1->y > V3->y) swap(V1, V3);
	if(V2->y > V3->y) swap(V2, V3);
	if(V1->y > V2->y) swap(V1, V2);

	const Vertex &v1 = *V1;
	const Vertex &v2 = *V2;
	const Vertex &v3 = *V3;
...
Vertices get passed as pointers, then they are sorted by swapping the pointers, and finally the pointers are dereferences so you can work with . instead of -> all the time. All my other parameters are in a 'context' structure directly accessible for the Rasterizer class. This avoids passing all the arguments to the function.

Just a suggestion. Makes the code very clean in my opinion...

#16 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 07 September 2004 - 09:33 PM

By the way, Chris Hecker's articles are worth gold when implementing a software rasterizer. I read each of them three times or more, and it was well worth it to understand every little bit he talks about.

Anyway, even though he presents the legacy method of rendering triangles, there are (better) alternatives. Triangle Scan Conversion using 2D Homogeneous Coordinates is more optimal for advanced rasterization...

#17 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 07 September 2004 - 09:54 PM

yeah... the articles are great. i loved them.
If Prolog is the answer, what is the question ?

#18 davepermen

    Senior Member

  • Members
  • PipPipPipPip
  • 1306 posts

Posted 15 September 2004 - 10:41 AM

maybe we could link both topics together. yours having a link to nicks, and nicks back to yours, to show the two possible ways 'as one'
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....

#19 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 15 September 2004 - 01:53 PM

well... i'd feel kind of embarassed to put my years old childrens code next to that :)
If Prolog is the answer, what is the question ?

#20 davepermen

    Senior Member

  • Members
  • PipPipPipPip
  • 1306 posts

Posted 15 September 2004 - 04:48 PM

hehe. hey, whats the problem. it's a working scanline software rastericer. you deserve credit.
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users