diff --git a/Cargo.toml b/Cargo.toml index 5b74b49..20e3608 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] rand = "0.7.0" -rayon = "1.8" \ No newline at end of file +rayon = "1.8" +image = "0.25.9" \ No newline at end of file diff --git a/img.png b/img.png index c88c09f..27b8382 100644 Binary files a/img.png and b/img.png differ diff --git a/src/main.rs b/src/main.rs index 1c6fc78..fe4f387 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,13 +8,9 @@ pub mod rtweekend; pub mod sphere; pub mod vec3; +use image::{Pixel, RgbImage}; use rayon::prelude::*; -use std::{ - io::{stdout, Write}, - sync::atomic::{AtomicUsize, Ordering}, -}; - use crate::{ camera::*, color::*, @@ -145,42 +141,28 @@ fn main() { .build_global() .unwrap(); - let mut buffer = vec![0u8; (image_width * image_height * 3) as usize]; + let mut img_buffer = RgbImage::new(image_width as u32, image_height as u32); - let rows_completed = AtomicUsize::new(0); - let total_rows = image_height as usize; + img_buffer + .par_enumerate_pixels_mut() + .for_each(|(x, y, pixel)| { + // goofy workaround :D + let reversed_y = image_height as u32 - y; - buffer - .par_chunks_mut((image_width * 3) as usize) - .enumerate() - .for_each(|(index, row_slice)| { - let j = image_height - 1 - index as i32; - - for i in 0..image_width { - let mut pixel_color = Color::new(0.0, 0.0, 0.0); - - for _ in 0..samples_per_pixel { - let u = (i as f64 + random_f64()) / (image_width - 1) as f64; - let v = (j as f64 + random_f64()) / (image_height - 1) as f64; - let r = cam.get_ray(u, v); - pixel_color += ray_color(r, &world, max_depth); - } - - let (ir, ig, ib) = get_scaled_color_components(pixel_color, samples_per_pixel); - - row_slice[(i as usize) * 3] = ir; - row_slice[(i as usize) * 3 + 1] = ig; - row_slice[(i as usize) * 3 + 2] = ib; + let mut pixel_color = Color::new(0.0, 0.0, 0.0); + for _ in 0..samples_per_pixel { + let u = (x as f64 + random_f64()) / (image_width - 1) as f64; + let v = (reversed_y as f64 + random_f64()) / (image_height - 1) as f64; + let r = cam.get_ray(u, v); + pixel_color += ray_color(r, &world, max_depth); } - // progress - let completed = rows_completed.fetch_add(1, Ordering::Relaxed) + 1; - if completed % 10 == 0 || completed == total_rows { - print!( - "\r[ {:.2} % ] Rendering...", - (completed as f64 / total_rows as f64) * 100.0 - ); - let _ = stdout().flush(); - } + let (ir, ig, ib) = get_scaled_color_components(pixel_color, samples_per_pixel); + + pixel.channels_mut()[0] = ir; + pixel.channels_mut()[1] = ig; + pixel.channels_mut()[2] = ib; }); + + img_buffer.save("img.png").unwrap(); }