diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-05-19 16:46:13 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-05-19 18:19:31 +0200 |
| commit | b0998910dd974280b3c6f3f65e21bfd5859b117f (patch) | |
| tree | 5a7049ac6cf0d05370df3324b2bb4b591c2bac87 /src | |
| parent | 6a80b1b70ec069b051c0e31aafac6eb596e20261 (diff) | |
| download | mandelbrot_cpu-b0998910dd974280b3c6f3f65e21bfd5859b117f.tar.gz mandelbrot_cpu-b0998910dd974280b3c6f3f65e21bfd5859b117f.tar.bz2 mandelbrot_cpu-b0998910dd974280b3c6f3f65e21bfd5859b117f.zip | |
Basic explorer with window resize, iterations change, moving around
Diffstat (limited to 'src')
| -rw-r--r-- | src/color.c | 94 | ||||
| -rw-r--r-- | src/event.c | 96 | ||||
| -rw-r--r-- | src/main.c | 1 | ||||
| -rw-r--r-- | src/mandelbrot.c | 19 | ||||
| -rw-r--r-- | src/state.c | 65 |
5 files changed, 229 insertions, 46 deletions
diff --git a/src/color.c b/src/color.c index f758595..2ad4bad 100644 --- a/src/color.c +++ b/src/color.c @@ -1,22 +1,76 @@ #include "mandel.h" -/* static Color *create_palette(Color start, Color end) */ -/* { */ - /* int red_step = abs(end.rgb.r - start.rgb.r) / MAX_ITERATION; */ - /* int green_step = abs(end.rgb.g - start.rgb.g) / MAX_ITERATION; */ - /* int blue_step = abs(end.rgb.b - start.rgb.b) / MAX_ITERATION; */ - /* */ - /* Color *palette = (Color*)malloc(sizeof(Color) * (MAX_ITERATION + 1)); */ - /* if (palette == NULL) */ - /* return NULL; */ - /* for (int i = 0; i < MAX_ITERATION; i++) */ - /* { */ - /* #<{(| palette[i] = helper_HSL_to_RGB(i, 0.6, 1.0); |)}># */ - /* #<{(| printf("%x\n", palette[i].hexcode); |)}># */ - /* palette[i].rgb.r = i * red_step + start.rgb.r; */ - /* palette[i].rgb.g = i * green_step + start.rgb.g; */ - /* palette[i].rgb.b = i * blue_step + start.rgb.b; */ - /* } */ - /* palette[MAX_ITERATION].hexcode = 0x0; */ - /* return palette; */ -/* } */ +#define MAX(x, y) (x > y ? x : y) +#define MIN(x, y) (x < y ? x : y) + +static Color color_hsl_to_rgb(ColorHSL color_hsl); + +Color *color_palette_new(Color *palette, int iterations) +{ + ColorHSL hsl; + + palette = realloc(palette, sizeof(Color) * (iterations + 1)); + if (palette == NULL) + return NULL; + for (int i = 0; i < iterations; i++) + { + hsl.h = (int)(255.0 * ((double)i / (double)iterations)); + hsl.s = 150; + hsl.l = 127; + palette[i] = color_hsl_to_rgb(hsl); + } + palette[iterations].data = 0x0; + return palette; +} + +static Color color_hsl_to_rgb(ColorHSL color_hsl) +{ + Color color_rgb; + double h; + double s; + double l; + double r; + double g; + double b; + double temp1, temp2, tempr, tempg, tempb; + + h = color_hsl.h / 256.0; + s = color_hsl.s / 256.0; + l = color_hsl.l / 256.0; + if(s == 0) + { + r = l; + g = l; + b = l; + } + else + { + if (l < 0.5) temp2 = l * (1 + s); + else temp2 = (l + s) - (l * s); + temp1 = 2 * l - temp2; + tempr = h + 1.0 / 3.0; + if (tempr > 1) tempr--; + tempg = h; + tempb = h - 1.0 / 3.0; + if (tempb < 0) tempb++; + + if (tempr < 1.0 / 6.0) r = temp1 + (temp2 - temp1) * 6.0 * tempr; + else if (tempr < 0.5) r = temp2; + else if (tempr < 2.0 / 3.0) r = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempr) * 6.0; + else r = temp1; + + if (tempg < 1.0 / 6.0) g = temp1 + (temp2 - temp1) * 6.0 * tempg; + else if (tempg < 0.5) g = temp2; + else if (tempg < 2.0 / 3.0) g = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempg) * 6.0; + else g = temp1; + + if(tempb < 1.0 / 6.0) b = temp1 + (temp2 - temp1) * 6.0 * tempb; + else if(tempb < 0.5) b = temp2; + else if(tempb < 2.0 / 3.0) b = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempb) * 6.0; + else b = temp1; + } + color_rgb.r = (int)(r * 256.0); + color_rgb.g = (int)(g * 256.0); + color_rgb.b = (int)(b * 256.0); + return (color_rgb); +} diff --git a/src/event.c b/src/event.c index d0354eb..f0f0e14 100644 --- a/src/event.c +++ b/src/event.c @@ -1,6 +1,10 @@ #include "mandel.h" -void event_handle(State *state) +static void st_zoom(State *state, bool zoom_in); +static void st_move_horizontal(State *state, bool move_right); +static void st_move_vertical(State *state, bool move_down); + +void event_handle(State *state) { SDL_Event e; @@ -11,46 +15,112 @@ void event_handle(State *state) case SDL_QUIT: state->running = false; break; + case SDL_KEYDOWN: switch (e.key.keysym.sym) { + case SDLK_r: + state->iterations += 10; + state->palette = color_palette_new(state->palette, state->iterations); + break; + case SDLK_e: + state->iterations -= 10; + if (state->iterations <= 0) + state->iterations = 1; + state->palette = color_palette_new(state->palette, state->iterations); + break; case SDLK_UP: case SDLK_k: - + st_move_vertical(state, false); break; case SDLK_DOWN: case SDLK_j: - + st_move_vertical(state, true); break; case SDLK_LEFT: case SDLK_h: - + st_move_horizontal(state, false); break; case SDLK_RIGHT: case SDLK_l: - + st_move_horizontal(state, true); break; - case SDLK_PLUS: - case SDLK_p: - + case SDLK_EQUALS: + case SDLK_f: + st_zoom(state, true); break; case SDLK_MINUS: - case SDLK_m: - + case SDLK_d: + st_zoom(state, false); break; case SDLK_q: state->running = false; } break; + case SDL_MOUSEWHEEL: if (e.wheel.y == -1) - ; + st_zoom(state, true); else if (e.wheel.y == 1) - ; + st_zoom(state, false); break; - case SDL_MOUSEBUTTONDOWN: + + case SDL_WINDOWEVENT: + if (e.window.event == SDL_WINDOWEVENT_RESIZED) + { + int width; + int height; + SDL_QueryTexture(state->texture, NULL, NULL, &width, &height); + + double w_ratio = (double)width / (double)e.window.data1; + double h_ratio = (double)height / (double)e.window.data2; + + state->real_start /= w_ratio; + state->real_end /= w_ratio; + state->imag_start /= h_ratio; + state->imag_end /= h_ratio; + + SDL_DestroyTexture(state->texture); + SDL_CALL(state->texture = SDL_CreateTexture( + state->renderer, + SDL_PIXELFORMAT_RGB888, + SDL_TEXTUREACCESS_STREAMING, + e.window.data1, + e.window.data2 + )); + } break; } } } +#define MANDEL_ZOOM_RATIO 30 + +static void st_zoom(State *state, bool zoom_in) +{ + double factor = zoom_in ? 1 : -1; + double real_change = (state->real_end - state->real_start) / MANDEL_ZOOM_RATIO; + double imag_change = (state->imag_end - state->imag_start) / MANDEL_ZOOM_RATIO; + state->real_start += factor * real_change; + state->real_end -= factor * real_change; + state->imag_start += factor * imag_change; + state->imag_end -= factor * imag_change; +} + +#define MANDEL_MOVE_RATIO 20 + +static void st_move_horizontal(State *state, bool move_right) +{ + double factor = move_right ? 1 : -1; + double real_change = (state->real_end - state->real_start) / MANDEL_MOVE_RATIO; + state->real_start += factor * real_change; + state->real_end += factor * real_change; +} + +static void st_move_vertical(State *state, bool move_down) +{ + double factor = move_down ? 1 : -1; + double imag_change = (state->imag_end - state->imag_start) / MANDEL_MOVE_RATIO; + state->imag_start += factor * imag_change; + state->imag_end += factor * imag_change; +} @@ -7,6 +7,7 @@ int main(void) if (!state_init(&state)) return (1); state_run(&state); + /* printf("yo\n"); */ state_quit(&state); return EXIT_SUCCESS; } diff --git a/src/mandelbrot.c b/src/mandelbrot.c index a996b26..3c8ab98 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -1,19 +1,20 @@ #include "mandel.h" -int mandelbrot(double ca, double cb) +int mandelbrot(double ca, double cb, int iterations) { - double zr = ca; - double zi = cb; - double zr_square; - double zi_square; - int n; - for (n = 0; n < 20; n++) + double zr = ca; + double zi = cb; + double zr_square; + double zi_square; + int n; + + for (n = 0; n < iterations; n++) { zi_square = zi * zi; zr_square = zr * zr; - if (zr_square + zi_square > 4) + if (zr_square + zi_square > 4.0) return n; - zi = 2 * zr * zi; + zi = 2.0 * zr * zi; zr = zr_square - zi_square; zi += cb; zr += ca; diff --git a/src/state.c b/src/state.c index ee68b77..395d590 100644 --- a/src/state.c +++ b/src/state.c @@ -10,10 +10,26 @@ bool state_init(State *state) SDL_WINDOWPOS_UNDEFINED, MANDEL_WINDOW_WIDTH, MANDEL_WINDOW_HEIGHT, - 0)); + SDL_WINDOW_RESIZABLE + )); SDL_CALL(state->renderer = SDL_CreateRenderer(state->window, -1, 0)); + SDL_CALL(state->texture = SDL_CreateTexture( + state->renderer, + SDL_PIXELFORMAT_RGB888, + SDL_TEXTUREACCESS_STREAMING, + MANDEL_WINDOW_WIDTH, + MANDEL_WINDOW_HEIGHT + )); + state->palette = color_palette_new(NULL, MANDEL_ITERATIONS); + if (state->palette == NULL) + return false; + state->iterations = MANDEL_ITERATIONS; + state->real_start = -2.0; + state->real_end = 2.0; + state->imag_start = -2.0; + state->imag_end = 2.0; state->running = true; - return state; + return true; } void state_run(State *state) @@ -21,13 +37,54 @@ void state_run(State *state) while (state->running) { event_handle(state); + + double real_step; + double imag_step; + double real; + double imag; + void *pixels; + int pitch; + int width; + int height; + + SDL_CALL(SDL_LockTexture(state->texture, NULL, &pixels, &pitch)); + SDL_CALL(SDL_QueryTexture(state->texture, NULL, NULL, &width, &height)); + + real_step = (state->real_end - state->real_start) / width; + imag_step = (state->imag_end - state->imag_start) / height; + imag = state->imag_start; + + uint32_t render_start_time = SDL_GetTicks(); + + for (int i = 0; i < height; i++) + { + real = state->real_start; + for (int j = 0; j < width; j++) + { + int n = mandelbrot(real, imag, state->iterations); + Color c = state->palette[n]; + ((Color*)pixels)[i * width + j] = c; + real += real_step; + } + imag += imag_step; + } + + uint32_t render_end_time = SDL_GetTicks(); + + printf("%ums\r", (render_end_time - render_start_time)); + fflush(stdout); + + SDL_UnlockTexture(state->texture); + SDL_CALL(SDL_RenderCopy(state->renderer, state->texture, NULL, NULL)); + SDL_RenderPresent(state->renderer); + SDL_Delay(3); } } void state_quit(State *state) { - /* free(state->palette); */ - /* SDL_FreeSurface(state->surface); */ + free(state->palette); + SDL_DestroyTexture(state->texture); SDL_DestroyRenderer(state->renderer); SDL_DestroyWindow(state->window); SDL_Quit(); |
