mirror of
https://github.com/CrispyPin/julia-fractal-renderer.git
synced 2024-11-22 10:00:26 +01:00
calculate predicted render time
This commit is contained in:
parent
583299c136
commit
8b4dcb39c8
2 changed files with 48 additions and 46 deletions
|
@ -7,7 +7,7 @@ pub struct RenderOptions {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
pub unit_width: f64,
|
pub unit_width: f64,
|
||||||
pub max_iterations: u32,
|
pub iterations: u32,
|
||||||
pub cx: f64,
|
pub cx: f64,
|
||||||
pub cy: f64,
|
pub cy: f64,
|
||||||
pub fill_style: FillStyle,
|
pub fill_style: FillStyle,
|
||||||
|
@ -25,7 +25,7 @@ impl Default for RenderOptions {
|
||||||
width: 512,
|
width: 512,
|
||||||
height: 512,
|
height: 512,
|
||||||
unit_width: 4.0,
|
unit_width: 4.0,
|
||||||
max_iterations: 128,
|
iterations: 128,
|
||||||
cx: -0.8,
|
cx: -0.8,
|
||||||
cy: -0.27,
|
cy: -0.27,
|
||||||
fill_style: FillStyle::Bright,
|
fill_style: FillStyle::Bright,
|
||||||
|
@ -49,8 +49,8 @@ pub fn view_point(q: &RenderOptions, image: RgbImage) -> RgbImage {
|
||||||
pub fn render(q: &RenderOptions, color: (u8, u8, u8)) -> RgbImage {
|
pub fn render(q: &RenderOptions, color: (u8, u8, u8)) -> RgbImage {
|
||||||
let img = RgbImage::new(q.width, q.height);
|
let img = RgbImage::new(q.width, q.height);
|
||||||
apply_fn(img, q, |x, y| {
|
apply_fn(img, q, |x, y| {
|
||||||
let i = julia(x, y, q.cx, q.cy, q.max_iterations);
|
let i = julia(x, y, q.cx, q.cy, q.iterations);
|
||||||
if q.fill_style == FillStyle::Black && i == q.max_iterations {
|
if q.fill_style == FillStyle::Black && i == q.iterations {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let i = i.min(255) as u8;
|
let i = i.min(255) as u8;
|
||||||
|
|
86
src/main.rs
86
src/main.rs
|
@ -41,7 +41,7 @@ struct JuliaGUI {
|
||||||
color: (u8, u8, u8),
|
color: (u8, u8, u8),
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
preview: Option<TextureHandle>,
|
preview: Option<TextureHandle>,
|
||||||
render_options: RenderOptions,
|
settings: RenderOptions,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
preview_render_ms: f64,
|
preview_render_ms: f64,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
|
@ -73,7 +73,7 @@ impl Default for JuliaGUI {
|
||||||
Self {
|
Self {
|
||||||
color: (12, 5, 10),
|
color: (12, 5, 10),
|
||||||
preview: None,
|
preview: None,
|
||||||
render_options: RenderOptions::default(),
|
settings: RenderOptions::default(),
|
||||||
preview_render_ms: 0.0,
|
preview_render_ms: 0.0,
|
||||||
export_render_ms: None,
|
export_render_ms: None,
|
||||||
export_res_power: 3,
|
export_res_power: 3,
|
||||||
|
@ -142,9 +142,9 @@ impl JuliaGUI {
|
||||||
|
|
||||||
fn update_preview(&mut self) {
|
fn update_preview(&mut self) {
|
||||||
let start_time = SystemTime::now();
|
let start_time = SystemTime::now();
|
||||||
let mut frame = render(&self.render_options, self.color);
|
let mut frame = render(&self.settings, self.color);
|
||||||
if self.preview_point {
|
if self.preview_point {
|
||||||
frame = view_point(&self.render_options, frame);
|
frame = view_point(&self.settings, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(preview) = &mut self.preview {
|
if let Some(preview) = &mut self.preview {
|
||||||
|
@ -164,10 +164,10 @@ impl JuliaGUI {
|
||||||
if let Some(channel) = &self.render_thread {
|
if let Some(channel) = &self.render_thread {
|
||||||
let res_mul = 1 << self.export_res_power;
|
let res_mul = 1 << self.export_res_power;
|
||||||
let settings = RenderOptions {
|
let settings = RenderOptions {
|
||||||
width: self.render_options.width * res_mul,
|
width: self.settings.width * res_mul,
|
||||||
height: self.render_options.height * res_mul,
|
height: self.settings.height * res_mul,
|
||||||
max_iterations: self.export_iterations,
|
iterations: self.export_iterations,
|
||||||
..self.render_options.clone()
|
..self.settings.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
channel
|
channel
|
||||||
|
@ -217,23 +217,18 @@ impl eframe::App for JuliaGUI {
|
||||||
|
|
||||||
let set_point_vis = ui.checkbox(&mut self.preview_point, "View C point");
|
let set_point_vis = ui.checkbox(&mut self.preview_point, "View C point");
|
||||||
ui.label("C point (X, Y):");
|
ui.label("C point (X, Y):");
|
||||||
let set_cx = ui.add(Slider::new(&mut self.render_options.cx, -2.0..=2.0));
|
let set_cx =
|
||||||
let set_cy = ui.add(Slider::new(&mut self.render_options.cy, -2.0..=2.0));
|
ui.add(Slider::new(&mut self.settings.cx, -1.0..=1.0).clamp_to_range(false));
|
||||||
|
let set_cy =
|
||||||
|
ui.add(Slider::new(&mut self.settings.cy, -1.0..=1.0).clamp_to_range(false));
|
||||||
ui.label("render width:");
|
ui.label("render width:");
|
||||||
let set_unit_width =
|
let set_unit_width = ui.add(Slider::new(&mut self.settings.unit_width, 0.1..=6.0));
|
||||||
ui.add(Slider::new(&mut self.render_options.unit_width, 0.1..=6.0));
|
|
||||||
ui.label("Fill style:");
|
ui.label("Fill style:");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let set_black = ui.radio_value(
|
let set_black =
|
||||||
&mut self.render_options.fill_style,
|
ui.radio_value(&mut self.settings.fill_style, FillStyle::Black, "Black");
|
||||||
FillStyle::Black,
|
let set_bright =
|
||||||
"Black",
|
ui.radio_value(&mut self.settings.fill_style, FillStyle::Bright, "Bright");
|
||||||
);
|
|
||||||
let set_bright = ui.radio_value(
|
|
||||||
&mut self.render_options.fill_style,
|
|
||||||
FillStyle::Bright,
|
|
||||||
"Bright",
|
|
||||||
);
|
|
||||||
if set_bright.changed() || set_black.changed() {
|
if set_bright.changed() || set_black.changed() {
|
||||||
self.settings_changed = true;
|
self.settings_changed = true;
|
||||||
}
|
}
|
||||||
|
@ -277,22 +272,19 @@ impl eframe::App for JuliaGUI {
|
||||||
let set_blue = ui.add(Slider::new(&mut self.color.2, 0..=16));
|
let set_blue = ui.add(Slider::new(&mut self.color.2, 0..=16));
|
||||||
|
|
||||||
ui.label("Preview iterations:");
|
ui.label("Preview iterations:");
|
||||||
let set_iter = ui.add(
|
let set_iter = ui
|
||||||
Slider::new(&mut self.render_options.max_iterations, 5..=256)
|
.add(Slider::new(&mut self.settings.iterations, 5..=256).clamp_to_range(false));
|
||||||
.clamp_to_range(false),
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.label(RichText::new("Render settings").heading());
|
|
||||||
ui.label("Preview resolution:");
|
ui.label("Preview resolution:");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let set_width = ui.add(
|
let set_width = ui.add(
|
||||||
DragValue::new(&mut self.render_options.width)
|
DragValue::new(&mut self.settings.width)
|
||||||
.clamp_range(128..=2048)
|
.clamp_range(128..=2048)
|
||||||
.suffix("px"),
|
.suffix("px"),
|
||||||
);
|
);
|
||||||
ui.label("x");
|
ui.label("x");
|
||||||
let set_height = ui.add(
|
let set_height = ui.add(
|
||||||
DragValue::new(&mut self.render_options.height)
|
DragValue::new(&mut self.settings.height)
|
||||||
.clamp_range(128..=2048)
|
.clamp_range(128..=2048)
|
||||||
.suffix("px"),
|
.suffix("px"),
|
||||||
);
|
);
|
||||||
|
@ -302,23 +294,18 @@ impl eframe::App for JuliaGUI {
|
||||||
});
|
});
|
||||||
ui.menu_button("presets", |ui| {
|
ui.menu_button("presets", |ui| {
|
||||||
if ui.button("1:1 512x512").clicked() {
|
if ui.button("1:1 512x512").clicked() {
|
||||||
self.render_options.width = 512;
|
self.settings.width = 512;
|
||||||
self.render_options.height = 512;
|
self.settings.height = 512;
|
||||||
self.settings_changed = true;
|
self.settings_changed = true;
|
||||||
}
|
}
|
||||||
if ui.button("16:9 960x540 (half hd)").clicked() {
|
if ui.button("16:9 960x540 (half hd)").clicked() {
|
||||||
self.render_options.width = 960;
|
self.settings.width = 960;
|
||||||
self.render_options.height = 540;
|
self.settings.height = 540;
|
||||||
self.settings_changed = true;
|
|
||||||
}
|
|
||||||
if ui.button("4:3 640x540").clicked() {
|
|
||||||
self.render_options.width = 640;
|
|
||||||
self.render_options.height = 540;
|
|
||||||
self.settings_changed = true;
|
self.settings_changed = true;
|
||||||
}
|
}
|
||||||
if ui.button("2:1 1024x512").clicked() {
|
if ui.button("2:1 1024x512").clicked() {
|
||||||
self.render_options.width = 1024;
|
self.settings.width = 1024;
|
||||||
self.render_options.height = 512;
|
self.settings.height = 512;
|
||||||
self.settings_changed = true;
|
self.settings_changed = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -329,8 +316,8 @@ impl eframe::App for JuliaGUI {
|
||||||
ui.add(Slider::new(&mut self.export_res_power, 0..=6).clamp_to_range(false));
|
ui.add(Slider::new(&mut self.export_res_power, 0..=6).clamp_to_range(false));
|
||||||
ui.label(format!(
|
ui.label(format!(
|
||||||
"Render resolution: {}x{}",
|
"Render resolution: {}x{}",
|
||||||
(1 << self.export_res_power) * self.render_options.width,
|
(1 << self.export_res_power) * self.settings.width,
|
||||||
(1 << self.export_res_power) * self.render_options.height
|
(1 << self.export_res_power) * self.settings.height
|
||||||
));
|
));
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
@ -358,6 +345,21 @@ impl eframe::App for JuliaGUI {
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let predicted_render_time = (self.preview_render_ms
|
||||||
|
* (1 << self.export_res_power * 2) as f64
|
||||||
|
* (self.export_iterations as f64 / self.settings.iterations as f64)
|
||||||
|
/ 1000.0)
|
||||||
|
.floor();
|
||||||
|
if predicted_render_time < 60.0 {
|
||||||
|
ui.label(format!("Predicted render time: {predicted_render_time}s"));
|
||||||
|
} else {
|
||||||
|
ui.label(format!(
|
||||||
|
"Predicted render time: {:.1} min",
|
||||||
|
predicted_render_time / 60.0
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ms) = self.export_render_ms {
|
if let Some(ms) = self.export_render_ms {
|
||||||
ui.label(format!("(took {ms:.2}ms)"));
|
ui.label(format!("(took {ms:.2}ms)"));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue