use unsafe access to write pixelbuf
This commit is contained in:
parent
5c1ae137bd
commit
534b332a7e
2 changed files with 34 additions and 14 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue