Multithread & pixelmap

master
E. Almqvist 3 years ago
parent 4a84e41e01
commit 8d394e857b
  1. 28
      mas/fractals/mandel/src/main.rs
  2. 7
      mas/fractals/mandel/src/mandel.rs
  3. 39
      mas/fractals/mandel/src/render.rs

@ -4,6 +4,7 @@ mod render;
use sdl2::pixels::Color; use sdl2::pixels::Color;
use sdl2::event::Event; use sdl2::event::Event;
use sdl2::keyboard::Keycode; use sdl2::keyboard::Keycode;
use std::thread;
fn main() { fn main() {
/* /*
@ -13,6 +14,8 @@ fn main() {
println!("{} {}", width, height); println!("{} {}", width, height);
*/ */
//let (width, height) = (640, 480); //let (width, height) = (640, 480);
// config stuff
let (width, height) = (1600, 900); let (width, height) = (1600, 900);
let (mut dx, mut dy) = (1.0, 0.0); let (mut dx, mut dy) = (1.0, 0.0);
let (mut zx, mut zy) = (2.8, 2.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 (zoom_out, zoom_in) = (1.1, 0.9);
let depth = 1000; 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 (window, ctx, _vid_sys) = render::create_window("Mandelbrot set", width, height);
let mut canvas = window.into_canvas().build().unwrap(); let mut canvas = window.into_canvas().build().unwrap();
@ -74,14 +82,22 @@ fn main() {
} }
if render_new { if render_new {
println!("Rendering..."); let mut maps = Vec::new();
mandel::mandelbrot(&mut canvas, width, height, depth, zx, zy, dx, dy); for thread_id in 0..threads {
canvas.present(); thread::spawn(move || { // do cool threads for performance
render_new = false; 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)); //::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
} }

@ -1,4 +1,5 @@
use crate::render::set_pixel; use crate::render::set_pixel;
use crate::render::PixelMap;
use sdl2::pixels::Color; use sdl2::pixels::Color;
use sdl2::render::Canvas; use sdl2::render::Canvas;
@ -10,7 +11,7 @@ pub fn get_col(i: u32, max_iter: u32) -> Color {
} }
} }
pub fn mandelbrot(canvas: &mut Canvas<sdl2::video::Window>, 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 for each pixel (Px, Py) on the screen do
@ -35,7 +36,7 @@ pub fn mandelbrot(canvas: &mut Canvas<sdl2::video::Window>, w: u32, h: u32, dept
for dy in 0..h { for dy in 0..h {
let y0 = ((dy as f32) / (h as f32)) * (yzoom) - (1.0 + yoffset); 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; let mut i: u32 = 0;
while i < depth && x*x + y*y <= 4.0 { while i < depth && x*x + y*y <= 4.0 {
@ -45,7 +46,7 @@ pub fn mandelbrot(canvas: &mut Canvas<sdl2::video::Window>, w: u32, h: u32, dept
i += 1; i += 1;
} }
let col = get_col(i, depth); 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);
} }
} }
} }

@ -1,7 +1,11 @@
extern crate sdl2; extern crate sdl2;
use sdl2::pixels::Color; use sdl2::pixels::Color;
use sdl2::rect::Rect; use sdl2::rect::Rect;
use sdl2::render::Canvas; use sdl2::render::Canvas;
use crate::mandel::mandelbrot;
//use std::time::Duration;
//use sdl2::ttf::Font; //use sdl2::ttf::Font;
pub fn create_window(title: &str, width: u32, height: u32) 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); 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<Color>
}
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) { pub fn text(x: u32, y: u32, text: &str, font_path: &str) {
let ttf_context = sdl2::ttf::init(); let ttf_context = sdl2::ttf::init();
@ -35,3 +65,12 @@ pub fn set_pixel(canvas: &mut Canvas<sdl2::video::Window>, x: i32, y: i32, color
canvas.set_draw_color(color); canvas.set_draw_color(color);
canvas.fill_rect(Rect::new(x, y, 1, 1)); 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;
}

Loading…
Cancel
Save