use unsafe access to write pixelbuf

This commit is contained in:
Joe Ardent 2025-09-10 16:12:51 -07:00
parent 5c1ae137bd
commit 534b332a7e
2 changed files with 34 additions and 14 deletions

View file

@ -43,7 +43,7 @@ fn main() {
let model = Model::from_obj("diablo3_pose.obj"); let model = Model::from_obj("diablo3_pose.obj");
model.render_triangles(&mut fb); 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) { fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut fb: &mut TGAImage) {

View file

@ -146,9 +146,6 @@ pub struct Triangle3i {
c: Point3i, c: Point3i,
} }
struct Wrapper<T>(T);
unsafe impl<T> Send for Wrapper<T> {}
impl Triangle3i { impl Triangle3i {
pub fn new(a: Point3i, b: Point3i, c: Point3i) -> Self { pub fn new(a: Point3i, b: Point3i, c: Point3i) -> Self {
Self { a, b, c } Self { a, b, c }
@ -173,8 +170,10 @@ impl Triangle3i {
} }
pub fn render_filled(&self, color: TGAColor, fb: &mut TGAImage, depth_buffer: &mut TGAImage) { pub fn render_filled(&self, color: TGAColor, fb: &mut TGAImage, depth_buffer: &mut TGAImage) {
let fb = Arc::new(Mutex::new(fb)); let w = fb.width as usize;
let zb = Arc::new(Mutex::new(depth_buffer)); 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 bb = self.bb();
let total_area = self.signed_area(); let total_area = self.signed_area();
if total_area < 1.0 { if total_area < 1.0 {
@ -201,14 +200,10 @@ impl Triangle3i {
+ beta * self.b.z as f32 + beta * self.b.z as f32
+ gamma * self.c.z as f32) + gamma * self.c.z as f32)
.round_ties_even() as u8; .round_ties_even() as u8;
if let Ok(mut zb) = zb.lock() { let pxl = (x + y * w as i32) as isize;
let oz = zb.get(x as u32, y as u32).unwrap_or_default().b(); let start = pxl * bpp as isize;
if oz <= z { unsafe {
if let Ok(mut fb) = fb.lock() { write_pixel(fb, zb, z, start, pxl, bpp, color);
zb.set(x as u32, y as u32, z.into());
fb.set(x as u32, y as u32, color);
}
}
} }
}; };
}); });
@ -232,3 +227,28 @@ impl Triangle3i {
Point3i { x, y, z, color } Point3i { x, y, z, color }
} }
} }
struct Wrapper<T>(T);
unsafe impl<T> Send for Wrapper<T> {}
unsafe impl<T> Sync for Wrapper<T> {}
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];
}
}
}
}