Threads pass back small images instead of sharing large image
This commit is contained in:
parent
a04f51998c
commit
0574dff685
|
|
@ -6,10 +6,11 @@ use super::integrators::{DirectionalLight, Integrator, WhittedIntegrator};
|
|||
use super::raycasting::Ray;
|
||||
use super::sampler::Sampler;
|
||||
use super::scene::Scene;
|
||||
use super::util::Tile;
|
||||
|
||||
use crate::Real;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
|
||||
struct ImageSampler<T: Real> {
|
||||
image_height_pixels: usize,
|
||||
|
|
@ -66,22 +67,13 @@ impl<T: Real> ImageSampler<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn render_scene<T: Real>(output_image: Arc<Mutex<ImageRgbF<T>>>, scene: Arc<Scene<T>>) {
|
||||
let height = output_image.lock().unwrap().get_height();
|
||||
let width = output_image.lock().unwrap().get_width();
|
||||
partial_render_scene(output_image, scene, 0, height, 0, width, height, width)
|
||||
}
|
||||
|
||||
pub fn partial_render_scene<T: Real>(
|
||||
output_image: Arc<Mutex<ImageRgbF<T>>>,
|
||||
scene: Arc<Scene<T>>,
|
||||
row_start: usize,
|
||||
row_end: usize,
|
||||
column_start: usize,
|
||||
column_end: usize,
|
||||
tile: Tile,
|
||||
height: usize,
|
||||
width: usize,
|
||||
) {
|
||||
) -> (Tile, ImageRgbF<T>) {
|
||||
let mut output_image_tile = ImageRgbF::new(tile.width(), tile.height());
|
||||
let image_sampler = ImageSampler::new(width, height, scene.camera_location);
|
||||
let ambient_intensity: T = convert(0.0);
|
||||
let directional_intensity1: T = convert(7.0);
|
||||
|
|
@ -105,18 +97,18 @@ pub fn partial_render_scene<T: Real>(
|
|||
],
|
||||
};
|
||||
let sampler = Sampler { scene: &scene };
|
||||
for column in column_start..column_end {
|
||||
for row in row_start..row_end {
|
||||
let ray = image_sampler.ray_for_pixel(row, column);
|
||||
for column in 0..tile.width() {
|
||||
for row in 0..tile.height() {
|
||||
let ray = image_sampler.ray_for_pixel(tile.start_row + row, tile.end_column + column);
|
||||
let hit = sampler.sample(&ray);
|
||||
let colour = match hit {
|
||||
None => ColourRgbF::from_named(NamedColour::Black),
|
||||
Some(intersection_info) => integrator.integrate(&sampler, &intersection_info),
|
||||
};
|
||||
let mut locked_image = output_image.lock().unwrap();
|
||||
locked_image.set_colour(row, column, colour);
|
||||
output_image_tile.set_colour(row, column, colour);
|
||||
}
|
||||
}
|
||||
(tile, output_image_tile)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
44
src/main.rs
44
src/main.rs
|
|
@ -3,6 +3,7 @@ use rayon::prelude::*;
|
|||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::pixels::PixelFormatEnum;
|
||||
use sdl2::rect::Rect;
|
||||
use sdl2::render::{Canvas, Texture};
|
||||
use sdl2::Sdl;
|
||||
use std::time::Duration;
|
||||
|
|
@ -11,21 +12,26 @@ use nalgebra::{Point3, Vector3};
|
|||
|
||||
use std::path::Path;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
|
||||
use vanrijn::camera::partial_render_scene;
|
||||
use vanrijn::colour::{ColourRgbF, NamedColour};
|
||||
use vanrijn::image::{ClampingToneMapper, ImageRgbF, ImageRgbU8, ToneMapper};
|
||||
use vanrijn::image::{ClampingToneMapper, ImageRgbU8, ToneMapper};
|
||||
use vanrijn::materials::{LambertianMaterial, PhongMaterial, ReflectiveMaterial};
|
||||
use vanrijn::mesh::load_obj;
|
||||
use vanrijn::raycasting::{Plane, Primitive, Sphere};
|
||||
use vanrijn::scene::Scene;
|
||||
use vanrijn::util::TileIterator;
|
||||
use vanrijn::util::{Tile, TileIterator};
|
||||
|
||||
fn update_texture(image: &ImageRgbU8, texture: &mut Texture) {
|
||||
fn update_texture(tile: &Tile, image: &ImageRgbU8, texture: &mut Texture) {
|
||||
texture
|
||||
.update(
|
||||
None,
|
||||
Rect::new(
|
||||
tile.start_column as i32,
|
||||
texture.query().height as i32 - (tile.start_row as i32 + tile.height() as i32),
|
||||
tile.width() as u32,
|
||||
tile.height() as u32,
|
||||
),
|
||||
image.get_pixel_data().as_slice(),
|
||||
(image.get_width() * ImageRgbU8::num_channels()) as usize,
|
||||
)
|
||||
|
|
@ -61,7 +67,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
image_width as u32,
|
||||
image_height as u32,
|
||||
)?;
|
||||
let output_image = Arc::new(Mutex::new(ImageRgbF::<f64>::new(image_width, image_height)));
|
||||
|
||||
let scene = Arc::new(Scene {
|
||||
camera_location: Point3::new(-2.0, 1.0, -5.0),
|
||||
|
|
@ -121,38 +126,27 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let (tile_tx, tile_rx) = mpsc::channel();
|
||||
let mut tile_rx = Some(tile_rx);
|
||||
|
||||
let output_image_workers = Arc::clone(&output_image);
|
||||
let worker_boss = std::thread::spawn(move || {
|
||||
TileIterator::new(image_width as usize, image_height as usize, 16)
|
||||
TileIterator::new(image_width as usize, image_height as usize, 8)
|
||||
.map(move |tile| (tile, tile_tx.clone()))
|
||||
.par_bridge()
|
||||
.try_for_each(|(tile, tx)| {
|
||||
let image_ptr = Arc::clone(&output_image_workers);
|
||||
let scene_ptr = scene.clone();
|
||||
partial_render_scene(
|
||||
image_ptr,
|
||||
scene_ptr,
|
||||
tile.start_row,
|
||||
tile.end_row,
|
||||
tile.start_column,
|
||||
tile.end_column,
|
||||
image_height,
|
||||
image_width,
|
||||
);
|
||||
let rendered_tile =
|
||||
partial_render_scene(scene_ptr, tile, image_height, image_width);
|
||||
|
||||
// There's nothing we can do if this fails, and we're already
|
||||
// at the end of the function anyway, so just ignore result.
|
||||
tx.send(tile).ok()
|
||||
tx.send(rendered_tile).ok()
|
||||
});
|
||||
});
|
||||
|
||||
'running: loop {
|
||||
if let Some(ref tile_rx) = tile_rx {
|
||||
for tile in tile_rx.try_iter() {
|
||||
let locked_image = output_image.lock().unwrap();
|
||||
let mut output_image_rgbu8 = ImageRgbU8::new(image_width, image_height);
|
||||
ClampingToneMapper {}.apply_tone_mapping(&locked_image, &mut output_image_rgbu8);
|
||||
update_texture(&output_image_rgbu8, &mut rendered_image_texture);
|
||||
for (tile, tile_image) in tile_rx.try_iter() {
|
||||
let mut tile_image_rgbu8 = ImageRgbU8::new(tile.width(), tile.height());
|
||||
ClampingToneMapper {}.apply_tone_mapping(&tile_image, &mut tile_image_rgbu8);
|
||||
update_texture(&tile, &tile_image_rgbu8, &mut rendered_image_texture);
|
||||
canvas.copy(&rendered_image_texture, None, None).unwrap();
|
||||
canvas.present();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use nalgebra::{Point2, Point3};
|
||||
use nalgebra::Point3;
|
||||
|
||||
use crate::Real;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,15 @@ pub struct Tile {
|
|||
pub end_row: usize,
|
||||
}
|
||||
|
||||
impl Tile {
|
||||
pub fn width(&self) -> usize {
|
||||
self.end_column - self.start_column
|
||||
}
|
||||
pub fn height(&self) -> usize {
|
||||
self.end_row - self.start_row
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TileIterator {
|
||||
tile_size: usize,
|
||||
total_height: usize,
|
||||
|
|
|
|||
Loading…
Reference in New Issue