ssloy/tinyrenderer

Holes in fill a triangle using coordinates of pixel left bottom corner

rfhits opened this issue · 1 comments

void triangle(Vec2i *pts, TGAImage &image, TGAColor color) { 
    Vec2i bboxmin(image.get_width()-1,  image.get_height()-1); 
    Vec2i bboxmax(0, 0); 
    Vec2i clamp(image.get_width()-1, image.get_height()-1); 
    for (int i=0; i<3; i++) { 
        bboxmin.x = std::max(0, std::min(bboxmin.x, pts[i].x));
	bboxmin.y = std::max(0, std::min(bboxmin.y, pts[i].y));

	bboxmax.x = std::min(clamp.x, std::max(bboxmax.x, pts[i].x));
	bboxmax.y = std::min(clamp.y, std::max(bboxmax.y, pts[i].y));
    } 
    Vec2i P; 
    for (P.x=bboxmin.x; P.x<=bboxmax.x; P.x++) { 
        for (P.y=bboxmin.y; P.y<=bboxmax.y; P.y++) { 
            Vec3f bc_screen  = barycentric(pts, P);  // we are check the corner of the pixel whether in the triangle
            if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0) continue; 
            image.set(P.x, P.y, color); 
        } 
    } 
} 

there is a black pixel at the left bottom of the triangle in the image:

img

I think we should check whether the center of the pixel in the triangle or not.

here is my solution:

void fill_triangle(TGAImage& img, Vec2f* pts, const TGAColor& col)
{
    int bbox_r = std::max({ pts[0].x, pts[1].x, pts[2].x, static_cast<float>(img.get_width() - 1) });
    int bbox_l = std::min({ pts[0].x, pts[1].x, pts[2].x, 0.0f });
    int bbox_b = std::min({ pts[0].y, pts[1].y, pts[2].y, 0.0f });
    int bbox_t = std::max({ pts[0].y, pts[1].y, pts[2].y, static_cast<float>(img.get_height() - 1) });

    for (int x = bbox_l; x <= bbox_r; ++x) {
        for (int y = bbox_b; y <= bbox_t; ++y) {
            if (inside_triangle(Vec2f(x+0.5, y+0.5), pts)) {
                img.set(x, y, col);
            }
        }
    }
}