use std::marker::PhantomData;
#[derive(Clone, Copy, Debug)]
pub struct RasterTarget<'a> {
fb_ptr: *mut u32,
fb_len: usize,
zb_ptr: *mut f32,
zb_len: usize,
_marker: PhantomData<&'a mut [u32]>,
}
unsafe impl Send for RasterTarget<'_> {}
unsafe impl Sync for RasterTarget<'_> {}
impl<'a> RasterTarget<'a> {
#[must_use]
pub fn new(framebuffer: &'a mut [u32], zbuffer: &'a mut [f32]) -> Self {
Self {
fb_ptr: framebuffer.as_mut_ptr(),
fb_len: framebuffer.len(),
zb_ptr: zbuffer.as_mut_ptr(),
zb_len: zbuffer.len(),
_marker: PhantomData,
}
}
#[must_use]
pub fn fb_len(self) -> usize {
self.fb_len
}
#[must_use]
pub fn fb_ptr(self) -> *mut u32 {
self.fb_ptr
}
#[must_use]
pub fn zb_ptr(self) -> *mut f32 {
self.zb_ptr
}
pub unsafe fn write_color(self, idx: usize, color: u32) {
debug_assert!(idx < self.fb_len, "fb idx {} >= len {}", idx, self.fb_len);
unsafe { self.fb_ptr.add(idx).write(color) };
}
pub unsafe fn write_depth(self, idx: usize, z: f32) {
debug_assert!(idx < self.zb_len, "zb idx {} >= len {}", idx, self.zb_len);
unsafe { self.zb_ptr.add(idx).write(z) };
}
#[must_use]
pub unsafe fn z_test_write(self, idx: usize, color: u32, z: f32) -> bool {
debug_assert!(idx < self.zb_len, "zb idx {} >= len {}", idx, self.zb_len);
unsafe {
if z < *self.zb_ptr.add(idx) {
self.fb_ptr.add(idx).write(color);
self.zb_ptr.add(idx).write(z);
true
} else {
false
}
}
}
}