diff --git a/raytracer/src/buffer.rs b/raytracer/src/buffer.rs index a88734c..e8a3db2 100644 --- a/raytracer/src/buffer.rs +++ b/raytracer/src/buffer.rs @@ -6,8 +6,8 @@ use alloc::vec::Vec; use uefi::Error; pub struct Buffer { - width: usize, - height: usize, + pub width: usize, + pub height: usize, pixels: Vec, } @@ -37,11 +37,7 @@ impl Buffer { } /// Update only a pixel to the framebuffer. - fn blit_pixel( - &self, - gop: &mut GraphicsOutput, - coords: (usize, usize), - ) -> Result<(), Error> { + fn blit_pixel(&self, gop: &mut GraphicsOutput, coords: (usize, usize)) -> Result<(), Error> { gop.blt(BltOp::BufferToVideo { buffer: &self.pixels, src: BltRegion::SubRectangle { @@ -52,4 +48,4 @@ impl Buffer { dims: (1, 1), }) } -} \ No newline at end of file +} diff --git a/raytracer/src/main.rs b/raytracer/src/main.rs index 5b7af29..23af95f 100644 --- a/raytracer/src/main.rs +++ b/raytracer/src/main.rs @@ -1,29 +1,28 @@ #![no_main] #![no_std] - mod buffer; +mod ray; +mod renderer; extern crate alloc; +use crate::buffer::Buffer; use uefi::allocator::Allocator; use uefi::boot::ScopedProtocol; use uefi::prelude::*; use uefi::proto::console::gop::GraphicsOutput; -use uefi::{boot, Result}; -use crate::buffer::Buffer; +use uefi::{Result, boot}; #[global_allocator] static ALLOCATOR: Allocator = uefi::allocator::Allocator; fn init_gop() -> Result> { - // Open graphics output protocol. + // Open graphics output protocol. let gop_handle = boot::get_handle_for_protocol::()?; boot::open_protocol_exclusive::(gop_handle) } - - -fn init_buffer(gop: &GraphicsOutput) -> Buffer{ +fn init_buffer(gop: &GraphicsOutput) -> Buffer { // Create a buffer to draw into. let (width, height) = gop.current_mode_info().resolution(); Buffer::new(width, height) @@ -36,4 +35,4 @@ fn main() -> Status { let buffer = init_buffer(&gop); buffer.blit(&mut gop).unwrap(); Status::SUCCESS -} \ No newline at end of file +} diff --git a/raytracer/src/ray.rs b/raytracer/src/ray.rs new file mode 100644 index 0000000..85b3178 --- /dev/null +++ b/raytracer/src/ray.rs @@ -0,0 +1,58 @@ +use alloc::vec::Vec; +use cgmath::{Matrix4, Vector3, Vector4, num_traits::Num}; + +pub struct Ray { + pub(crate) origin: Vector3, + pub(crate) direction: Vector3, +} + +pub fn construct_primary_rays( + (width, height): (usize, usize), + (pixel_x_coord, pixel_y_coord): (usize, usize), + cam_to_world_matrix: &Matrix4, + focal_length: f32, + rays_per_pixel: usize, +) -> Vec { + let mut rays: Vec = Vec::with_capacity(rays_per_pixel); + + //generate all rays for this pixel and add them to the rays vector + for _ in 0..rays_per_pixel { + rays.push(generate_single_primary_ray( + (width, height), + cam_to_world_matrix, + focal_length, + pixel_x_coord, + pixel_y_coord, + //no noise + 0.0f, + 0.0f, + )); + } + + rays +} + +fn generate_single_primary_ray( + (buffer_width, buffer_height): (usize, usize), + cam_to_world_transform: &Matrix4, + focal_length: f32, + u: usize, + v: usize, + u_offset: f32, + v_offset: f32, +) -> Ray { + //calculate the ray direction and translate it to world space + let direction_camera_space: Vector4 = Vector4::new( + u as f32 - (buffer_width as f32 / 2.0) + u_offset, + v as f32 - (buffer_height as f32 / 2.0) + v_offset, + focal_length, + 0.0, + ); + + let direction_world_space = cam_to_world_transform * direction_camera_space.normalize(); + + Ray { + origin: cam_to_world_transform.w.truncate(), + direction: direction_world_space.truncate().normalize(), + } +} diff --git a/raytracer/src/renderer.rs b/raytracer/src/renderer.rs new file mode 100644 index 0000000..5fa22f7 --- /dev/null +++ b/raytracer/src/renderer.rs @@ -0,0 +1,31 @@ +use alloc::vec::Vec; +use cgmath::{Matrix4, Vector4, Zero}; + +use crate::{ + buffer::Buffer, + ray::{Ray, construct_primary_rays}, +}; + +pub fn render(buffer: Buffer) { + let camera_matrix: Matrix4 = Matrix4 { + x: Vector4::unit_x(), + y: Vector4::unit_y(), + z: Vector4::unit_z(), + w: Vector4::zero(), + }; + + let focal_length = 1.0f; + + //this reeeeally wants to run in parallel… + (0..buffer.width).for_each(|x| { + (0..buffer.height).for_each(|y| { + let rays: Vec> = construct_primary_rays( + (buffer.width, buffer.height), + (x, y), + camera_matrix, + focal_length, + 1, + ); + }); + }); +}