From c11bfdcc00064eb04fe42295d0a711fdaac55e12 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Mon, 8 Sep 2025 13:52:04 -0700 Subject: [PATCH] render colored triangle, but something is weird with coordinates --- src/main.rs | 65 +++++++++++++++++++--------------------------------- src/point.rs | 16 ++++++------- src/tga.rs | 46 +++++++++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 58 deletions(-) diff --git a/src/main.rs b/src/main.rs index 242e1f7..eb21adb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,8 @@ use point::*; mod model; use model::*; +const BLACK: TGAColor = TGAColor { bgra: [0u8; 4] }; + const WHITE: TGAColor = TGAColor { bgra: [255, 255, 255, 255], }; @@ -36,44 +38,17 @@ const YELLOW: TGAColor = TGAColor { }; fn main() { - let w = 800; - let h = 800; + let w = 640; + let h = 640; let mut fb = TGAImage::new(w, h, TGAFormat::RGB); - render_head(&mut fb); -} + let a = Point2i::new(170, 40).with_color(BLUE); + let b = Point2i::new(550, 390).with_color(GREEN); + let c = Point2i::new(230, 590).with_color(RED); -fn _render_diablo(fb: &mut TGAImage) { - let model = Model::from_obj("diablo3_pose.obj"); - model.render_wireframe(fb); - fb.write_file("diablo.tga", true, true).unwrap(); -} - -fn render_head(fb: &mut TGAImage) { - let model = Model::from_obj("head.obj"); - model.render_triangles(fb); - fb.write_file("head.tga", true, true).unwrap(); -} -fn _baseline(framebuffer: &mut TGAImage) { - let ax = 7; - let ay = 3; - let bx = 12; - let by = 37; - let cx = 62; - let cy = 53; - - framebuffer.set(ax, ay, WHITE); - framebuffer.set(bx, by, WHITE); - framebuffer.set(cx, cy, WHITE); - - let a = Point2i::newu(ax, ay); - let b = Point2i::newu(bx, by); - let c = Point2i::newu(cx, cy); - - line(a, b, BLUE, framebuffer); - line(c, b, GREEN, framebuffer); - line(c, a, YELLOW, framebuffer); - line(a, c, RED, framebuffer); + let t = Triangle2i::new(a, b, c); + t.render_filled(BLACK, &mut fb); + fb.write_file("triangle.tga", true, true).unwrap(); } fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut fb: &mut TGAImage) { @@ -140,15 +115,23 @@ impl Triangle2i { (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 = Triangle2i::new(p, self.a, self.b).signed_area() * it; - let b = Triangle2i::new(p, self.b, self.c).signed_area() * it; - let c = Triangle2i::new(p, self.c, self.a).signed_area() * it; + let alpha = Triangle2i::new(p, self.a, self.b).signed_area() * it; + let beta = Triangle2i::new(p, self.b, self.c).signed_area() * it; + let gamma = Triangle2i::new(p, self.c, self.a).signed_area() * it; - if a.is_sign_positive() - && b.is_sign_positive() - && c.is_sign_positive() + if alpha.is_sign_positive() + && beta.is_sign_positive() + && gamma.is_sign_positive() && let Ok(mut fb) = fb.lock() { + let color = if let Some(ca) = self.a.color + && let Some(cb) = self.b.color + && let Some(cc) = self.c.color + { + ca * alpha + cb * beta + cc * gamma + color + } else { + color + }; fb.set(x as u32, y as u32, color); } }); diff --git a/src/point.rs b/src/point.rs index 41e1574..122ae14 100644 --- a/src/point.rs +++ b/src/point.rs @@ -6,25 +6,25 @@ use crate::tga::TGAColor; pub struct Point2i { pub x: i32, pub y: i32, - pub c: Option, + pub color: Option, } impl Point2i { pub fn new(x: i32, y: i32) -> Self { - Self { x, y, c: None } + Self { x, y, color: None } } pub fn newu(x: u32, y: u32) -> Self { Self { x: x as i32, y: y as i32, - c: None, + color: None, } } pub fn with_color(self, color: TGAColor) -> Self { Self { - c: Some(color), + color: Some(color), ..self } } @@ -37,7 +37,7 @@ impl Add for Point2i { Self { x: self.x + rhs.x, y: self.y + rhs.y, - c: None, + color: None, } } } @@ -49,7 +49,7 @@ impl Sub for Point2i { Self { x: self.x - rhs.x, y: self.y - rhs.y, - c: None, + color: None, } } } @@ -61,7 +61,7 @@ impl Mul for Point2i { Self { x: self.x * rhs.x, y: self.y * rhs.y, - c: None, + color: None, } } } @@ -143,7 +143,7 @@ impl From for Point2i { Self { x: p.x().round_ties_even() as i32, y: p.y().round_ties_even() as i32, - c: None, + color: None, } } } diff --git a/src/tga.rs b/src/tga.rs index 1135246..f8e5409 100644 --- a/src/tga.rs +++ b/src/tga.rs @@ -1,7 +1,7 @@ use std::{ fs::File, io::{Read, Write}, - ops::{Deref, DerefMut}, + ops::{Add, Deref, DerefMut, Mul}, }; const HEADER_SIZE: usize = 18; @@ -73,6 +73,34 @@ impl From for TGAColor { } } +impl Add for TGAColor { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self { + bgra: [ + self[0].saturating_add(rhs[0]), + self[1].saturating_add(rhs[1]), + self[2].saturating_add(rhs[2]), + self[3].saturating_add(rhs[3]), + ], + } + } +} + +impl Mul for TGAColor { + type Output = Self; + + fn mul(self, rhs: f32) -> Self::Output { + let b = (self.b() as f32 * rhs).round_ties_even() as u8; + let g = (self.g() as f32 * rhs).round_ties_even() as u8; + let r = (self.r() as f32 * rhs).round_ties_even() as u8; + let a = (self.a() as f32 * rhs).round_ties_even() as u8; + + Self { bgra: [b, g, r, a] } + } +} + impl TGAColor { pub fn new() -> Self { Self { @@ -80,20 +108,20 @@ impl TGAColor { } } - pub fn b(&mut self) -> &mut u8 { - &mut self[0] + pub fn b(&self) -> u8 { + self[0] } - pub fn g(&mut self) -> &mut u8 { - &mut self[1] + pub fn g(&self) -> u8 { + self[1] } - pub fn r(&mut self) -> &mut u8 { - &mut self[2] + pub fn r(&self) -> u8 { + self[2] } - pub fn a(&mut self) -> &mut u8 { - &mut self[3] + pub fn a(&self) -> u8 { + self[3] } }