diff options
| author | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-03-14 15:39:45 +0100 |
|---|---|---|
| committer | Sakarias Johansson <sakariasjohansson@hotmail.com> | 2023-03-14 20:32:13 +0100 |
| commit | 7d32f05f6123dc12ab099cf337f9abe137750e43 (patch) | |
| tree | e30ad8933ae3e71f2beec104abf1ce3bcd1aa329 /racer-tracer | |
| parent | f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc (diff) | |
| download | racer-tracer-7d32f05f6123dc12ab099cf337f9abe137750e43.tar.gz racer-tracer-7d32f05f6123dc12ab099cf337f9abe137750e43.tar.xz racer-tracer-7d32f05f6123dc12ab099cf337f9abe137750e43.zip | |
🧹 Misc cleanup
- Was pointless to have one event for render and one for
cancel. Reduced it to one while fixing a minor bug.
- Remove useless dereference and borrow. Not sure how it
ended up like that.
- Moved around some code.
Diffstat (limited to 'racer-tracer')
| -rw-r--r-- | racer-tracer/src/image_action.rs | 96 | ||||
| -rw-r--r-- | racer-tracer/src/image_action/png.rs | 64 | ||||
| -rw-r--r-- | racer-tracer/src/image_action/wait_for_signal.rs | 25 | ||||
| -rw-r--r-- | racer-tracer/src/main.rs | 29 | ||||
| -rw-r--r-- | racer-tracer/src/render.rs | 45 | ||||
| -rw-r--r-- | racer-tracer/src/scene.rs | 19 | ||||
| -rw-r--r-- | racer-tracer/src/vec3.rs | 2 |
7 files changed, 134 insertions, 146 deletions
diff --git a/racer-tracer/src/image_action.rs b/racer-tracer/src/image_action.rs index 825c506..d6d212c 100644 --- a/racer-tracer/src/image_action.rs +++ b/racer-tracer/src/image_action.rs @@ -1,8 +1,12 @@ -use std::{path::PathBuf, sync::RwLock}; +pub mod png; +pub mod wait_for_signal; + +use std::sync::RwLock; -use sha2::{Digest, Sha256}; use synchronoise::SignalEvent; +use crate::image_action::{png::SavePng, wait_for_signal::WaitForSignal}; + use crate::{ config::{Config, ImageAction as CImageAction}, error::TracerError, @@ -20,92 +24,8 @@ pub trait ImageAction: Send + Sync { impl From<&CImageAction> for Box<dyn ImageAction> { fn from(image_action: &CImageAction) -> Self { match image_action { - CImageAction::WaitForSignal => Box::new(WaitForSignal::new()), - CImageAction::SavePng => Box::new(SavePng::new()), + CImageAction::WaitForSignal => Box::new(WaitForSignal {}), + CImageAction::SavePng => Box::new(SavePng {}), } } } - -pub struct SavePng {} - -impl SavePng { - pub fn new() -> Self { - Self {} - } -} - -impl ImageAction for SavePng { - fn action( - &self, - screen_buffer: &RwLock<Vec<u32>>, - _event: &SignalEvent, - config: &Config, - ) -> Result<(), TracerError> { - screen_buffer - .read() - .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) - .map(|buf| { - // Convert ARGB8 to RGBA8 - buf.iter() - .map(|v| { - let a: u32 = (v >> 24) & 0xff; - let r: u32 = (v >> 16) & 0xff; - let g: u32 = (v >> 8) & 0xff; - let b: u32 = v & 0xff; - - (r << 24) | (g << 16) | (b << 8) | a - }) - .flat_map(|val| val.to_be_bytes()) - .collect::<Vec<u8>>() - }) - .and_then(|buf| match &config.image_output_dir { - Some(image_dir) => { - println!("Saving image..."); - let mut sha = Sha256::new(); - - sha.update(buf.as_slice()); - - let mut file_path = PathBuf::from(image_dir); - file_path.push(format!("{:X}.png", sha.finalize())); - - img::save_buffer( - file_path.as_path(), - buf.as_slice(), - config.screen.width as u32, - config.screen.height as u32, - img::ColorType::Rgba8, - ) - .map_err(|e| { - let error = e.to_string(); - TracerError::ImageSave(error) - }) - .map(|_| { - println!("Saved image to: {}", file_path.to_string_lossy()); - }) - } - None => Ok(()), - }) - } -} - -pub struct WaitForSignal {} - -impl WaitForSignal { - pub fn new() -> Self { - Self {} - } -} - -impl ImageAction for WaitForSignal { - fn action( - &self, - _screen_buffer: &RwLock<Vec<u32>>, - event: &SignalEvent, - _config: &Config, - ) -> Result<(), TracerError> { - println!("Press R to resume."); - event.wait(); - event.reset(); - Ok(()) - } -} diff --git a/racer-tracer/src/image_action/png.rs b/racer-tracer/src/image_action/png.rs new file mode 100644 index 0000000..c43e863 --- /dev/null +++ b/racer-tracer/src/image_action/png.rs @@ -0,0 +1,64 @@ +use std::{path::PathBuf, sync::RwLock}; + +use sha2::{Digest, Sha256}; +use synchronoise::SignalEvent; + +use crate::{config::Config, error::TracerError}; + +use super::ImageAction; + +pub struct SavePng {} + +impl ImageAction for SavePng { + fn action( + &self, + screen_buffer: &RwLock<Vec<u32>>, + _event: &SignalEvent, + config: &Config, + ) -> Result<(), TracerError> { + screen_buffer + .read() + .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) + .map(|buf| { + // Convert ARGB8 to RGBA8 + buf.iter() + .map(|v| { + let a: u32 = (v >> 24) & 0xff; + let r: u32 = (v >> 16) & 0xff; + let g: u32 = (v >> 8) & 0xff; + let b: u32 = v & 0xff; + + (r << 24) | (g << 16) | (b << 8) | a + }) + .flat_map(|val| val.to_be_bytes()) + .collect::<Vec<u8>>() + }) + .and_then(|buf| match &config.image_output_dir { + Some(image_dir) => { + println!("Saving image..."); + let mut sha = Sha256::new(); + + sha.update(buf.as_slice()); + + let mut file_path = PathBuf::from(image_dir); + file_path.push(format!("{:X}.png", sha.finalize())); + + img::save_buffer( + file_path.as_path(), + buf.as_slice(), + config.screen.width as u32, + config.screen.height as u32, + img::ColorType::Rgba8, + ) + .map_err(|e| { + let error = e.to_string(); + TracerError::ImageSave(error) + }) + .map(|_| { + println!("Saved image to: {}", file_path.to_string_lossy()); + }) + } + None => Ok(()), + }) + } +} diff --git a/racer-tracer/src/image_action/wait_for_signal.rs b/racer-tracer/src/image_action/wait_for_signal.rs new file mode 100644 index 0000000..54480ac --- /dev/null +++ b/racer-tracer/src/image_action/wait_for_signal.rs @@ -0,0 +1,25 @@ +use std::sync::RwLock; + +use synchronoise::SignalEvent; + +use crate::{config::Config, error::TracerError}; + +use super::ImageAction; + +pub struct WaitForSignal {} + +impl ImageAction for WaitForSignal { + fn action( + &self, + _screen_buffer: &RwLock<Vec<u32>>, + event: &SignalEvent, + _config: &Config, + ) -> Result<(), TracerError> { + if !event.status() { + println!("Press R to resume."); + event.wait(); + } + event.reset(); + Ok(()) + } +} diff --git a/racer-tracer/src/main.rs b/racer-tracer/src/main.rs index 6648c81..0c65208 100644 --- a/racer-tracer/src/main.rs +++ b/racer-tracer/src/main.rs @@ -40,6 +40,7 @@ fn run(config: Config) -> Result<(), TracerError> { let screen_buffer: RwLock<Vec<u32>> = RwLock::new(vec![0; image.width * image.height]); let look_from = Vec3::new(13.0, 2.0, 3.0); let look_at = Vec3::new(0.0, 0.0, 0.0); + let camera_speed = 2.0; let camera = RwLock::new(Camera::new( look_from, look_at, @@ -50,13 +51,12 @@ fn run(config: Config) -> Result<(), TracerError> { 10.0, )); - let scene = Scene::try_new((&config.loader).into())?; + let scene = Scene::try_new(&config.loader)?; let mut window_res: Result<(), TracerError> = Ok(()); let mut render_res: Result<(), TracerError> = Ok(()); let render_image = SignalEvent::manual(false); - let cancel_render = SignalEvent::manual(false); let exit = SignalEvent::manual(false); let image_action: Box<dyn ImageAction> = (&config.image_action).into(); @@ -73,6 +73,7 @@ fn run(config: Config) -> Result<(), TracerError> { .then_some(|| ()) .map_or_else( || { + render_image.reset(); // Render preview render( &screen_buffer, @@ -85,6 +86,7 @@ fn run(config: Config) -> Result<(), TracerError> { ) }, |_| { + render_image.reset(); let render_time = Instant::now(); render( &screen_buffer, @@ -92,11 +94,10 @@ fn run(config: Config) -> Result<(), TracerError> { &image, &scene, &config.render, - Some(&cancel_render), + Some(&render_image), None, ) .and_then(|_| { - render_image.reset(); println!( "It took {} seconds to render the image.", Instant::now().duration_since(render_time).as_secs() @@ -134,15 +135,7 @@ fn run(config: Config) -> Result<(), TracerError> { std::thread::sleep(std::time::Duration::from_millis(10)); if window.is_key_released(Key::R) { - if render_image.status() { - // Signal cancel - cancel_render.signal(); - render_image.reset(); - } else { - // Signal render - render_image.signal(); - cancel_render.reset(); - } + render_image.signal(); } camera @@ -150,15 +143,15 @@ fn run(config: Config) -> Result<(), TracerError> { .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) .map(|mut cam| { if window.is_key_down(Key::W) { - cam.go_forward(-dt); + cam.go_forward(-dt * camera_speed); } else if window.is_key_down(Key::S) { - cam.go_forward(dt); + cam.go_forward(dt * camera_speed); } if window.is_key_down(Key::A) { - cam.go_right(-dt); + cam.go_right(-dt * camera_speed); } else if window.is_key_down(Key::D) { - cam.go_right(dt); + cam.go_right(dt * camera_speed); } })?; @@ -172,7 +165,7 @@ fn run(config: Config) -> Result<(), TracerError> { })? } exit.signal(); - cancel_render.signal(); + render_image.signal(); Ok(()) }); }); diff --git a/racer-tracer/src/render.rs b/racer-tracer/src/render.rs index fefafce..6926091 100644 --- a/racer-tracer/src/render.rs +++ b/racer-tracer/src/render.rs @@ -1,4 +1,4 @@ -use std::{borrow::Borrow, sync::RwLock, time::Duration}; +use std::{sync::RwLock, time::Duration}; use rayon::prelude::*; use synchronoise::SignalEvent; @@ -34,6 +34,21 @@ fn ray_color(scene: &dyn Hittable, ray: &Ray, depth: usize) -> Vec3 { (1.0 - t) * first_color + t * second_color } +fn do_cancel(cancel_event: Option<&SignalEvent>) -> bool { + match cancel_event { + Some(event) => event.wait_timeout(Duration::from_secs(0)), + None => false, + } +} + +fn get_highest_divdable(value: usize, mut div: usize) -> usize { + // Feels like there could possibly be some other nicer trick to this. + while (value % div) != 0 { + div -= 1; + } + div +} + pub fn raytrace_scaled( buffer: &RwLock<Vec<u32>>, cancel_event: Option<&SignalEvent>, @@ -146,21 +161,6 @@ pub fn raytrace( }) } -fn do_cancel(cancel_event: Option<&SignalEvent>) -> bool { - match cancel_event { - Some(event) => event.wait_timeout(Duration::from_secs(0)), - None => false, - } -} - -fn get_highest_divdable(value: usize, mut div: usize) -> usize { - // Feels like there could possibly be some other nicer trick to this. - while (value % div) != 0 { - div -= 1; - } - div -} - pub fn render( buffer: &RwLock<Vec<u32>>, camera: &RwLock<Camera>, @@ -228,21 +228,12 @@ pub fn render( .into_par_iter() .map(|image| { scale.map_or_else( - || { - raytrace( - buffer, - cancel_event, - (*scene).borrow(), - cam.clone(), - &image, - data, - ) - }, + || raytrace(buffer, cancel_event, scene, cam.clone(), &image, data), |_| { raytrace_scaled( buffer, cancel_event, - (*scene).borrow(), + scene, cam.clone(), &image, data, diff --git a/racer-tracer/src/scene.rs b/racer-tracer/src/scene.rs index 12e2296..e730db0 100644 --- a/racer-tracer/src/scene.rs +++ b/racer-tracer/src/scene.rs @@ -12,8 +12,13 @@ pub struct Scene { } impl Scene { - #[allow(dead_code)] - pub fn try_new(loader: Box<dyn SceneLoader>) -> Result<Self, TracerError> { + pub fn try_new(config_loader: &CSLoader) -> Result<Self, TracerError> { + let loader: Box<dyn SceneLoader> = match config_loader { + CSLoader::Yml { path } => Box::new(YmlLoader::new(path.clone())), + CSLoader::Random => Box::new(Random::new()), + CSLoader::None => Box::new(NoneLoader::new()), + }; + loader.load().map(|objects| Self { objects }) } @@ -47,13 +52,3 @@ impl Hittable for Scene { pub trait SceneLoader: Send + Sync { fn load(&self) -> Result<Vec<Box<dyn Hittable>>, TracerError>; } - -impl From<&CSLoader> for Box<dyn SceneLoader> { - fn from(loader: &CSLoader) -> Self { - match loader { - CSLoader::Yml { path } => Box::new(YmlLoader::new(path.clone())), - CSLoader::Random => Box::new(Random::new()), - CSLoader::None => Box::new(NoneLoader::new()), - } - } -} diff --git a/racer-tracer/src/vec3.rs b/racer-tracer/src/vec3.rs index e315203..281fb26 100644 --- a/racer-tracer/src/vec3.rs +++ b/racer-tracer/src/vec3.rs @@ -87,7 +87,7 @@ impl Vec3 { let red: u32 = (self.data[0] * 255.0) as u32; let green: u32 = (self.data[1] * 255.0) as u32; let blue: u32 = (self.data[2] * 255.0) as u32; - // ARGB + // XRGB (255 << 24) | (red << 16) | green << 8 | blue } |
