Make main rendering loop multithreaded again.
This commit is contained in:
parent
254957c5c3
commit
a04f51998c
|
|
@ -12,6 +12,7 @@ itertools = "0.8"
|
||||||
obj = "0.9"
|
obj = "0.9"
|
||||||
quickcheck = "0.9"
|
quickcheck = "0.9"
|
||||||
quickcheck_macros = "0.8"
|
quickcheck_macros = "0.8"
|
||||||
|
rayon = "1.3"
|
||||||
sdl2 = "0.32"
|
sdl2 = "0.32"
|
||||||
|
|
||||||
[dependencies.nalgebra]
|
[dependencies.nalgebra]
|
||||||
|
|
|
||||||
75
src/main.rs
75
src/main.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
use sdl2::pixels::PixelFormatEnum;
|
use sdl2::pixels::PixelFormatEnum;
|
||||||
|
|
@ -8,6 +10,7 @@ use std::time::Duration;
|
||||||
use nalgebra::{Point3, Vector3};
|
use nalgebra::{Point3, Vector3};
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::sync::mpsc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use vanrijn::camera::partial_render_scene;
|
use vanrijn::camera::partial_render_scene;
|
||||||
|
|
@ -47,8 +50,8 @@ fn init_canvas(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let image_width = 320usize;
|
let image_width = 640usize;
|
||||||
let image_height = 240usize;
|
let image_height = 480usize;
|
||||||
|
|
||||||
let (sdl_context, mut canvas) = init_canvas(image_width, image_height)?;
|
let (sdl_context, mut canvas) = init_canvas(image_width, image_height)?;
|
||||||
|
|
||||||
|
|
@ -115,42 +118,46 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump()?;
|
let mut event_pump = sdl_context.event_pump()?;
|
||||||
|
|
||||||
'running: for tile in TileIterator::new(image_width as usize, image_height as usize, 16) {
|
let (tile_tx, tile_rx) = mpsc::channel();
|
||||||
let image_ptr = output_image.clone();
|
let mut tile_rx = Some(tile_rx);
|
||||||
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 locked_image = output_image.lock().unwrap();
|
let output_image_workers = Arc::clone(&output_image);
|
||||||
let mut output_image_rgbu8 = ImageRgbU8::new(image_width, image_height);
|
let worker_boss = std::thread::spawn(move || {
|
||||||
ClampingToneMapper {}.apply_tone_mapping(&locked_image, &mut output_image_rgbu8);
|
TileIterator::new(image_width as usize, image_height as usize, 16)
|
||||||
update_texture(&output_image_rgbu8, &mut rendered_image_texture);
|
.map(move |tile| (tile, tile_tx.clone()))
|
||||||
canvas.copy(&rendered_image_texture, None, None)?;
|
.par_bridge()
|
||||||
canvas.present();
|
.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,
|
||||||
|
);
|
||||||
|
|
||||||
for event in event_pump.poll_iter() {
|
// There's nothing we can do if this fails, and we're already
|
||||||
match event {
|
// at the end of the function anyway, so just ignore result.
|
||||||
Event::Quit { .. }
|
tx.send(tile).ok()
|
||||||
| Event::KeyDown {
|
});
|
||||||
keycode: Some(Keycode::Escape),
|
});
|
||||||
..
|
|
||||||
} => break 'running,
|
'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);
|
||||||
|
canvas.copy(&rendered_image_texture, None, None).unwrap();
|
||||||
|
canvas.present();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut i = 0;
|
|
||||||
'running: loop {
|
|
||||||
i = (i + 1) % 255;
|
|
||||||
for event in event_pump.poll_iter() {
|
for event in event_pump.poll_iter() {
|
||||||
match event {
|
match event {
|
||||||
Event::Quit { .. }
|
Event::Quit { .. }
|
||||||
|
|
@ -164,5 +171,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||||
}
|
}
|
||||||
|
drop(tile_rx.take());
|
||||||
|
worker_boss.join().expect("Couldn't join worker threads.");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ pub mod axis_aligned_bounding_box;
|
||||||
pub mod morton;
|
pub mod morton;
|
||||||
pub mod normalizer;
|
pub mod normalizer;
|
||||||
mod tile_iterator;
|
mod tile_iterator;
|
||||||
pub use tile_iterator::TileIterator;
|
pub use tile_iterator::{Tile, TileIterator};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#[derive(Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Tile {
|
pub struct Tile {
|
||||||
pub start_column: usize,
|
pub start_column: usize,
|
||||||
pub end_column: usize,
|
pub end_column: usize,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue