Skip to content

Instantly share code, notes, and snippets.

@Nyrox
Created September 26, 2018 07:45
Show Gist options
  • Save Nyrox/100678f16d453dce54eacb97faebbec7 to your computer and use it in GitHub Desktop.
Save Nyrox/100678f16d453dce54eacb97faebbec7 to your computer and use it in GitHub Desktop.
pub fn launch_tiled<C: 'static + Clone + Sync + Send + Fn(super::Tile)>(
self,
scene: Scene,
tile_size: (usize, usize),
cb: C,
) -> () {
let queue = Arc::new(MsQueue::new());
// Generate tiles
{
let mut x = 0;
let mut y = 0;
'gen_tiles: loop {
let tile_min = (x, y);
let tile_max = (
(x + tile_size.0).min(self.width - 1),
(y + tile_size.1).min(self.height - 1),
);
let width = tile_max.0 - tile_min.0;
let height = tile_max.1 - tile_min.1;
queue.push(super::Tile {
sample_count: 0,
left: tile_min.0,
top: tile_min.1,
width,
height,
data: vec![Vector3::new(0.0, 0.0, 0.0); width * height],
});
y += tile_size.1;
if y >= self.height {
y = 0;
x += tile_size.0;
}
if x >= self.width {
break 'gen_tiles;
}
}
}
let mut handles = Vec::new();
for i in 0..self.num_workers {
let queue = queue.clone();
let raytracer = Raytracer {
config: self.clone(),
scene: scene.clone(),
};
let cb = cb.clone();
handles.push(thread::spawn(move || loop {
if let Some(mut tile) = queue.try_pop() {
for y in tile.top..(tile.top + tile.height) {
for x in tile.left..(tile.left + tile.width) {
let ray = raytracer.generate_primary_ray_with_dof(x, y);
tile.data[(x - tile.left) + (y - tile.top) * tile.width] +=
raytracer.trace(ray, raytracer.config.camera_pos, 1);
}
}
tile.sample_count += 1;
cb(tile.clone());
if tile.sample_count < raytracer.config.num_samples {
queue.push(tile);
}
} else {
println!("Worker {} done.", i);
return;
}
}));
}
return ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment