From: Lukas Jiriste Date: Wed, 17 Jan 2024 14:02:12 +0000 (+0100) Subject: Change the code without much to show for it X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=6d4f6c21a27e7200598894ec417338984f81f004;p=42%2Ffract-ol.git Change the code without much to show for it Change the code so that adding partial picture construction is easier in the future. Changes also support drawing in worse resolution. Needs refactoring of main.c and possible checking the header files. --- diff --git a/Libft b/Libft index 988bd41..00bb2e3 160000 --- a/Libft +++ b/Libft @@ -1 +1 @@ -Subproject commit 988bd412d9b3d0681457c4c169d398c273d0c6ff +Subproject commit 00bb2e3124c52f1269675bb28175de780ffe9c6e diff --git a/color.c b/color.c index c7651e6..0081000 100644 --- a/color.c +++ b/color.c @@ -6,12 +6,12 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/11 18:50:32 by ljiriste #+# #+# */ -/* Updated: 2023/11/11 18:51:07 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 12:19:22 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ -#include #include "color.h" +#include t_color to_color(unsigned int num) { diff --git a/color.h b/color.h index b4f5f16..cf2fa4d 100644 --- a/color.h +++ b/color.h @@ -6,13 +6,15 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/11 18:51:23 by ljiriste #+# #+# */ -/* Updated: 2023/11/11 18:51:25 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 12:20:02 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef COLOR_H # define COLOR_H +# include + struct s_color { unsigned char a; diff --git a/event_handling.c b/event_handling.c index f6d6c39..b122286 100644 --- a/event_handling.c +++ b/event_handling.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/05 19:35:01 by ljiriste #+# #+# */ -/* Updated: 2024/01/17 10:31:31 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 14:42:38 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,17 +25,17 @@ int handle_key_press(int keycode, t_session *s) if (keycode == XK_Escape) close_win(s); else if (keycode == XK_Up || keycode == XK_w) - move_view(0, MOVE_AMOUNT, s); + move_view(s, 0, MOVE_AMOUNT); else if (keycode == XK_Left || keycode == XK_a) - move_view(-MOVE_AMOUNT, 0, s); + move_view(s, -MOVE_AMOUNT, 0); else if (keycode == XK_Down || keycode == XK_s) - move_view(0, -MOVE_AMOUNT, s); + move_view(s, 0, -MOVE_AMOUNT); else if (keycode == XK_Right || keycode == XK_d) - move_view(MOVE_AMOUNT, 0, s); + move_view(s, MOVE_AMOUNT, 0); else if (keycode == XK_KP_Add) - change_zoom(&s->view, (t_vect2){.x = s->img.width / 2, .y = s->img.height / 2}, ZOOM_IN); + change_zoom(s, (t_vect2){.x = s->img.width / 2, .y = s->img.height / 2}, ZOOM_IN); else if (keycode == XK_KP_Subtract) - change_zoom(&s->view, (t_vect2){.x = s->img.width / 2, .y = s->img.height / 2}, ZOOM_OUT); + change_zoom(s, (t_vect2){.x = s->img.width / 2, .y = s->img.height / 2}, ZOOM_OUT); if (keycode != XK_Escape) draw_fractal(s); return (0); @@ -44,9 +44,9 @@ int handle_key_press(int keycode, t_session *s) int handle_mouse_press(int button, int x, int y, t_session *s) { if (button == Button4) - change_zoom(&s->view, (t_vect2){.x = x, .y = y}, ZOOM_OUT); + change_zoom(s, (t_vect2){.x = x, .y = y}, ZOOM_OUT); else if (button == Button5) - change_zoom(&s->view, (t_vect2){.x = x, .y = y}, ZOOM_IN); + change_zoom(s, (t_vect2){.x = x, .y = y}, ZOOM_IN); if (button == Button4 || button == Button5) draw_fractal(s); return (0); @@ -60,10 +60,9 @@ int handle_mouse_press(int button, int x, int y, t_session *s) */ int no_event_handle(t_session *s) { - if (s->view.resolution < 1) + if (s->img.undersample > 1) { - s->view.draw_whole = 0; - s->view.resolution *= 2; + --s->img.undersample; draw_fractal(s); } return (0); diff --git a/fractol.h b/fractol.h index 7524676..b677812 100644 --- a/fractol.h +++ b/fractol.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/11 18:51:29 by ljiriste #+# #+# */ -/* Updated: 2024/01/16 14:01:51 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 14:43:55 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,6 +26,8 @@ struct s_img int endian; int width; int height; + t_mat calced; + int undersample; }; typedef struct s_img t_img; @@ -35,8 +37,6 @@ struct s_view t_color (*palette)(double); t_vect2 window_coord; t_vect2 pixel_size; - double resolution; - int draw_whole; }; typedef struct s_view t_view; @@ -52,9 +52,10 @@ typedef struct s_session t_session; int handle_key_press(int keycode, t_session *s); int handle_mouse_press(int button, int x, int y, t_session *s); int no_event_handle(t_session *s); -int draw_fractal(t_session *s); -void change_zoom(t_view *view, t_vect2 invariant, double d_zoom); -void move_view(float move_amount_right, float move_amount_up, t_session *s); +void process_pixel_group(t_session *s, int x, int y); +void draw_fractal(t_session *s); +void change_zoom(t_session *s, t_vect2 invariant, double d_zoom); +void move_view(t_session *s, float move_amount_right, float move_amount_up); int close_win(t_session *s); #endif diff --git a/main.c b/main.c index f397d53..26df455 100644 --- a/main.c +++ b/main.c @@ -6,21 +6,22 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/27 14:29:26 by ljiriste #+# #+# */ -/* Updated: 2024/01/17 10:29:34 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 14:49:49 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include "libft.h" -#include "fractol.h" #include "complex.h" #include "color.h" #include "vect2.h" +#include "fractol.h" +#include "libft.h" +#include +#include +#include +#include +#include +#include +#include int close_win(t_session *s) { @@ -28,11 +29,16 @@ int close_win(t_session *s) return (0); } +void *get_pixel(t_img *img, int x, int y) +{ + return (img->addr + y * img->bpl + x * img->bpp / CHAR_BIT); +} + void ft_putpx_img(t_img *img, int x, int y, t_color c) { char *px_addr; - px_addr = img->addr + y * img->bpl + x * img->bpp / CHAR_BIT; + px_addr = get_pixel(img, x, y); if (img->endian) { px_addr[0] = c.a; @@ -50,15 +56,6 @@ void ft_putpx_img(t_img *img, int x, int y, t_color c) return ; } -int is_black(t_img *img, int x, int y) -{ - char *px_addr; - - px_addr = img->addr + y * img->bpl + x * img->bpp / CHAR_BIT; - return (!(px_addr[0] || px_addr[1] || px_addr[2] || px_addr[3])); -} - - void free_session(t_session *s) { mlx_destroy_display(s->mlx); @@ -66,10 +63,10 @@ void free_session(t_session *s) return ; } -double mandelbrot(double x, double y, double resolution) +double mandelbrot(double x, double y) { const double threshold = 1000; - const double log2 = log(2); + const double detail = 10; int count; t_complex c; t_complex z; @@ -81,21 +78,83 @@ double mandelbrot(double x, double y, double resolution) z.i = 0; if (complex_norm(c) > 4) return (0.01); - while (complex_norm(z) < threshold && count < 100 * resolution) + while (complex_norm(z) < threshold && count < 100 * detail) { z = complex_add(complex_mul(z, z), c); ++count; } - if (count == 100 * resolution) + if (count == 100 * detail) return (-1); - return (fmod((count + 1 - log(log(complex_norm(z)) / log2) / log2) / 100., 1.)); + return (fmod((count + 1 - log(log(complex_norm(z)) / log(2)) / log(2)) / 100., 1.)); +} + +t_color get_img_pixel_color(t_img *img, int x, int y) +{ + char *px_addr; + t_color c; + + px_addr = get_pixel(img, x, y); + if (img->endian) + { + c.a = px_addr[0]; + c.r = px_addr[1]; + c.g = px_addr[2]; + c.b = px_addr[3]; + } + else + { + c.a = px_addr[3]; + c.r = px_addr[2]; + c.g = px_addr[1]; + c.b = px_addr[0]; + } + return (c); } -int draw_fractal(t_session *s) +t_color get_color(t_session *s, int x, int y) +{ + double palette_param; + + if (!*(bool *)ft_mat_access(&s->img.calced, x, y)) + { + palette_param = s->view.fractal( + s->view.window_coord.x + s->view.pixel_size.x * x, + s->view.window_coord.y - s->view.pixel_size.y * y); + return (s->view.palette(palette_param)); + } + else + { + return (get_img_pixel_color(&s->img, x, y)); + } +} + +void process_pixel_group(t_session *s, int x, int y) +{ + int i; + int j; + t_color color; + + color = get_color(s, x, y); + i = 0; + while (i < s->img.undersample && x + i < s->img.width) + { + j = 0; + while (j < s->img.undersample && y + j < s->img.height) + { + if (!*(bool *)ft_mat_access(&s->img.calced, x + i, y + j)) + ft_putpx_img(&s->img, x + i, y + j, color); + ++j; + } + ++i; + } + *(bool *)ft_mat_access(&s->img.calced, x, y) = 1; + return ; +} + +void draw_fractal(t_session *s) { int x; int y; - double palette_param; x = 0; while (x < s->img.width) @@ -103,45 +162,77 @@ int draw_fractal(t_session *s) y = 0; while (y < s->img.height) { - if(!is_black(&s->img, x, y) && !s->view.draw_whole) - { - ++y; - continue ; - } - palette_param = s->view.fractal( - s->view.window_coord.x + s->view.pixel_size.x * x, - s->view.window_coord.y - s->view.pixel_size.y * y, - s->view.resolution); - ft_putpx_img(&s->img, x, y, s->view.palette(palette_param)); - ++y; + process_pixel_group(s, x, y); + y += s->img.undersample; } - ++x; + x += s->img.undersample; } mlx_put_image_to_window(s->mlx, s->win, s->img.img, 0, 0); - return (0); } -void change_zoom(t_view *view, t_vect2 invariant, double d_zoom) +void erase_calced(t_mat *mat) { - view->pixel_size.x /= d_zoom; - view->pixel_size.y /= d_zoom; - view->window_coord.x += view->pixel_size.x * invariant.x * (d_zoom - 1); - view->window_coord.y -= view->pixel_size.y * invariant.y * (d_zoom - 1); - //view->resolution = 1; - view->draw_whole = 1; + size_t i; + size_t j; + + i = 0; + while (i < mat->rows) + { + j = 0; + while (j < mat->cols) + { + *(bool *)ft_mat_access(mat, i, j) = false; + ++j; + } + ++i; + } + return ; +} + +void change_zoom(t_session *s, t_vect2 invariant, double d_zoom) +{ + s->view.pixel_size.x /= d_zoom; + s->view.pixel_size.y /= d_zoom; + s->view.window_coord.x += s->view.pixel_size.x * invariant.x * (d_zoom - 1); + s->view.window_coord.y -= s->view.pixel_size.y * invariant.y * (d_zoom - 1); + erase_calced(&s->img.calced); + s->img.undersample = 2; return ; } // move_amount is ratio of move distance to length one can see -void move_view(float move_amount_right, float move_amount_up, t_session *s) +void move_view(t_session *s, float move_amount_right, float move_amount_up) { s->view.window_coord.x += move_amount_right * s->img.height * s->view.pixel_size.x; s->view.window_coord.y += move_amount_up * s->img.height * s->view.pixel_size.y; - s->view.draw_whole = 1; + erase_calced(&s->img.calced); + s->img.undersample = 2; return ; } -void init_view(t_session *s) +// Something like this function should be added to Libft +// with maybe additional argument (void *) of the filler +t_arr_stat construct_mat(t_mat *mat, size_t rows, size_t cols) +{ + t_vec filler_vec; + bool filler; + size_t i; + t_arr_stat res; + + filler = false; + ft_vec_init(&filler_vec, sizeof(bool)); + i = 0; + while (i < cols) + { + ft_vec_append(&filler_vec, &filler); + ++i; + } + res = ft_mat_insert_row(mat, &filler_vec, rows - 1); + ft_vec_free(&filler_vec, NULL); + return (res); +} + +static void init_view(t_session *s) { s->view.fractal = mandelbrot; s->view.palette = tri_color; @@ -149,37 +240,49 @@ void init_view(t_session *s) s->view.pixel_size.y = 0.01; s->view.window_coord.x = -s->img.width / 2 * s->view.pixel_size.x; s->view.window_coord.y = s->img.height / 2 * s->view.pixel_size.y; - s->view.resolution = 10; - s->view.draw_whole = 1; return ; } +void init_session(t_session *s) +{ + s->mlx = mlx_init(); + s->win = mlx_new_window(s->mlx, s->img.width, s->img.height, "Fract-ol"); + s->img.img = mlx_new_image(s->mlx, s->img.width, s->img.height); + s->img.addr = mlx_get_data_addr(s->img.img, &s->img.bpp, &s->img.bpl, &s->img.endian); + ft_mat_init(&s->img.calced, sizeof(bool)); + construct_mat(&s->img.calced, s->img.height, s->img.width); + init_view(s); + s->img.undersample = 2; +} + void parse_args(int argc, char **argv, t_session *s) { if (argc == 0) free(argv); s->img.width = 500; s->img.height = 500; - init_view(s); return ; } +void cleanup(t_session *s) +{ + ft_mat_free(&s->img.calced, NULL); + mlx_destroy_image(s->mlx, s->img.img); + free_session(s); +} + int main(int argc, char **argv) { t_session s; parse_args(argc, argv, &s); - s.mlx = mlx_init(); - s.win = mlx_new_window(s.mlx, s.img.width, s.img.height, "Fract-ol"); - s.img.img = mlx_new_image(s.mlx, s.img.width, s.img.height); - s.img.addr = mlx_get_data_addr(s.img.img, &s.img.bpp, &s.img.bpl, &s.img.endian); + init_session(&s); mlx_hook(s.win, KeyPress, KeyPressMask, handle_key_press, &s); mlx_hook(s.win, ButtonPress, ButtonPressMask, handle_mouse_press, &s); mlx_hook(s.win, DestroyNotify, NoEventMask, close_win, &s); mlx_loop_hook(s.mlx, no_event_handle, &s); draw_fractal(&s); mlx_loop(s.mlx); - mlx_destroy_image(s.mlx, s.img.img); - free_session(&s); + cleanup(&s); return (0); }