add export options

This commit is contained in:
Crispy 2023-07-13 21:32:02 +02:00
parent 7c7d56e868
commit c76f340fd7
2 changed files with 44 additions and 27 deletions

View file

@ -20,15 +20,15 @@ pub enum FillStyle {
pub fn render(q: &RenderOptions, color: (u8, u8, u8)) -> RgbImage { pub fn render(q: &RenderOptions, color: (u8, u8, u8)) -> RgbImage {
let mut img = RgbImage::new(q.width, q.height); let mut img = RgbImage::new(q.width, q.height);
let width = q.width as f64; let width: f64 = q.width.into();
let height = q.height as f64; let height: f64 = q.height.into();
let ppu = width / q.unit_width; let ppu = width / q.unit_width;
for y in 0..q.height { for y in 0..q.height {
for x in 0..q.width { for x in 0..q.width {
let pixel = { let pixel = {
let x = (x as f64 - width / 2.0) / ppu; let x = (f64::from(x) - width / 2.0) / ppu;
let y = (y as f64 - height / 2.0) / ppu; let y = (f64::from(y) - height / 2.0) / ppu;
let iter = julia(x, y, q.cx, q.cy, q.max_iterations); let iter = julia(x, y, q.cx, q.cy, q.max_iterations);
if q.fill_style == FillStyle::Black && iter == q.max_iterations { if q.fill_style == FillStyle::Black && iter == q.max_iterations {
@ -57,5 +57,5 @@ fn julia(mut x: f64, mut y: f64, cx: f64, cy: f64, max_iter: u32) -> u32 {
); );
iter += 1; iter += 1;
} }
return iter; iter
} }

View file

@ -2,7 +2,7 @@
use std::time::SystemTime; use std::time::SystemTime;
use eframe::{ use eframe::{
egui::{self, RichText, Slider}, egui::{self, DragValue, RichText, Slider, TextureOptions},
epaint::{TextureHandle, Vec2}, epaint::{TextureHandle, Vec2},
Frame, NativeOptions, Frame, NativeOptions,
}; };
@ -40,9 +40,9 @@ struct JuliaGUI {
impl JuliaGUI { impl JuliaGUI {
fn new(cc: &eframe::CreationContext<'_>) -> Self { fn new(cc: &eframe::CreationContext<'_>) -> Self {
let preview = cc.egui_ctx.load_texture( let preview = cc.egui_ctx.load_texture(
"my-image", "preview_image",
egui::ColorImage::from_rgb([1, 1], &[0, 0, 0]), egui::ColorImage::from_rgb([1, 1], &[0, 0, 0]),
Default::default(), TextureOptions::default(),
); );
let preview_quality = RenderOptions { let preview_quality = RenderOptions {
width: 512, width: 512,
@ -60,7 +60,7 @@ impl JuliaGUI {
render_options: preview_quality, render_options: preview_quality,
preview_render_ms: 0.0, preview_render_ms: 0.0,
export_render_ms: f64::NAN, export_render_ms: f64::NAN,
export_res_multiplier: 4, export_res_multiplier: 8,
export_iterations: 512, export_iterations: 512,
export_name: String::from("julia_set.png"), export_name: String::from("julia_set.png"),
settings_changed: true, settings_changed: true,
@ -75,7 +75,7 @@ impl JuliaGUI {
[preview.width() as usize, preview.height() as usize], [preview.width() as usize, preview.height() as usize],
preview.as_bytes(), preview.as_bytes(),
), ),
Default::default(), TextureOptions::default(),
); );
self.preview_render_ms = start_time.elapsed().unwrap().as_micros() as f64 / 1000.0; self.preview_render_ms = start_time.elapsed().unwrap().as_micros() as f64 / 1000.0;
} }
@ -89,8 +89,8 @@ impl JuliaGUI {
..self.render_options.clone() ..self.render_options.clone()
}; };
let image = render(&settings, self.color); let image = render(&settings, self.color);
if let Err(e) = image.save(&self.export_name) { if let Err(err) = image.save(&self.export_name) {
println!("Error exporting render: {e}"); println!("Error exporting render: {err}");
} }
self.export_render_ms = start_time.elapsed().unwrap().as_micros() as f64 / 1000.0; self.export_render_ms = start_time.elapsed().unwrap().as_micros() as f64 / 1000.0;
} }
@ -107,6 +107,7 @@ impl eframe::App for JuliaGUI {
.resizable(false) .resizable(false)
.exact_width(200.0) .exact_width(200.0)
.show(ctx, |ui| { .show(ctx, |ui| {
ui.label(RichText::new("Fractal settings").heading());
if ui.button("Update preview").clicked() { if ui.button("Update preview").clicked() {
self.settings_changed = true; self.settings_changed = true;
} }
@ -115,18 +116,6 @@ impl eframe::App for JuliaGUI {
self.preview_render_ms self.preview_render_ms
)); ));
if ui
.button(format!("Render to '{}'", &self.export_name))
.clicked()
{
self.export_render();
}
ui.label(format!(
"last exported render took {:.2}ms",
self.export_render_ms
));
ui.label("CX:"); ui.label("CX:");
let set_cx = ui.add(Slider::new(&mut self.render_options.cx, -2.0..=2.0)); let set_cx = ui.add(Slider::new(&mut self.render_options.cx, -2.0..=2.0));
ui.label("CY:"); ui.label("CY:");
@ -151,13 +140,41 @@ impl eframe::App for JuliaGUI {
} }
}); });
ui.label(RichText::new("Quality settings").heading()); ui.label("Preview iterations:");
ui.label("iterations:");
let set_iter = ui.add( let set_iter = ui.add(
Slider::new(&mut self.render_options.max_iterations, 5..=256) Slider::new(&mut self.render_options.max_iterations, 5..=256)
.clamp_to_range(false), .clamp_to_range(false),
); );
//todo resolution
ui.label(RichText::new("Render settings").heading());
ui.label("preview resolution:");
ui.horizontal(|ui| {
let set_width = ui.add(DragValue::new(&mut self.render_options.width));
ui.label("x");
let set_height = ui.add(DragValue::new(&mut self.render_options.height));
if set_width.changed() || set_height.changed() {
self.settings_changed = true;
}
});
ui.label("Export iterations:");
ui.add(Slider::new(&mut self.export_iterations, 5..=1024).clamp_to_range(false));
ui.label("Resolution multiplier:");
ui.add(Slider::new(&mut self.export_res_multiplier, 1..=32));
ui.label(format!(
"Export resolution: {}x{}",
self.export_res_multiplier * self.render_options.width,
self.export_res_multiplier * self.render_options.height
));
let render_button = ui.button(format!("Render to '{}'", &self.export_name));
if render_button.clicked() {
self.export_render();
}
ui.label(format!(
"last exported render took {:.2}ms",
self.export_render_ms
));
if set_cx.changed() if set_cx.changed()
|| set_cy.changed() || set_unit_width.changed() || set_cy.changed() || set_unit_width.changed()