diff options
author | Julian T <julian@jtle.dk> | 2021-08-05 15:44:40 +0200 |
---|---|---|
committer | Julian T <julian@jtle.dk> | 2021-08-05 15:44:40 +0200 |
commit | 3ef8f4d918406eec6bdc29e0ebd883fabfac9b2e (patch) | |
tree | aa4b1aac1e165821c16f222ebfb9212a9740e98b /src/render | |
parent | 45119506c0293fdde6cef35f6e6f82d4055b46b6 (diff) |
Add picture for c5505ab84820248c6dba35fc06aef9e0ced183derendered
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/coordinator.rs | 126 | ||||
-rw-r--r-- | src/render/mod.rs | 5 | ||||
-rw-r--r-- | src/render/task.rs | 49 |
3 files changed, 0 insertions, 180 deletions
diff --git a/src/render/coordinator.rs b/src/render/coordinator.rs deleted file mode 100644 index e2f825b..0000000 --- a/src/render/coordinator.rs +++ /dev/null @@ -1,126 +0,0 @@ -//! Split a image into small tiles -//! -//! This enables multithreaded rendering. - -use super::{RenderTask, RenderContext}; -use crate::camera::Film; -use crate::core::{Bound2i, Vector2i}; -use crate::sample::Sampler; - -use std::sync::{Mutex}; - -struct Tiler { - tilesize: Vector2i, - - fullbound: Bound2i, - tilemap_size: Vector2i, - tilemap_area: i32, - - next_tile: i32, - tiles_done: i32, -} - -pub struct RenderCoord<'a> { - film: Mutex<&'a mut Film>, - samples: u32, - tiler: Mutex<Tiler>, -} - -impl Tiler { - pub fn new(fullsize: Vector2i, tilesize: Vector2i) -> Tiler { - assert!(tilesize.x != 0 && tilesize.y != 0); - - let tilemap_size = fullsize / tilesize; - - Self { - tilesize, - - fullbound: Bound2i::new(&Vector2i::ZERO, &fullsize), - tilemap_size, - tilemap_area: (tilemap_size.x * tilemap_size.y), - - next_tile: 0, - tiles_done: 0, - } - - } - - pub fn next_tile(&mut self) -> Option<(Bound2i, i32)> { - // Check if we are outside - if self.next_tile >= self.tilemap_area { - return None; - } - - // Convert the tile to xy in tilemap - let tile = Vector2i::new_xy(self.next_tile / self.tilemap_size.x, self.next_tile % self.tilemap_size.x); - let tile_index = self.next_tile; - - self.next_tile += 1; - - // Create a bound from the tilecoordinate - let tile_start = tile * self.tilesize; - // We need to make sure the resulting tile is inside the image bound - Some(( - Bound2i::new(&tile_start, &(tile_start + self.tilesize)).intersect(&self.fullbound), - tile_index, - )) - } - - /// Mark a index as done and return the overall process - pub fn mark_done(&mut self, _index: i32) -> f32 { - self.tiles_done += 1; - - println!("Progress: {}/{}", self.tiles_done, self.tilemap_area); - self.tiles_done as f32 / self.tilemap_area as f32 - } -} - -impl<'a> RenderCoord<'a> { - pub fn new(film: &'a mut Film, tilesize: Vector2i, samples: u32) -> Self { - let size = film.size; - - Self { - film: Mutex::new(film), - samples, - tiler: Mutex::new(Tiler::new(size, tilesize)), - } - } - - pub fn next_task(&self) -> Option<RenderTask> { - let (tile_bound, index) = self.tiler.lock().unwrap().next_tile()?; - - let film_tile = { - let film = self.film.lock().unwrap(); - Box::new(film.get_tile(&tile_bound)) - }; - - Some(RenderTask::new(film_tile, self.samples, index)) - } - - pub fn finish_task(&self, task: &RenderTask) { - { - let mut film = self.film.lock().unwrap(); - film.commit_tile(task.tile.as_ref()); - } - - self.tiler.lock().unwrap().mark_done(task.tile_index); - } - - pub fn work(&self, ctx: &RenderContext, sampler: &mut dyn Sampler) { - while let Some(mut task) = self.next_task() { - task.render(ctx, sampler); - self.finish_task(&task); - } - } - - pub fn run_threaded(&self, ctx: &RenderContext, sampler: &mut (dyn Sampler + Send), threads: u32) { - crossbeam::scope(|scope| { - for _ in 0..threads { - let mut sampler = sampler.clone_and_seed(); - scope.spawn(move |_| { - self.work(ctx, sampler.as_mut()); - }); - } - }).unwrap(); - } -} diff --git a/src/render/mod.rs b/src/render/mod.rs deleted file mode 100644 index b81aaf5..0000000 --- a/src/render/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod task; -mod coordinator; - -pub use task::{RenderContext, RenderTask}; -pub use coordinator::RenderCoord; diff --git a/src/render/task.rs b/src/render/task.rs deleted file mode 100644 index 017fe24..0000000 --- a/src/render/task.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! Implements the main render loop -//! -//! This is not a final design -use crate::camera::film::FilmTile; -use crate::camera::Camera; -use crate::trace::{DefaultTracer, Tracer}; -use crate::sample::Sampler; - -use crate::core::{Vector2f}; -use crate::Float; - -pub struct RenderTask { - pub tile: Box<FilmTile>, - samples: u32, - pub tile_index: i32, -} - -pub struct RenderContext<'a> { - pub cam: &'a Camera, - pub trc: &'a DefaultTracer<'a>, -} - -impl RenderTask { - pub fn new(tile: Box<FilmTile>, samples: u32, tile_index: i32) -> Self { - Self { tile, samples, tile_index } - } - - fn render_at(&mut self, ctx: &RenderContext, x: i32, y: i32, sampler: &mut dyn Sampler) { - let corner = Vector2f::new_xy(x as Float, y as Float); - - for _ in 0..self.samples { - let p = corner + sampler.get_sample_2d(); - - // Create a ray - let (r, _) = ctx.cam.generate_ray(&p, sampler); - - self.tile.add_sample(&p, ctx.trc.trace(sampler, &r)); - } - } - - pub fn render(&mut self, ctx: &RenderContext, sampler: &mut dyn Sampler) { - let b = self.tile.bounds.clone(); - for y in b.min.y .. b.max.y { - for x in b.min.x .. b.max.x { - self.render_at(ctx, x, y, sampler); - } - } - } -} |