# Drawing solid triangle

This topic is 480 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm trying to draw a cube using software rendering. So I have I'm drawing a cube out of triangles. So I render a solid triangle. The cube is rendered successfully, but there are flicker while rotating it.

here is my solid triangle filling, can somebody notice a problem in the algorithm?

void Rasterizer::DrawSolidTriangle(int x0, int y0, int x1, int y1, int x2, int y2, Color&color)
{
// Sort our points into order of y
// 0 top
// 2 middle
// 1 bottom
if (y1 < y0)
{
swap(y1, y0);
swap(x1, x0);
}
if (y2 < y0)
{
swap(y2, y0);
swap(x2, x0);
}
if (y1 < y2)
{
swap(y2, y1);
swap(x2, x1);
}

float xl_edge = (float)x0; // left edge
float xr_edge = (float)x0; // right edge

float dxldy;
float dxrdy;

float dxdy1 = (float)(x2 - x0) / (y2 - y0);
float dxdy2 = (float)(x1 - x0) / (y1 - y0);

if (dxdy1 < dxdy2)
{
dxldy = dxdy1;
dxrdy = dxdy2;
}
else
{
dxldy = dxdy2;
dxrdy = dxdy1;
}

// Top of the triangle
for (int y = y0; y<y2; y++)
{

for (int x = xl_edge; x<xr_edge; x++)
{
SetPixel((unsigned int)x, (unsigned int)y, color);

}//end for loop x

xl_edge = xl_edge + dxldy;
xr_edge = xr_edge + dxrdy;

}// end for loop y

// Bottom half of the triangle

if (dxdy1 < dxdy2)
{
dxldy = (float)(x2 - x1) / (y2 - y1);
}
else
{
dxrdy = (float)(x2 - x1) / (y2 - y1);
}

for (int y = y2; y<y1; y++)
{

for (int x = xl_edge; x<xr_edge; x++)
{
SetPixel((unsigned int)x, (unsigned int)y, color);
}//end for loop x

xl_edge = xl_edge + dxldy;
xr_edge = xr_edge + dxrdy;

}// end for loop y

} 

##### Share on other sites

your code is incredibly hard to follow as the names for variables is poorly chosen and there are not too much in the comments department.

also, what happens when some of your points have the same y value?  step through your code and see if you can see what happens?

what is a bottom half and top half of triangle?  what is a top, middle, and bottom point?  perhaps draw a pic and put it with your post?

##### Share on other sites

If it draws a triangle then probably it's alrgiht,

have you considered Z order for your triangles in the cube?

##### Share on other sites
Your rasterizer only work so long as x0,y0 is at the top. Your code doesn't take the case of a horizontal top edge into consideration and fails at this point. This is why your cube is only being rendered as right triangles with the apex at the top. Edited by MarkS

##### Share on other sites

@MarkS how would I fix it ? please ?

##### Share on other sites

It isn't that I don't want to help, but this is a topic that is older than I am and I'll be 40 in March. Doctoral thesis were written on this subject up through the '90s. I would recommend you break this down into parts and try to solve each part. How would you scan convert a triangle with a flat bottom vs. a flat top vs. a general triangle? What tests would you need to perform? How should your code change?

I found multiple examples on Google in seconds, but I strongly recommend you not go this route. It is simple math and you're already part way there.

Edited by MarkS

##### Share on other sites
I wrote code to do this when I was 17, and it wasn't that hard back then. You just have to make sure you don't divide by 0.

##### Share on other sites

I wrote code to do this when I was 17, and it wasn't that hard back then. You just have to make sure you don't divide by 0.

I wasn't clear. This isn't hard, but rather, VERY well documented and covered. It has been thoroughly researched over the course of the past 40+ years. He's right there. All he needs to do is change the logic a bit and cover the three cases.

##### Share on other sites

so the problem is I'm not covering the third case ? a general triangle ?

##### Share on other sites

so the problem is I'm not covering the third case ? a general triangle ?

No, the problem is that you are not covering the specific case of a flat top. There at at three specific cases that you must handle individually, flat top, flat bottom and general triangle. That is the easy part. Then you have to figure out how to handle the cases of a degenerate triangle, slivers and adjacent triangles with no overdraw.

##### Share on other sites

I tried to draw a flat bottom triangle but I'm not sure if the math is correct or not

here is call and the code

void Rasterizer::DrawBottomTriangle(int x0, int y0, int x1, int y1, int x2, int y2, Color color)
{
float dxy_left = (x2 - x0) / (y2 - y0);
float dxy_right = (x2 - x0) / (y2 - y0);
// set starting and ending points for edge trace
float xs = x0;
float xe = x0;
// draw each scanline
for (int y = y0; y <= y2; y++)
{
// draw a line from xs to xe at y in color c
DrawLine(color, (int)xs, y, color, (int)xe, y);
// move down one scanline
xs += dxy_left;
xe += dxy_right;
} // end for y
}

The call

raster.DrawBottomTriangle(76, 50, 90, 10, 60, 10, Color(1, 0, 0));


##### Share on other sites

here is the full code

it can't draw the cube correctly

http://pastebin.com/Udd1u1Bx

##### Share on other sites
Try to find the arguments that were passed to a call where your code didn't do the right thing. Then step line by line thinking of what every variable's value would be and see why it doesn't work. You can use a debugger to help you with this.

##### Share on other sites

here is the full code
it can't draw the cube correctly

http://pastebin.com/Udd1u1Bx

I haven't had the chance to look at your code in detail as I work overnight, but this is wrong:

    if (y1 < y2)
{
swap(y2, y1);
swap(x2, x1);
}

You WANT y0 <= y1 <= y2. With the above code, if y1 and y2 are correctly ordered, you end up swapping them into incorrect order.

    if (y2 < y1)
{
swap(y2, y1);
swap(x2, x1);
}


##### Share on other sites
can you explain "flicker"? Are you seeing holes pixel holes? If so, where are they occurring? Is it where triangles share edges? If so, often times this is caused by "sub pixel" accuracy issues.

What do you know about triangle fill rules, such as the top-left rule used by OpenGL?