From 4430b7c0bf486acc37fcb713e2ac42c13f3434ad Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Fri, 18 Aug 2023 18:08:37 -0500 Subject: [PATCH] Render frame function does the iterator thing! The many, many nested for loops don't feel right in a language that lets you `let x = for...` to assign the results of the loop directly to a variable. The logic hasn't changed (and I'm pretty sure the compiler emits the same code), but it feels better now. I'm now equipped to go over the rest of the project and rewrite the loops. Hopefully a more ergonomic way to dispatch to the threads arises as a result. I shall see. --- src/main.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index e465ed1..436ce82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -147,21 +147,22 @@ pub struct RenderContext{ camera: Camera, } -fn render_line(y: i32, small_rng: &mut SmallRng, context: RenderContext ) -> Vec { +fn render_line(y: i32, small_rng: &mut SmallRng, context: RenderContext) -> Vec { + //TODO: Ensure that the compiler hoists the distribution's out as constants + // else, do so manually let distrib_zero_one = Uniform::new(0.0, 1.0); let distrib_plusminus_one = Uniform::new(-1.0, 1.0); - let mut line = Vec::::new(); - for x in 0..context.image.0 { - let mut color = Vec3::zero(); - for _ in 0..context.samples_per_pixel { - let u = ((x as f32) + small_rng.sample(distrib_zero_one)) / ((context.image.0 - 1) as f32); - let v = ((y as f32) + small_rng.sample(distrib_zero_one)) / ((context.image.1 - 1) as f32); - let ray = context.camera.get_ray(u, v, small_rng); - color+= ray_color(ray, &context.world, context.max_depth, small_rng, distrib_plusminus_one); - } - line.push(color); - } - return line; + (0..context.image.0).map(|x| { + (0..context.samples_per_pixel).into_iter().fold( + Vec3::zero(), + |color, _sample| { + let u = ((x as f32) + small_rng.sample(distrib_zero_one)) / ((context.image.0 - 1) as f32); + let v = ((y as f32) + small_rng.sample(distrib_zero_one)) / ((context.image.1 - 1) as f32); + let ray = context.camera.get_ray(u, v, small_rng); + color + ray_color(ray, &context.world, context.max_depth, small_rng, distrib_plusminus_one) + } + ) + }).collect() } fn ray_color(r: Ray, world: &Hittable, depth: u32, srng: &mut SmallRng, distrib: Uniform ) -> Vec3 {