summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md6
-rw-r--r--Cargo.toml2
-rw-r--r--source/benoit/benoit.rs29
-rw-r--r--source/benoit/benoit/app.rs10
-rw-r--r--source/benoit/benoit/app/animate.rs2
-rw-r--r--source/benoit/benoit/app/handle_keys.rs22
-rw-r--r--source/benoit/benoit/app/initialise.rs8
-rw-r--r--source/benoit/benoit/app/interactive.rs12
-rw-r--r--source/benoit/benoit/app/run.rs2
-rw-r--r--source/benoit/benoit/app/still.rs2
-rw-r--r--source/benoit/benoit/configuration.rs4
-rw-r--r--source/benoit/benoit/render.rs5
-rw-r--r--source/benoit/benoit/render/iterate/multibrot3.rs16
-rw-r--r--source/benoit/benoit/render/render.rs32
-rw-r--r--source/benoit/benoit/render/render_data.rs40
-rw-r--r--source/benoit/benoit/render/render_point.rs (renamed from source/benoit/benoit/render/render_row.rs)0
-rw-r--r--source/benoit/benoit/render/render_point/julia.rs76
-rw-r--r--source/benoit/benoit/render/render_point/normal.rs89
-rw-r--r--source/benoit/benoit/render/render_row/julia.rs84
-rw-r--r--source/benoit/benoit/render/render_row/normal.rs94
-rw-r--r--source/benoit/benoit/rendering.rs10
-rw-r--r--source/benoit/benoit/video/initialise.rs2
-rw-r--r--source/benoit/benoit/width_height_ratio.rs30
23 files changed, 301 insertions, 276 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 26a68fd..5c9a622 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 2.2.0
+
+* Bump minor version
+* Rework row renderers as point renderers
+* Support inverse fractals (toggle with left control)
+
# 2.1.1
* Update readme
diff --git a/Cargo.toml b/Cargo.toml
index 1e0d590..a6768dd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "benoit"
-version = "2.1.0"
+version = "2.2.0"
authors = ["Gabriel Bjørnager Jensen"]
edition = "2021"
description = "Mandelbrot renderer."
diff --git a/source/benoit/benoit.rs b/source/benoit/benoit.rs
index c384b5b..a366c61 100644
--- a/source/benoit/benoit.rs
+++ b/source/benoit/benoit.rs
@@ -32,24 +32,17 @@ pub mod palette;
pub mod rendering;
pub mod render;
pub mod video;
-pub mod width_height_ratio;
-pub use width_height_ratio::*;
-
-pub struct Version<T> {
- major: T,
- minor: T,
- patch: T,
-}
-
-pub const VERSION: Version::<u32> = Version::<u32> {
- major: 0x2,
- minor: 0x1,
- patch: 0x1,
-};
+pub const VERSION: [u32; 0x3] = [
+ 0x2,
+ 0x2,
+ 0x0,
+];
pub const PRECISION: u32 = 0x80;
+pub const BAILOUT: f32 = 256.0;
+
#[derive(Clone, Copy)]
pub enum ImageFormat {
Png,
@@ -64,3 +57,11 @@ pub struct FeedbackInfo<'a> {
next_centre_imag: &'a Float,
next_zoom: &'a Float,
}
+
+pub fn width_height_ratio(width: u32, height: u32) -> (f32, f32) {
+ return if width > height {
+ (1.0, height as f32 / width as f32)
+ } else {
+ (width as f32 / height as f32, 1.0)
+ };
+}
diff --git a/source/benoit/benoit/app.rs b/source/benoit/benoit/app.rs
index feac808..fa047f9 100644
--- a/source/benoit/benoit/app.rs
+++ b/source/benoit/benoit/app.rs
@@ -25,7 +25,7 @@ use crate::benoit::ImageFormat;
use crate::benoit::fractal::Fractal;
use crate::benoit::palette::Palette;
use crate::benoit::rendering::Rendering;
-use crate::benoit::render::{IteratorFunction, RowRenderer};
+use crate::benoit::render::{IteratorFunction, PointRenderer};
use crate::benoit::video::Video;
extern crate rug;
@@ -60,10 +60,12 @@ pub struct App {
centre_imag: Float,
zoom: Float,
- multibrot_exponent: f32,
-
max_iter_count: u32,
+ inverse: bool,
+
+ multibrot_exponent: f32,
+
palette: Palette,
colour_range: f32,
@@ -76,6 +78,6 @@ pub struct App {
do_render: bool,
do_textual_feedback: bool,
- row_renderer: RowRenderer,
+ point_renderer: PointRenderer,
iterator_function: IteratorFunction,
}
diff --git a/source/benoit/benoit/app/animate.rs b/source/benoit/benoit/app/animate.rs
index 3d35bdb..9a6b4ba 100644
--- a/source/benoit/benoit/app/animate.rs
+++ b/source/benoit/benoit/app/animate.rs
@@ -79,7 +79,7 @@ impl App {
let time_start = Instant::now();
- render(&mut iter_count_buffer[..], &mut square_dist_buffer[..], self.canvas_width, self.canvas_height, &self.centre_real, &self.centre_imag, &zoom, self.max_iter_count, self.row_renderer, self.iterator_function);
+ render(&mut iter_count_buffer[..], &mut square_dist_buffer[..], self.canvas_width, self.canvas_height, &self.centre_real, &self.centre_imag, &zoom, self.max_iter_count, self.inverse, self.point_renderer, self.iterator_function);
let render_time = time_start.elapsed();
eprint!(" {:.3}ms, colouring...", render_time.as_micros() as f32 / 1000.0);
diff --git a/source/benoit/benoit/app/handle_keys.rs b/source/benoit/benoit/app/handle_keys.rs
index 0dc5b5a..3f9c0dd 100644
--- a/source/benoit/benoit/app/handle_keys.rs
+++ b/source/benoit/benoit/app/handle_keys.rs
@@ -25,7 +25,7 @@ use crate::benoit::{PRECISION};
use crate::benoit::app::App;
use crate::benoit::fractal::Fractal;
use crate::benoit::palette::Palette;
-use crate::benoit::render::{IteratorFunction, RowRenderer};
+use crate::benoit::render::{IteratorFunction, PointRenderer};
use crate::benoit::rendering::Rendering;
extern crate rug;
@@ -44,10 +44,11 @@ impl App {
Scancode::Escape => return true,
Scancode::F1 => self.do_textual_feedback = !self.do_textual_feedback,
Scancode::LAlt => (self.fractal, self.multibrot_exponent, self.iterator_function) = cycle_fractal(self.fractal, -0x1),
+ Scancode::LCtrl => self.inverse = toggle_inverse(self.inverse),
Scancode::Left => self.palette = cycle_palette(self.palette, -0x1),
Scancode::RAlt => (self.fractal, self.multibrot_exponent, self.iterator_function) = cycle_fractal(self.fractal, 0x1),
Scancode::Right => self.palette = cycle_palette(self.palette, 0x1),
- Scancode::Tab => (self.rendering, self.row_renderer) = toggle_julia(self.rendering),
+ Scancode::Tab => (self.rendering, self.point_renderer) = toggle_julia(self.rendering),
Scancode::Z => eprintln!("c = {}{:+}i, {}x @ {} iter. (range.: {:.3})", &self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count, self.colour_range),
_ => {},
}
@@ -113,17 +114,28 @@ fn cycle_fractal(fractal: Fractal, distance: i8) -> (Fractal, f32, IteratorFunct
return (fractal, exponent, iterator_function);
}
-fn toggle_julia(rendering: Rendering) -> (Rendering, RowRenderer) {
+fn toggle_julia(rendering: Rendering) -> (Rendering, PointRenderer) {
let rendering = rendering.cycle();
- let row_renderer = rendering.get_row_renderer();
+ let point_renderer = rendering.get_point_renderer();
match rendering {
Rendering::Julia => eprintln!("enabled the julia set"),
Rendering::Normal => eprintln!("disabled the julia set"),
};
- return (rendering, row_renderer);
+ return (rendering, point_renderer);
+}
+
+fn toggle_inverse(inverse: bool) -> bool {
+ let inverse = !inverse;
+
+ match inverse {
+ false => eprintln!("reverting fractal"),
+ true => eprintln!("inverting fractals"),
+ };
+
+ return inverse;
}
fn cycle_palette(palette: Palette, direction: i8) -> Palette {
diff --git a/source/benoit/benoit/app/initialise.rs b/source/benoit/benoit/app/initialise.rs
index 75535e8..f4b4f8e 100644
--- a/source/benoit/benoit/app/initialise.rs
+++ b/source/benoit/benoit/app/initialise.rs
@@ -74,10 +74,12 @@ impl App {
centre_imag: configuration.centre_imag,
zoom: configuration.zoom,
- multibrot_exponent: 2.0,
-
max_iter_count: configuration.max_iter_count,
+ inverse: configuration.inverse,
+
+ multibrot_exponent: configuration.fractal.get_exponent(),
+
palette: configuration.palette,
colour_range: configuration.colour_range,
@@ -90,7 +92,7 @@ impl App {
do_render: true,
do_textual_feedback: false,
- row_renderer: configuration.rendering.get_row_renderer(),
+ point_renderer: configuration.rendering.get_point_renderer(),
iterator_function: configuration.fractal.get_iterator(),
};
}
diff --git a/source/benoit/benoit/app/interactive.rs b/source/benoit/benoit/app/interactive.rs
index e4ecd7c..a5cc51f 100644
--- a/source/benoit/benoit/app/interactive.rs
+++ b/source/benoit/benoit/app/interactive.rs
@@ -63,7 +63,7 @@ impl App {
let time_start = Instant::now();
- render(&mut iter_count_buffer[..], &mut square_dist_buffer[..], self.canvas_width, self.canvas_height, &self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count, self.row_renderer, self.iterator_function);
+ render(&mut iter_count_buffer[..], &mut square_dist_buffer[..], self.canvas_width, self.canvas_height, &self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count, self.inverse, self.point_renderer, self.iterator_function);
let render_time = time_start.elapsed();
eprintln!(" {:.3}ms", render_time.as_micros() as f32 / 1000.0);
@@ -94,7 +94,7 @@ impl App {
pub fn draw_feedback(&self, video: &mut Video, prev_centre_real: &Float, prev_centre_imag: &Float, prev_zoom: &Float) {
let julia = match self.rendering {
Rendering::Julia => true,
- _ => false,
+ _ => false,
};
if {
@@ -135,15 +135,15 @@ impl App {
println!("- \u{1B}[1mR\u{1B}[0m Decrease max. iteration count");
println!("- \u{1B}[1mF\u{1B}[0m Increase max. iteration count");
println!();
- println!("- \u{1B}[1mTab\u{1B}[0m Toggle Julia");
println!("- \u{1B}[1mLeft Alt\u{1B}[0m Cycle to previous fractal");
println!("- \u{1B}[1mRight Alt\u{1B}[0m Cycle to next fractal");
- println!();
- println!("- \u{1B}[1mUp\u{1B}[0m Increase colour range");
- println!("- \u{1B}[1mDown\u{1B}[0m Decrease colour range");
+ println!("- \u{1B}[1mTab\u{1B}[0m Toggle Julia");
+ println!("- \u{1B}[1mLeft Ctrl\u{1B}[0m Toggle inverse");
println!();
println!("- \u{1B}[1mLeft\u{1B}[0m Cycle to previous palette");
println!("- \u{1B}[1mRight\u{1B}[0m Cycle to next palette");
+ println!("- \u{1B}[1mUp\u{1B}[0m Increase colour range");
+ println!("- \u{1B}[1mDown\u{1B}[0m Decrease colour range");
println!();
println!("- \u{1B}[1mF1\u{1B}[0m Toggle textual feedback");
println!("- \u{1B}[1mZ\u{1B}[0m Print centre value (c)");
diff --git a/source/benoit/benoit/app/run.rs b/source/benoit/benoit/app/run.rs
index b1ef578..cc8e3bb 100644
--- a/source/benoit/benoit/app/run.rs
+++ b/source/benoit/benoit/app/run.rs
@@ -30,7 +30,7 @@ impl App {
#[must_use]
pub fn run(&mut self) -> i32 {
println!();
- println!("\u{1B}[1mBENO\u{CE}T\u{1B}[0m {:X}.{:X}.{:X}", VERSION.major, VERSION.minor, VERSION.patch);
+ println!("\u{1B}[1mBENO\u{CE}T\u{1B}[0m {:X}.{:X}.{:X}", VERSION[0x0], VERSION[0x1], VERSION[0x2]);
println!("Copyright 2021, 2023 Gabriel Bj\u{F8}rnager Jensen.");
println!();
println!("COCITAVIT\u{B7}ERCO\u{B7}FVIT");
diff --git a/source/benoit/benoit/app/still.rs b/source/benoit/benoit/app/still.rs
index ff483b6..a5b6cc1 100644
--- a/source/benoit/benoit/app/still.rs
+++ b/source/benoit/benoit/app/still.rs
@@ -35,7 +35,7 @@ impl App {
eprint!("rendering at {}{:+}i ({}x)...", self.centre_real.to_f32(), self.centre_imag.to_f32(), self.zoom.to_f32());
let time_start = Instant::now();
- render(&mut iter_count_buffer[..], &mut square_dist_buffer[..], self.canvas_width, self.canvas_height, &self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count, self.row_renderer, self.iterator_function);
+ render(&mut iter_count_buffer[..], &mut square_dist_buffer[..], self.canvas_width, self.canvas_height, &self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count, self.inverse, self.point_renderer, self.iterator_function);
let render_time = time_start.elapsed();
eprint!(" {:.3}ms, colouring...", render_time.as_micros() as f32 / 1000.0);
diff --git a/source/benoit/benoit/configuration.rs b/source/benoit/benoit/configuration.rs
index ea6a841..2514ef8 100644
--- a/source/benoit/benoit/configuration.rs
+++ b/source/benoit/benoit/configuration.rs
@@ -51,6 +51,8 @@ pub struct Configuration {
pub max_iter_count: u32,
+ pub inverse: bool,
+
pub palette: Palette,
pub colour_range: f32,
@@ -80,6 +82,8 @@ impl Configuration {
max_iter_count: 0x100,
+ inverse: false,
+
palette: Palette::Fire,
colour_range: 64.0,
diff --git a/source/benoit/benoit/render.rs b/source/benoit/benoit/render.rs
index b6c0ac8..45da9ee 100644
--- a/source/benoit/benoit/render.rs
+++ b/source/benoit/benoit/render.rs
@@ -26,18 +26,17 @@ use crate::benoit::render::render_data::RenderData;
extern crate rug;
use rug::Float;
-use std::sync::Arc;
pub mod colour;
pub mod colour_data;
pub mod iterate;
pub mod render;
pub mod render_data;
-pub mod render_row;
+pub mod render_point;
pub use colour::*;
pub use render::*;
pub type IteratorFunction = fn(&mut Float, &mut Float, &Float, &Float);
-pub type RowRenderer = fn(Arc<RenderData>, u32, IteratorFunction);
+pub type PointRenderer = fn(&RenderData, u32, u32, IteratorFunction) -> (u32, f32);
diff --git a/source/benoit/benoit/render/iterate/multibrot3.rs b/source/benoit/benoit/render/iterate/multibrot3.rs
index 1de2e07..d0a7c2f 100644
--- a/source/benoit/benoit/render/iterate/multibrot3.rs
+++ b/source/benoit/benoit/render/iterate/multibrot3.rs
@@ -39,22 +39,22 @@ pub fn multibrot3(za: &mut Float, zb: &mut Float, ca: &Float, cb: &Float) {
// <=> z_a = a^3-3ab^2
// z_b = 3(a^2)b-b^3
- let mut tmp0 = Float::with_val(PRECISION, &*zb * &*zb); // b^2
+ let mut temporary0 = Float::with_val(PRECISION, &*zb * &*zb); // b^2
- let tmp1 = Float::with_val(PRECISION, &tmp0 * &*zb); // b^3
+ let temporary1 = Float::with_val(PRECISION, &temporary0 * &*zb); // b^3
- tmp0 *= &*za; // ab^2
- tmp0 *= 0x3; // 3ab^2
+ temporary0 *= &*za; // ab^2
+ temporary0 *= 0x3; // 3ab^2
za.square_mut(); // a^2
*zb *= &*za; // (a^2)b
*za *= &za_temporary; // a^3
- *za -= &tmp0; // a^3-3ab^2
+ *za -= &temporary0; // a^3-3ab^2
*za += ca; // a^3-3ab^2+Re(c)
- *zb *= 3.0; // 3(a^2)b
- *zb -= &tmp1; // 3(a^2)b-b^3
- *zb += cb; // 3(a^2)b-b^3+Im(c)
+ *zb *= 3.0; // 3(a^2)b
+ *zb -= &temporary1; // 3(a^2)b-b^3
+ *zb += cb; // 3(a^2)b-b^3+Im(c)
}
diff --git a/source/benoit/benoit/render/render.rs b/source/benoit/benoit/render/render.rs
index 947bca7..1ff0931 100644
--- a/source/benoit/benoit/render/render.rs
+++ b/source/benoit/benoit/render/render.rs
@@ -21,7 +21,7 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-use crate::benoit::render::{IteratorFunction, RowRenderer};
+use crate::benoit::render::{IteratorFunction, PointRenderer};
use crate::benoit::render::render_data::RenderData;
extern crate rayon;
@@ -29,12 +29,32 @@ extern crate rug;
use rayon::prelude::*;
use rug::Float;
-use std::sync::Arc;
-pub fn render(iter_count_buffer: &mut [u32], square_dist_buffer: &mut [f32], canvas_width: u32, canvas_height: u32, centre_real: &Float, centre_imag: &Float, zoom: &Float, max_iter_count: u32, row_renderer: RowRenderer, iterator: IteratorFunction) {
- let data = Arc::new(RenderData::new(iter_count_buffer, square_dist_buffer, canvas_width, canvas_height, centre_real.clone(), centre_imag.clone(), zoom.clone(), max_iter_count));
+pub fn render(iter_count_buffer: &mut [u32], square_dist_buffer: &mut [f32], canvas_width: u32, canvas_height: u32, centre_real: &Float, centre_imag: &Float, zoom: &Float, max_iter_count: u32, inverse: bool, point_renderer: PointRenderer, iterator: IteratorFunction) {
+ let data = RenderData::new(iter_count_buffer, square_dist_buffer, canvas_width, canvas_height, centre_real.clone(), centre_imag.clone(), zoom.clone(), max_iter_count, inverse);
- (0x0..canvas_height).into_par_iter().for_each(|row| {
- row_renderer(data.clone(), row as u32, iterator);
+ let (canvas_size, overflow) = canvas_height.overflowing_mul(canvas_width);
+ if overflow { panic!("overflow when calculating canvas size") };
+
+ (0x0..canvas_size).into_par_iter().for_each(|index| {
+ render_point(&data, index as u32, point_renderer, iterator);
});
}
+
+fn render_point(data: &RenderData, index: u32, point_renderer: PointRenderer, iterator: IteratorFunction) {
+ let (iter_count_buffer, square_dist_buffer) = data.output_buffers();
+
+ let (canvas_width, _) = data.canvas_size();
+
+ let x = index % canvas_width;
+ let y = index / canvas_width;
+
+ let (iter_count, square_dist) = point_renderer(&data, x, y, iterator);
+
+ // Sacrifice safety for speed by removing bounds-
+ // checking.
+ unsafe {
+ *iter_count_buffer.get_unchecked_mut( index as usize) = iter_count;
+ *square_dist_buffer.get_unchecked_mut(index as usize) = square_dist;
+ }
+}
diff --git a/source/benoit/benoit/render/render_data.rs b/source/benoit/benoit/render/render_data.rs
index 765c0c0..a1d2fdd 100644
--- a/source/benoit/benoit/render/render_data.rs
+++ b/source/benoit/benoit/render/render_data.rs
@@ -21,7 +21,7 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-use crate::benoit::width_height_ratio;
+use crate::benoit::{PRECISION, width_height_ratio};
extern crate rug;
@@ -32,12 +32,16 @@ pub struct RenderData {
canvas_width: u32,
canvas_height: u32,
+ canvas_size: usize,
+
centre_real: Float,
centre_imag: Float,
zoom: Float,
max_iter_count: u32,
+ inverse: bool,
+
x_offset: f32,
y_offset: f32,
@@ -50,19 +54,23 @@ pub struct RenderData {
impl RenderData {
#[must_use]
- pub fn new(iter_count_buffer: &mut [u32], square_dist_buffer: &mut [f32], canvas_width: u32, canvas_height: u32, centre_real: Float, centre_imag: Float, zoom: Float, max_iter_count: u32) -> RenderData {
+ pub fn new(iter_count_buffer: &mut [u32], square_dist_buffer: &mut [f32], canvas_width: u32, canvas_height: u32, centre_real: Float, centre_imag: Float, zoom: Float, max_iter_count: u32, inverse: bool) -> RenderData {
let (width_ratio, height_ratio) = width_height_ratio(canvas_width, canvas_height);
return RenderData {
canvas_width: canvas_width,
canvas_height: canvas_height,
+ canvas_size: canvas_height as usize * canvas_width as usize,
+
centre_real: centre_real,
centre_imag: centre_imag,
zoom: zoom,
max_iter_count: max_iter_count,
+ inverse: inverse,
+
x_offset: canvas_width as f32 / -2.0,
y_offset: canvas_height as f32 / -2.0,
@@ -75,18 +83,32 @@ impl RenderData {
}
#[must_use]
- pub fn input(&self) -> (u32, &Float, &Float, &Float, u32) {
- return (self.canvas_width, &self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count);
+ pub fn inverse_factor(&self, a: &Float, b: &Float) -> Float {
+ return if self.inverse {
+ let mut inverse_factor = Float::with_val(PRECISION, a * a);
+ inverse_factor += b * b;
+ inverse_factor.recip_mut();
+
+ inverse_factor
+ } else {
+ Float::with_val(PRECISION, 0x1)
+ };
}
#[must_use]
- pub fn output_buffers(&self, row: u32) -> (&mut [u32], &mut [f32]) {
- assert!(row < self.canvas_height);
+ pub fn canvas_size(&self) -> (u32, u32) {
+ return (self.canvas_width, self.canvas_height);
+ }
- let offset = row as isize * self.canvas_width as isize;
+ #[must_use]
+ pub fn input(&self) -> (&Float, &Float, &Float, u32) {
+ return (&self.centre_real, &self.centre_imag, &self.zoom, self.max_iter_count);
+ }
- let iter_count = unsafe { from_raw_parts_mut(self.iter_count_buffer.offset(offset), self.canvas_width as usize) };
- let square_dist = unsafe { from_raw_parts_mut(self.square_dist_buffer.offset(offset), self.canvas_width as usize) };
+ #[must_use]
+ pub fn output_buffers(&self) -> (&mut [u32], &mut [f32]) {
+ let iter_count = unsafe { from_raw_parts_mut(self.iter_count_buffer, self.canvas_size as usize) };
+ let square_dist = unsafe { from_raw_parts_mut(self.square_dist_buffer, self.canvas_size as usize) };
return (iter_count, square_dist);
}
diff --git a/source/benoit/benoit/render/render_row.rs b/source/benoit/benoit/render/render_point.rs
index 7f9bf9a..7f9bf9a 100644
--- a/source/benoit/benoit/render/render_row.rs
+++ b/source/benoit/benoit/render/render_point.rs
diff --git a/source/benoit/benoit/render/render_point/julia.rs b/source/benoit/benoit/render/render_point/julia.rs
new file mode 100644
index 0000000..fa7329c
--- /dev/null
+++ b/source/benoit/benoit/render/render_point/julia.rs
@@ -0,0 +1,76 @@
+/*
+ Copyright 2021, 2023 Gabriel Bjørnager Jensen.
+
+ This file is part of Benoit.
+
+ Benoit is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ Benoit is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with Benoit.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::benoit::{BAILOUT, PRECISION};
+use crate::benoit::render::IteratorFunction;
+use crate::benoit::render::render_data::RenderData;
+
+extern crate rug;
+
+use rug::{Assign, Float};
+use rug::float::Special;
+
+pub fn julia(data: &RenderData, x: u32, y: u32, iterator: IteratorFunction) -> (u32, f32) {
+ // For more information, see render_point::normal.
+
+ let (centre_real, centre_imag, _zoom, max_iter_count) = data.input();
+
+ let (x_offset, y_offset, x_factor, y_factor) = data.consts();
+
+ let x_temporary = (x as f32 + x_offset) * x_factor;
+ let y_temporary = (y as f32 + y_offset) * y_factor;
+
+ let ca = centre_real;
+ let cb = centre_imag;
+
+ let mut za = Float::with_val(PRECISION, x_temporary);
+ let mut zb = Float::with_val(PRECISION, y_temporary);
+
+ let inverse_factor = data.inverse_factor(&za, &zb);
+
+ za *= &inverse_factor;
+ zb *= &inverse_factor;
+
+ let mut za_prev = Float::with_val(PRECISION, Special::Nan);
+ let mut zb_prev = Float::with_val(PRECISION, Special::Nan);
+
+ let mut iter_count: u32 = 0x1;
+ let mut square_dist = Float::with_val(PRECISION, Special::Nan);
+ while {
+ square_dist.assign(&za * &za + &zb * &zb);
+
+ let periodic = za == za_prev && zb == zb_prev;
+ if periodic { iter_count = max_iter_count }
+
+ square_dist <= BAILOUT && iter_count < max_iter_count
+ } {
+ za_prev.assign(&za);
+ zb_prev.assign(&zb);
+
+ iterator(&mut za, &mut zb, ca, cb);
+
+ iter_count += 0x1;
+ }
+
+ return (iter_count, square_dist.to_f32());
+}
diff --git a/source/benoit/benoit/render/render_point/normal.rs b/source/benoit/benoit/render/render_point/normal.rs
new file mode 100644
index 0000000..8bf88f3
--- /dev/null
+++ b/source/benoit/benoit/render/render_point/normal.rs
@@ -0,0 +1,89 @@
+/*
+ Copyright 2021, 2023 Gabriel Bjørnager Jensen.
+
+ This file is part of Benoit.
+
+ Benoit is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ Benoit is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without
+ even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with Benoit.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::benoit::{BAILOUT, PRECISION};
+use crate::benoit::render::IteratorFunction;
+use crate::benoit::render::render_data::RenderData;
+
+extern crate rug;
+
+use rug::{Assign, Float};
+use rug::float::Special;
+
+pub fn normal(data: &RenderData, x: u32, y: u32, iterator: IteratorFunction) -> (u32, f32) {
+ let (centre_real, centre_imag, zoom, max_iter_count) = data.input();
+
+ let (x_offset, y_offset, x_factor, y_factor) = data.consts();
+
+ let x_temporary = (x as f32 + x_offset) * x_factor;
+ let y_temporary = (y as f32 + y_offset) * y_factor;
+
+ let ca = {
+ let mut ca = Float::with_val(PRECISION, x_temporary / zoom);
+ ca += centre_real;
+
+ ca
+ };
+
+ let cb = {
+ let mut cb = Float::with_val(PRECISION, y_temporary / zoom);
+ cb -= centre_imag;
+
+ cb
+ };
+
+ let inverse_factor = data.inverse_factor(&ca, &cb);
+
+ let ca = ca * &inverse_factor;
+ let cb = cb * &inverse_factor;
+
+ let mut za = ca.clone();
+ let mut zb = cb.clone();
+
+ let mut za_prev = Float::with_val(PRECISION, Special::Nan);
+ let mut zb_prev = Float::with_val(PRECISION, Special::Nan);
+
+ let mut iter_count: u32 = 0x1;
+ let mut square_dist = Float::with_val(PRECISION, Special::Nan);
+ while {
+ square_dist.assign(&za * &za + &zb * &zb);
+ // Having a larger escape radius gives better
+ // results with regard to smoothing.
+
+ // Check if the value is periodic, i.e. its
+ // sequence repeats.
+ let periodic = za == za_prev && zb == zb_prev;
+ if periodic { iter_count = max_iter_count }
+
+ square_dist <= BAILOUT && iter_count < max_iter_count
+ } {
+ za_prev.assign(&za);
+ zb_prev.assign(&zb);
+
+ iterator(&mut za, &mut zb, &ca, &cb);
+
+ iter_count += 0x1;
+ }
+
+ return (iter_count, square_dist.to_f32());
+}
diff --git a/source/benoit/benoit/render/render_row/julia.rs b/source/benoit/benoit/render/render_row/julia.rs
deleted file mode 100644
index 9202a19..0000000
--- a/source/benoit/benoit/render/render_row/julia.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- Copyright 2021, 2023 Gabriel Bjørnager Jensen.
-
- This file is part of Benoit.
-
- Benoit is free software: you can redistribute it
- and/or modify it under the terms of the GNU
- Affero General Public License as published by
- the Free Software Foundation, either version 3
- of the License, or (at your option) any later
- version.
-
- Benoit is distributed in the hope that it will
- be useful, but WITHOUT ANY WARRANTY; without
- even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU
- Affero General Public License along with Benoit.
- If not, see <https://www.gnu.org/licenses/>.
-*/
-
-use crate::benoit::PRECISION;
-use crate::benoit::render::IteratorFunction;
-use crate::benoit::render::render_data::RenderData;
-
-extern crate rug;
-
-use rug::{Assign, Float};
-use rug::float::Special;
-use std::sync::Arc;
-
-pub fn julia(data: Arc<RenderData>, y: u32, iterator: IteratorFunction) {
- let (iter_count_buffer, square_dist_buffer) = data.output_buffers(y);
-
- let (canvas_width, centre_real, centre_imag, _zoom, max_iter_count) = data.input();
-
- let (x_offset, y_offset, x_factor, y_factor) = data.consts();
-
- for x in 0x0..canvas_width {
- // For more information, see render_row::normal.
-
- let x_temporary = (x as f32 + x_offset) * x_factor;
- let y_temporary = (y as f32 + y_offset) * y_factor;
-
- let ca = centre_real;
- let cb = centre_imag;
-
- // When rendering the Julia fractals, the value of
- // (c) remains constant throughout the entire
- // canvas. The value of (z) - however - takes the
- // position-determined value that (c) would've had.
-
- let mut za = Float::with_val(PRECISION, x_temporary);
- let mut zb = Float::with_val(PRECISION, y_temporary);
-
- let mut za_prev = Float::with_val(PRECISION, Special::Nan);
- let mut zb_prev = Float::with_val(PRECISION, Special::Nan);
-
- let mut iter_count: u32 = 0x1;
- let mut square_dist;
- while {
- square_dist = Float::with_val(PRECISION, &za * &za + &zb * &zb).to_f32();
-
- let periodic = za == za_prev && zb == zb_prev;
- if periodic { iter_count = max_iter_count }
-
- square_dist <= 256.0 && iter_count < max_iter_count
- } {
- za_prev.assign(&za);
- zb_prev.assign(&zb);
-
- iterator(&mut za, &mut zb, ca, cb);
-
- iter_count += 0x1;
- }
-
- unsafe {
- *iter_count_buffer.get_unchecked_mut( x as usize) = iter_count;
- *square_dist_buffer.get_unchecked_mut(x as usize) = square_dist;
- }
- }
-}
diff --git a/source/benoit/benoit/render/render_row/normal.rs b/source/benoit/benoit/render/render_row/normal.rs
deleted file mode 100644
index 6e310d7..0000000
--- a/source/benoit/benoit/render/render_row/normal.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- Copyright 2021, 2023 Gabriel Bjørnager Jensen.
-
- This file is part of Benoit.
-
- Benoit is free software: you can redistribute it
- and/or modify it under the terms of the GNU
- Affero General Public License as published by
- the Free Software Foundation, either version 3
- of the License, or (at your option) any later
- version.
-
- Benoit is distributed in the hope that it will
- be useful, but WITHOUT ANY WARRANTY; without
- even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU
- Affero General Public License along with Benoit.
- If not, see <https://www.gnu.org/licenses/>.
-*/
-
-use crate::benoit::PRECISION;
-use crate::benoit::render::IteratorFunction;
-use crate::benoit::render::render_data::RenderData;
-
-extern crate rug;
-
-use rug::{Assign, Float};
-use rug::float::Special;
-use std::sync::Arc;
-
-pub fn normal(data: Arc<RenderData>, y: u32, iterator: IteratorFunction) {
- let (iter_count_buffer, square_dist_buffer) = data.output_buffers(y);
-
- let (canvas_width, centre_real, centre_imag, zoom, max_iter_count) = data.input();
-
- let (x_offset, y_offset, x_factor, y_factor) = data.consts();
-
- for x in 0x0..canvas_width {
- let x_temporary = (x as f32 + x_offset) * x_factor;
- let y_temporary = (y as f32 + y_offset) * y_factor;
-
- let ca = {
- let mut ca = Float::with_val(PRECISION, x_temporary / zoom);
- ca += centre_real;
-
- ca
- };
-
- let cb = {
- let mut cb = Float::with_val(PRECISION, y_temporary / zoom);
- cb -= centre_imag;
-
- cb
- };
-
- let mut za = ca.clone();
- let mut zb = cb.clone();
-
- let mut za_prev = Float::with_val(PRECISION, Special::Nan);
- let mut zb_prev = Float::with_val(PRECISION, Special::Nan);
-
- let mut iter_count: u32 = 0x1;
- let mut square_dist;
- while {
- square_dist = Float::with_val(PRECISION, &za * &za + &zb * &zb).to_f32();
- // Having a larger escape radius gives better
- // results with regard to smoothing.
-
- // Check if the value is periodic, i.e. its
- // sequence repeats.
- let periodic = za == za_prev && zb == zb_prev;
- if periodic { iter_count = max_iter_count }
-
- square_dist <= 256.0 && iter_count < max_iter_count
- } {
- za_prev.assign(&za);
- zb_prev.assign(&zb);
-
- iterator(&mut za, &mut zb, &ca, &cb);
-
- iter_count += 0x1;
- }
-
- // Sacrifice safety for speed by removing bounds-
- // checking.
- unsafe {
- *iter_count_buffer.get_unchecked_mut( x as usize) = iter_count;
- *square_dist_buffer.get_unchecked_mut(x as usize) = square_dist;
- }
- }
-}
diff --git a/source/benoit/benoit/rendering.rs b/source/benoit/benoit/rendering.rs
index 125798f..923c01f 100644
--- a/source/benoit/benoit/rendering.rs
+++ b/source/benoit/benoit/rendering.rs
@@ -21,8 +21,8 @@
If not, see <https://www.gnu.org/licenses/>.
*/
-use crate::benoit::render::RowRenderer;
-use crate::benoit::render::render_row;
+use crate::benoit::render::PointRenderer;
+use crate::benoit::render::render_point;
use std::mem::transmute;
@@ -33,10 +33,10 @@ pub enum Rendering {
}
impl Rendering {
- pub fn get_row_renderer(self) -> RowRenderer {
+ pub fn get_point_renderer(self) -> PointRenderer {
return match self {
- Rendering::Julia => render_row::julia,
- Rendering::Normal => render_row::normal,
+ Rendering::Julia => render_point::julia,
+ Rendering::Normal => render_point::normal,
};
}
diff --git a/source/benoit/benoit/video/initialise.rs b/source/benoit/benoit/video/initialise.rs
index dcd92f7..8719b4e 100644
--- a/source/benoit/benoit/video/initialise.rs
+++ b/source/benoit/benoit/video/initialise.rs
@@ -34,7 +34,7 @@ impl Video {
let sdl = sdl2::init().expect("unable to initialise sdl2");
let sdl_video = sdl.video().expect("unable to initialise video");
- let window_title = format!("BENO\u{CE}T {:X}.{:X}.{:X}", VERSION.major, VERSION.minor, VERSION.patch);
+ let window_title = format!("BENO\u{CE}T {:X}.{:X}.{:X}", VERSION[0x0], VERSION[0x1], VERSION[0x2]);
let mut window_builder = sdl_video.window(window_title.as_str(), canvas_width * scale, canvas_height * scale);
window_builder.borderless();
diff --git a/source/benoit/benoit/width_height_ratio.rs b/source/benoit/benoit/width_height_ratio.rs
deleted file mode 100644
index c4afe91..0000000
--- a/source/benoit/benoit/width_height_ratio.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright 2021, 2023 Gabriel Bjørnager Jensen.
-
- This file is part of Benoit.
-
- Benoit is free software: you can redistribute it
- and/or modify it under the terms of the GNU
- Affero General Public License as published by
- the Free Software Foundation, either version 3
- of the License, or (at your option) any later
- version.
-
- Benoit is distributed in the hope that it will
- be useful, but WITHOUT ANY WARRANTY; without
- even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU
- Affero General Public License along with Benoit.
- If not, see <https://www.gnu.org/licenses/>.
-*/
-
-pub fn width_height_ratio(width: u32, height: u32) -> (f32, f32) {
- return if width > height {
- (1.0, height as f32 / width as f32)
- } else {
- (width as f32 / height as f32, 1.0)
- };
-}