diff --git a/mas/fractals/mandel/src/main.rs b/mas/fractals/mandel/src/main.rs index 4516566..ca8954d 100644 --- a/mas/fractals/mandel/src/main.rs +++ b/mas/fractals/mandel/src/main.rs @@ -4,6 +4,7 @@ mod render; use sdl2::pixels::Color; use sdl2::event::Event; use sdl2::keyboard::Keycode; +use std::thread; fn main() { /* @@ -13,6 +14,8 @@ fn main() { println!("{} {}", width, height); */ //let (width, height) = (640, 480); + + // config stuff let (width, height) = (1600, 900); let (mut dx, mut dy) = (1.0, 0.0); let (mut zx, mut zy) = (2.8, 2.0); @@ -20,6 +23,11 @@ fn main() { let (zoom_out, zoom_in) = (1.1, 0.9); let depth = 1000; + // Sectors for multithreading + let threads = 4; + let (w_sector_size, h_sector_size) = (width/threads, height/threads); + + // create window let (window, ctx, _vid_sys) = render::create_window("Mandelbrot set", width, height); let mut canvas = window.into_canvas().build().unwrap(); @@ -74,14 +82,22 @@ fn main() { } if render_new { - println!("Rendering..."); - mandel::mandelbrot(&mut canvas, width, height, depth, zx, zy, dx, dy); - canvas.present(); - render_new = false; + let mut maps = Vec::new(); + for thread_id in 0..threads { + thread::spawn(move || { // do cool threads for performance + let mut pixmap = render::prerender_mandelbrot( + width, height, depth, + zx, zy, dx, dy, + thread_id, threads, w_sector_size, h_sector_size); + maps.push(pixmap); + }); + } - println!("Post mandel render"); + for pixmap in maps.iter() { + // do render + } + render_new = false; } - } //::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); } diff --git a/mas/fractals/mandel/src/mandel.rs b/mas/fractals/mandel/src/mandel.rs index b9b8e88..5c5871f 100644 --- a/mas/fractals/mandel/src/mandel.rs +++ b/mas/fractals/mandel/src/mandel.rs @@ -1,4 +1,5 @@ use crate::render::set_pixel; +use crate::render::PixelMap; use sdl2::pixels::Color; use sdl2::render::Canvas; @@ -10,7 +11,7 @@ pub fn get_col(i: u32, max_iter: u32) -> Color { } } -pub fn mandelbrot(canvas: &mut Canvas, w: u32, h: u32, depth: u32, xzoom: f32, yzoom: f32, xoffset: f32, yoffset: f32) { +pub fn mandelbrot(pixmap: &mut PixelMap, w: u32, h: u32, depth: u32, xzoom: f32, yzoom: f32, xoffset: f32, yoffset: f32) { /* for each pixel (Px, Py) on the screen do @@ -35,7 +36,7 @@ pub fn mandelbrot(canvas: &mut Canvas, w: u32, h: u32, dept for dy in 0..h { let y0 = ((dy as f32) / (h as f32)) * (yzoom) - (1.0 + yoffset); - let (mut x, mut y) = (0.0, 0.0); + let (mut x, mut y) = (0.0, 0.0); let mut i: u32 = 0; while i < depth && x*x + y*y <= 4.0 { @@ -45,7 +46,7 @@ pub fn mandelbrot(canvas: &mut Canvas, w: u32, h: u32, dept i += 1; } let col = get_col(i, depth); - set_pixel(canvas, dx as i32, dy as i32, col); + pixmap.set_pixel(dx as u32, dy as u32, col); } } } diff --git a/mas/fractals/mandel/src/render.rs b/mas/fractals/mandel/src/render.rs index 3ca7341..11c66f0 100644 --- a/mas/fractals/mandel/src/render.rs +++ b/mas/fractals/mandel/src/render.rs @@ -1,7 +1,11 @@ extern crate sdl2; + use sdl2::pixels::Color; use sdl2::rect::Rect; use sdl2::render::Canvas; + +use crate::mandel::mandelbrot; +//use std::time::Duration; //use sdl2::ttf::Font; pub fn create_window(title: &str, width: u32, height: u32) @@ -17,6 +21,32 @@ pub fn create_window(title: &str, width: u32, height: u32) return (window, ctx, vid_sys); } +pub struct PixelMap { + pub offset_cols: u32, + pub offset_rows: u32, + pub cols: u32, + pub rows: u32, + pub data: Vec +} + +impl PixelMap { + fn new(cols: u32, rows: u32, offset_cols: u32, offset_rows: u32) -> PixelMap { + PixelMap { + offset_cols: offset_cols, + offset_rows: offset_rows, + cols: cols, + rows: rows, + data: vec![Color::RGB(0,0,0); (cols as usize)*(rows as usize)] + } + } + + pub fn set_pixel(&mut self, x: u32, y: u32, color: Color) { + // A[c, r] = a[r*rows + c] + // for a vec of U^(cols*rows) + self.data[((self.rows * y) + x) as usize] = color; + } +} + /* pub fn text(x: u32, y: u32, text: &str, font_path: &str) { let ttf_context = sdl2::ttf::init(); @@ -35,3 +65,12 @@ pub fn set_pixel(canvas: &mut Canvas, x: i32, y: i32, color canvas.set_draw_color(color); canvas.fill_rect(Rect::new(x, y, 1, 1)); } + +pub fn prerender_mandelbrot(w: u32, h: u32, depth: u32, xzoom: f32, yzoom: f32, xoffset: f32, yoffset: f32, thread_id: u32, threads: u32, w_sector_size: u32, h_sector_size: u32) -> PixelMap { + println!("Rendering..."); + let mut pixmap = PixelMap::new(w, h, thread_id * w_sector_size, thread_id * h_sector_size); + mandelbrot(&mut pixmap, w, h, depth, xzoom, yzoom, xoffset, yoffset); + println!("Post mandel render"); + + return pixmap; +}