diff --git a/src/main.rs b/src/main.rs index c2f2eae..d97f7c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -156,10 +156,16 @@ struct Triangle { impl Triangle { pub fn new(a: Point2i, b: Point2i, c: Point2i) -> Self { - let mut sorted = [a, b, c]; + Self { a, b, c } + } + + pub fn sort(&mut self) { + let mut sorted = [self.a, self.b, self.c]; sorted.sort_unstable_by(|a, b| a.y.cmp(&b.y)); let [a, b, c] = sorted; - Self { a, b, c } + self.a = a; + self.b = b; + self.c = c; } pub fn signed_area(&self) -> f32 { @@ -179,13 +185,27 @@ impl Triangle { upper_right: Point2i::new(xmax, ymax), } } + pub fn render_filled(&self, color: TGAColor, fb: &mut TGAImage) { + let fb = Arc::new(Mutex::new(fb)); let bb = self.bb(); - for y in bb.ymin()..=bb.ymax() { - let a = Point2i::new(bb.xmin(), y); - let b = Point2i::new(bb.xmax(), y); - line(a, b, color, fb); - } + let total_area = self.signed_area(); + (bb.ymin()..=bb.ymax()).into_par_iter().for_each(|y| { + (bb.xmin()..bb.xmax()).into_par_iter().for_each(|x| { + let p = Point2i::new(x, y); + let a = Triangle::new(p, self.a, self.b).signed_area() / total_area; + let b = Triangle::new(p, self.b, self.c).signed_area() / total_area; + let c = Triangle::new(p, self.c, self.a).signed_area() / total_area; + + if a.is_sign_positive() + && b.is_sign_positive() + && c.is_sign_positive() + && let Ok(mut fb) = fb.lock() + { + fb.set(x as u32, y as u32, color); + } + }); + }); } pub fn render_lines(&self, color: TGAColor, fb: &mut TGAImage) {