aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/color.c94
-rw-r--r--src/event.c96
-rw-r--r--src/main.c1
-rw-r--r--src/mandelbrot.c19
-rw-r--r--src/state.c65
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;
+}
diff --git a/src/main.c b/src/main.c
index c19d32a..5884a64 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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();