From 534b332a7e0eede28a528343ac27e3a88e5799ab Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Wed, 10 Sep 2025 16:12:51 -0700 Subject: [PATCH] use unsafe access to write pixelbuf --- src/main.rs | 2 +- src/triangle.rs | 46 +++++++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 322b756..91fae05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ fn main() { let model = Model::from_obj("diablo3_pose.obj"); model.render_triangles(&mut fb); - //fb.write_file("triangle.tga", true).unwrap(); + fb.write_file("triangle.tga", true).unwrap(); } fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut fb: &mut TGAImage) { diff --git a/src/triangle.rs b/src/triangle.rs index 39853c4..c6d173c 100644 --- a/src/triangle.rs +++ b/src/triangle.rs @@ -146,9 +146,6 @@ pub struct Triangle3i { c: Point3i, } -struct Wrapper(T); -unsafe impl Send for Wrapper {} - impl Triangle3i { pub fn new(a: Point3i, b: Point3i, c: Point3i) -> Self { Self { a, b, c } @@ -173,8 +170,10 @@ impl Triangle3i { } pub fn render_filled(&self, color: TGAColor, fb: &mut TGAImage, depth_buffer: &mut TGAImage) { - let fb = Arc::new(Mutex::new(fb)); - let zb = Arc::new(Mutex::new(depth_buffer)); + let w = fb.width as usize; + let bpp = fb.bytes_per_pixel() as usize; + let fb = &Wrapper(fb.data.as_mut_ptr()); + let zb = &Wrapper(depth_buffer.data.as_mut_ptr()); let bb = self.bb(); let total_area = self.signed_area(); if total_area < 1.0 { @@ -201,14 +200,10 @@ impl Triangle3i { + beta * self.b.z as f32 + gamma * self.c.z as f32) .round_ties_even() as u8; - if let Ok(mut zb) = zb.lock() { - let oz = zb.get(x as u32, y as u32).unwrap_or_default().b(); - if oz <= z { - if let Ok(mut fb) = fb.lock() { - zb.set(x as u32, y as u32, z.into()); - fb.set(x as u32, y as u32, color); - } - } + let pxl = (x + y * w as i32) as isize; + let start = pxl * bpp as isize; + unsafe { + write_pixel(fb, zb, z, start, pxl, bpp, color); } }; }); @@ -232,3 +227,28 @@ impl Triangle3i { Point3i { x, y, z, color } } } + +struct Wrapper(T); +unsafe impl Send for Wrapper {} +unsafe impl Sync for Wrapper {} + +unsafe fn write_pixel( + fb: &Wrapper<*mut u8>, + zb: &Wrapper<*mut u8>, + z: u8, + fb_offset: isize, + zb_offset: isize, + len: usize, + color: TGAColor, +) { + unsafe { + let oz = zb.0.offset(zb_offset); + if *oz <= z { + *oz = z; + for i in 0..len as isize { + let offset = fb_offset + i; + *fb.0.offset(offset) = color[i as usize]; + } + } + } +}