mirror of
https://github.com/csd4ni3l/fractal-viewer.git
synced 2026-01-01 04:13:41 +01:00
Add julia N, slider steps
This commit is contained in:
@@ -37,7 +37,7 @@ class JuliaViewer(arcade.gui.UIView):
|
|||||||
def on_show_view(self):
|
def on_show_view(self):
|
||||||
super().on_show_view()
|
super().on_show_view()
|
||||||
|
|
||||||
self.shader_program, self.julia_image = create_julia_shader(self.window.width, self.window.height, self.settings_dict.get("julia_precision", "Single").lower(), self.settings_dict.get("julia_escape_radius", 2), self.settings_dict.get("julia_type", "Classic swirling"))
|
self.shader_program, self.julia_image = create_julia_shader(self.window.width, self.window.height, self.settings_dict.get("julia_precision", "Single").lower(), self.settings_dict.get("julia_escape_radius", 2), self.settings_dict.get("julia_type", "Classic swirling"), int(self.settings_dict.get("julia_n", 2)))
|
||||||
|
|
||||||
self.julia_sprite = pyglet.sprite.Sprite(img=self.julia_image)
|
self.julia_sprite = pyglet.sprite.Sprite(img=self.julia_image)
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class JuliaViewer(arcade.gui.UIView):
|
|||||||
|
|
||||||
def create_image(self):
|
def create_image(self):
|
||||||
with self.shader_program:
|
with self.shader_program:
|
||||||
self.shader_program['u_maxIter'] = self.max_iter
|
self.shader_program['u_maxIter'] = int(self.max_iter)
|
||||||
self.shader_program['u_resolution'] = (self.window.width, self.window.height)
|
self.shader_program['u_resolution'] = (self.window.width, self.window.height)
|
||||||
self.shader_program['u_real_range'] = (self.real_min, self.real_max)
|
self.shader_program['u_real_range'] = (self.real_min, self.real_max)
|
||||||
self.shader_program['u_imag_range'] = (self.imag_min, self.imag_max)
|
self.shader_program['u_imag_range'] = (self.imag_min, self.imag_max)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class MandelbrotViewer(arcade.gui.UIView):
|
|||||||
|
|
||||||
def create_image(self):
|
def create_image(self):
|
||||||
with self.shader_program:
|
with self.shader_program:
|
||||||
self.shader_program['u_maxIter'] = self.max_iter
|
self.shader_program['u_maxIter'] = int(self.max_iter)
|
||||||
self.shader_program['u_resolution'] = (self.window.width, self.window.height)
|
self.shader_program['u_resolution'] = (self.window.width, self.window.height)
|
||||||
self.shader_program['u_real_range'] = (self.real_min, self.real_max)
|
self.shader_program['u_real_range'] = (self.real_min, self.real_max)
|
||||||
self.shader_program['u_imag_range'] = (self.imag_min, self.imag_max)
|
self.shader_program['u_imag_range'] = (self.imag_min, self.imag_max)
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ void main() {
|
|||||||
|
|
||||||
if (iters != u_maxIter) {
|
if (iters != u_maxIter) {
|
||||||
float t = float(iters) / float(u_maxIter);
|
float t = float(iters) / float(u_maxIter);
|
||||||
float pow_amount = 0.7;
|
|
||||||
t = pow(t, pow_amount);
|
|
||||||
|
|
||||||
value.r = 9.0 * (1.0 - t) * t * t * t;
|
value.r = 9.0 * (1.0 - t) * t * t * t;
|
||||||
value.g = 15.0 * (1.0 - t) * (1.0 - t) * t * t;
|
value.g = 15.0 * (1.0 - t) * (1.0 - t) * t * t;
|
||||||
@@ -102,7 +100,8 @@ layout(location = 0, rgba32f) uniform image2D img_output;
|
|||||||
void main() {
|
void main() {
|
||||||
ivec2 texel_coord = ivec2(gl_GlobalInvocationID.xy);
|
ivec2 texel_coord = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
int R = {escape_radius};
|
float R = {escape_radius};
|
||||||
|
int n = {julia_n};
|
||||||
{vec2type} c = {vec2type}{julia_c};
|
{vec2type} c = {vec2type}{julia_c};
|
||||||
|
|
||||||
{vec2type} z = map_pixel({floattype}(texel_coord.x), {floattype}(texel_coord.y), u_resolution, u_real_range, u_imag_range);
|
{vec2type} z = map_pixel({floattype}(texel_coord.x), {floattype}(texel_coord.y), u_resolution, u_real_range, u_imag_range);
|
||||||
@@ -110,9 +109,9 @@ void main() {
|
|||||||
int iters = 0;
|
int iters = 0;
|
||||||
|
|
||||||
while ((z.x * z.x + z.y * z.y) < pow(R, 2) && iters < u_maxIter) {
|
while ((z.x * z.x + z.y * z.y) < pow(R, 2) && iters < u_maxIter) {
|
||||||
{floattype} xtemp = z.x * z.x - z.y * z.y;
|
{floattype} xtmp = pow((z.x * z.x + z.y * z.y), (n / 2)) * cos(n * atan(z.y, z.x)) + c.x;
|
||||||
z.y = 2 * z.x * z.y + c.y;
|
z.y = pow((z.x * z.x + z.y * z.y), (n / 2)) * sin(n * atan(z.y, z.x)) + c.y;
|
||||||
z.x = xtemp + c.x;
|
z.x = xtmp;
|
||||||
|
|
||||||
iters = iters + 1;
|
iters = iters + 1;
|
||||||
}
|
}
|
||||||
@@ -121,8 +120,6 @@ void main() {
|
|||||||
|
|
||||||
if (iters != u_maxIter) {
|
if (iters != u_maxIter) {
|
||||||
float t = float(iters) / float(u_maxIter);
|
float t = float(iters) / float(u_maxIter);
|
||||||
float pow_amount = 0.7;
|
|
||||||
t = pow(t, pow_amount);
|
|
||||||
|
|
||||||
value.r = 9.0 * (1.0 - t) * t * t * t;
|
value.r = 9.0 * (1.0 - t) * t * t * t;
|
||||||
value.g = 15.0 * (1.0 - t) * (1.0 - t) * t * t;
|
value.g = 15.0 * (1.0 - t) * (1.0 - t) * t * t;
|
||||||
@@ -152,7 +149,7 @@ def create_sierpinsky_carpet_shader(width, height, precision="single"):
|
|||||||
|
|
||||||
return shader_program, sierpinsky_carpet_image
|
return shader_program, sierpinsky_carpet_image
|
||||||
|
|
||||||
def create_julia_shader(width, height, precision="single", escape_radius=2, julia_type="Classic swirling"):
|
def create_julia_shader(width, height, precision="single", escape_radius=2, julia_type="Classic swirling", julia_n=2):
|
||||||
shader_source = julia_compute_source
|
shader_source = julia_compute_source
|
||||||
|
|
||||||
if precision == "single":
|
if precision == "single":
|
||||||
@@ -166,6 +163,7 @@ def create_julia_shader(width, height, precision="single", escape_radius=2, juli
|
|||||||
shader_source = shader_source.replace("{julia_c}", str(julia_c))
|
shader_source = shader_source.replace("{julia_c}", str(julia_c))
|
||||||
|
|
||||||
shader_source = shader_source.replace("{escape_radius}", str(escape_radius))
|
shader_source = shader_source.replace("{escape_radius}", str(escape_radius))
|
||||||
|
shader_source = shader_source.replace("{julia_n}", str(julia_n))
|
||||||
|
|
||||||
shader_program = pyglet.graphics.shader.ComputeShaderProgram(shader_source)
|
shader_program = pyglet.graphics.shader.ComputeShaderProgram(shader_source)
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class SierpinskyCarpetViewer(arcade.gui.UIView):
|
|||||||
|
|
||||||
def create_image(self):
|
def create_image(self):
|
||||||
with self.shader_program:
|
with self.shader_program:
|
||||||
self.shader_program['u_depth'] = self.depth
|
self.shader_program['u_depth'] = int(self.depth)
|
||||||
self.shader_program['u_zoom'] = int(self.zoom)
|
self.shader_program['u_zoom'] = int(self.zoom)
|
||||||
self.shader_program['u_center'] = self.click_center
|
self.shader_program['u_center'] = self.click_center
|
||||||
self.shader_program.dispatch(self.sierpinsky_carpet_image.width, self.sierpinsky_carpet_image.height, 1, barrier=pyglet.gl.GL_ALL_BARRIER_BITS)
|
self.shader_program.dispatch(self.sierpinsky_carpet_image.width, self.sierpinsky_carpet_image.height, 1, barrier=pyglet.gl.GL_ALL_BARRIER_BITS)
|
||||||
|
|||||||
@@ -119,20 +119,21 @@ class Settings(arcade.gui.UIView):
|
|||||||
else:
|
else:
|
||||||
label_text = f"FPS Limit: {self.settings_dict.get(setting_dict['config_key'], setting_dict['default'])}"
|
label_text = f"FPS Limit: {self.settings_dict.get(setting_dict['config_key'], setting_dict['default'])}"
|
||||||
else:
|
else:
|
||||||
label_text = f"{setting}: {int(self.settings_dict.get(setting_dict['config_key'], setting_dict['default']))}"
|
label_text = f"{setting}: {self.settings_dict.get(setting_dict['config_key'], setting_dict['default'])}"
|
||||||
|
|
||||||
label.text = label_text
|
label.text = label_text
|
||||||
|
|
||||||
self.slider_labels[setting] = label
|
self.slider_labels[setting] = label
|
||||||
|
|
||||||
slider = arcade.gui.UISlider(width=400, height=50, value=self.settings_dict.get(setting_dict["config_key"], setting_dict["default"]), min_value=setting_dict['min'], max_value=setting_dict['max'], style=slider_style)
|
slider = arcade.gui.UISlider(width=400, height=50, value=self.settings_dict.get(setting_dict["config_key"], setting_dict["default"]), min_value=setting_dict['min'], max_value=setting_dict['max'], step=setting_dict.get("step", 1), style=slider_style)
|
||||||
slider.on_change = lambda _, setting=setting, slider=slider: self.update(setting, slider.value, "slider")
|
slider._render_steps = lambda surface: None
|
||||||
|
slider.on_change = lambda event, setting=setting, slider=slider: self.update(setting, slider.value, "slider")
|
||||||
|
|
||||||
self.sliders[setting] = slider
|
self.sliders[setting] = slider
|
||||||
self.value_layout.add(slider)
|
self.value_layout.add(slider)
|
||||||
|
|
||||||
self.apply_button = arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Apply', style=button_style, width=200, height=100)
|
self.apply_button = arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='Apply', style=button_style, width=200, height=100)
|
||||||
self.apply_button.on_click = lambda e: self.apply_settings()
|
self.apply_button.on_click = lambda event: self.apply_settings()
|
||||||
self.anchor.add(self.apply_button, anchor_x="right", anchor_y="bottom", align_x=-10, align_y=10)
|
self.anchor.add(self.apply_button, anchor_x="right", anchor_y="bottom", align_x=-10, align_y=10)
|
||||||
|
|
||||||
def apply_settings(self):
|
def apply_settings(self):
|
||||||
@@ -221,18 +222,16 @@ class Settings(arcade.gui.UIView):
|
|||||||
self.set_normal_style(self.on_radiobuttons[setting])
|
self.set_normal_style(self.on_radiobuttons[setting])
|
||||||
|
|
||||||
elif setting_type == "slider":
|
elif setting_type == "slider":
|
||||||
new_value = int(button_state)
|
self.modified_settings[config_key] = button_state
|
||||||
|
self.sliders[setting].value = button_state
|
||||||
self.modified_settings[config_key] = new_value
|
|
||||||
self.sliders[setting].value = new_value
|
|
||||||
|
|
||||||
if setting == "FPS Limit":
|
if setting == "FPS Limit":
|
||||||
if new_value == 0:
|
if button_state == 0:
|
||||||
label_text = "FPS Limit: Disabled"
|
label_text = "FPS Limit: Disabled"
|
||||||
else:
|
else:
|
||||||
label_text = f"FPS Limit: {str(new_value).rjust(8)}"
|
label_text = f"FPS Limit: {str(button_state).rjust(8)}"
|
||||||
else:
|
else:
|
||||||
label_text = f"{setting}: {str(new_value).rjust(8)}"
|
label_text = f"{setting}: {str(button_state).rjust(8)}"
|
||||||
|
|
||||||
self.slider_labels[setting].text = label_text
|
self.slider_labels[setting].text = label_text
|
||||||
|
|
||||||
|
|||||||
@@ -36,26 +36,27 @@ settings = {
|
|||||||
"Mandelbrot": {
|
"Mandelbrot": {
|
||||||
"Float Precision": {"type": "option", "options": ["Single", "Double"], "config_key": "mandelbrot_precision", "default": "Single"},
|
"Float Precision": {"type": "option", "options": ["Single", "Double"], "config_key": "mandelbrot_precision", "default": "Single"},
|
||||||
"Zoom Increase Per Click": {"type": "slider", "min": 2, "max": 100, "config_key": "mandelbrot_zoom_increase", "default": 2},
|
"Zoom Increase Per Click": {"type": "slider", "min": 2, "max": 100, "config_key": "mandelbrot_zoom_increase", "default": 2},
|
||||||
"Max Iterations": {"type": "slider", "min": 100, "max": 10000, "config_key": "mandelbrot_max_iter", "default": 200}
|
"Max Iterations": {"type": "slider", "min": 100, "max": 10000, "config_key": "mandelbrot_max_iter", "default": 200, "step": 100}
|
||||||
},
|
},
|
||||||
"Sierpinsky Carpet": {
|
"Sierpinsky Carpet": {
|
||||||
"Float Precision": {"type": "option", "options": ["Single", "Double"], "config_key": "sierpinsky_precision", "default": "Single"},
|
"Float Precision": {"type": "option", "options": ["Single", "Double"], "config_key": "sierpinsky_precision", "default": "Single"},
|
||||||
"Zoom Increase Per Click": {"type": "slider", "min": 2, "max": 100, "config_key": "sierpinsky_zoom_increase", "default": 2},
|
"Zoom Increase Per Click": {"type": "slider", "min": 2, "max": 100, "config_key": "sierpinsky_zoom_increase", "default": 2},
|
||||||
"Depth": {"type": "slider", "min": 2, "max": 10000, "config_key": "sierpinsky_depth", "default": 10}
|
"Depth": {"type": "slider", "min": 100, "max": 10000, "config_key": "sierpinsky_depth", "default": 100, "step": 100}
|
||||||
},
|
},
|
||||||
"Julia": {
|
"Julia": {
|
||||||
"Type": {"type": "option", "options": ["Classic swirling", "Douady rabbit", "Nebula-style", "Snowflake"], "config_key": "julia_type", "default": "Classic swirling"},
|
"Type": {"type": "option", "options": ["Classic swirling", "Douady rabbit", "Nebula-style", "Snowflake"], "config_key": "julia_type", "default": "Classic swirling"},
|
||||||
"Float Precision": {"type": "option", "options": ["Single", "Double"], "config_key": "julia_precision", "default": "Single"},
|
"Float Precision": {"type": "option", "options": ["Single", "Double"], "config_key": "julia_precision", "default": "Single"},
|
||||||
"Escape Radius": {"type": "slider", "min": 1, "max": 10, "config_key": "julia_escape_radius", "default": 2},
|
"N": {"type": "slider", "min": 1, "max": 10, "config_key": "julia_n", "default": 2, "step": 1},
|
||||||
|
"Escape Radius": {"type": "slider", "min": 1, "max": 10, "config_key": "julia_escape_radius", "default": 2, "step": 0.1},
|
||||||
"Zoom Increase Per Click": {"type": "slider", "min": 2, "max": 100, "config_key": "julia_zoom_increase", "default": 2},
|
"Zoom Increase Per Click": {"type": "slider", "min": 2, "max": 100, "config_key": "julia_zoom_increase", "default": 2},
|
||||||
"Max Iterations": {"type": "slider", "min": 100, "max": 10000, "config_key": "julia_max_iter", "default": 200}
|
"Max Iterations": {"type": "slider", "min": 100, "max": 10000, "config_key": "julia_max_iter", "default": 200, "step": 100}
|
||||||
},
|
},
|
||||||
"Graphics": {
|
"Graphics": {
|
||||||
"Window Mode": {"type": "option", "options": ["Windowed", "Fullscreen", "Borderless"], "config_key": "window_mode", "default": "Windowed"},
|
"Window Mode": {"type": "option", "options": ["Windowed", "Fullscreen", "Borderless"], "config_key": "window_mode", "default": "Windowed"},
|
||||||
"Resolution": {"type": "option", "options": ["1366x768", "1440x900", "1600x900", "1920x1080", "2560x1440", "3840x2160"], "config_key": "resolution"},
|
"Resolution": {"type": "option", "options": ["1366x768", "1440x900", "1600x900", "1920x1080", "2560x1440", "3840x2160"], "config_key": "resolution"},
|
||||||
"Anti-Aliasing": {"type": "option", "options": ["None", "2x MSAA", "4x MSAA", "8x MSAA", "16x MSAA"], "config_key": "anti_aliasing", "default": "4x MSAA"},
|
"Anti-Aliasing": {"type": "option", "options": ["None", "2x MSAA", "4x MSAA", "8x MSAA", "16x MSAA"], "config_key": "anti_aliasing", "default": "4x MSAA"},
|
||||||
"VSync": {"type": "bool", "config_key": "vsync", "default": True},
|
"VSync": {"type": "bool", "config_key": "vsync", "default": True},
|
||||||
"FPS Limit": {"type": "slider", "min": 0, "max": 480, "config_key": "fps_limit", "default": 60},
|
"FPS Limit": {"type": "slider", "min": 0, "max": 480, "config_key": "fps_limit", "default": 60, "step": 10},
|
||||||
},
|
},
|
||||||
"Miscellaneous": {
|
"Miscellaneous": {
|
||||||
"Discord RPC": {"type": "bool", "config_key": "discord_rpc", "default": True},
|
"Discord RPC": {"type": "bool", "config_key": "discord_rpc", "default": True},
|
||||||
|
|||||||
Reference in New Issue
Block a user