aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-05-20 16:53:25 +0200
committerCharles <sircharlesaze@gmail.com>2020-05-20 16:53:25 +0200
commit322c1a49f59d3fc6441804bbbb29da22567e4bcb (patch)
tree1806d82a7f5cecdf4c256da86454ddf2530305cd
parent5d6b59778a7346317ddfc549c350c0960a7a54a7 (diff)
downloadmandelbrot-322c1a49f59d3fc6441804bbbb29da22567e4bcb.tar.gz
mandelbrot-322c1a49f59d3fc6441804bbbb29da22567e4bcb.tar.bz2
mandelbrot-322c1a49f59d3fc6441804bbbb29da22567e4bcb.zip
Correct resize, linear iterpolation draft
-rw-r--r--inc/config.h15
-rw-r--r--inc/mandel.h6
-rw-r--r--src/color.c93
-rw-r--r--src/event.c36
-rw-r--r--src/state.c1
5 files changed, 127 insertions, 24 deletions
diff --git a/inc/config.h b/inc/config.h
index c336c51..680d893 100644
--- a/inc/config.h
+++ b/inc/config.h
@@ -1,9 +1,20 @@
#ifndef CONFIG_H
# define CONFIG_H
-# define MANDEL_WINDOW_WIDTH 640
-# define MANDEL_WINDOW_HEIGHT 480
+# include "mandel.h"
+
+# define MANDEL_WINDOW_WIDTH 400
+# define MANDEL_WINDOW_HEIGHT 400
# define MANDEL_WINDOW_TITLE "Mandelbrot"
# define MANDEL_ITERATIONS 50
+static ControlPoint g_theme[] = {
+ {0.0, {0x00, 0x0F, 0x64} },
+ {0.16, {0x20, 0x6B, 0xCB} },
+ {0.42, {0xED, 0xFF, 0xFF} },
+ {0.6425, {0xFF, 0xAA, 0x00} },
+ {1.0, {0x00, 0x02, 0x00} },
+ // {0.8575, {0x00, 0x02, 0x00} },
+};
+
#endif
diff --git a/inc/mandel.h b/inc/mandel.h
index 0383a39..a2af137 100644
--- a/inc/mandel.h
+++ b/inc/mandel.h
@@ -58,6 +58,12 @@ typedef struct
typedef struct
{
+ float position;
+ Color color;
+} ControlPoint;
+
+typedef struct
+{
unsigned int id;
struct
{
diff --git a/src/color.c b/src/color.c
index 24ca2f2..40d43d5 100644
--- a/src/color.c
+++ b/src/color.c
@@ -1,19 +1,95 @@
#include "mandel.h"
+#include "config.h"
#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);
+static Color *st_hsl_rainbow(int count);
+static int st_compar_control_points(const void *ptr1, const void *ptr2);
+static Color *st_linear_iterpolation(int count, ControlPoint *points, size_t points_count);
unsigned int color_texture_new(int count)
{
- ColorHSL hsl;
- Color *palette;
unsigned int texture;
+ Color *palette;
- palette = malloc(sizeof(Color) * count);
- if (palette == NULL)
+ if ((palette = st_hsl_rainbow(count)) == NULL)
return 0;
+ /* if ((palette = st_linear_iterpolation(count, g_theme, sizeof(g_theme) / sizeof(ControlPoint))) == NULL) */
+ /* return 0; */
+ GL_CALL(glGenTextures(1, &texture));
+ GL_CALL(glBindTexture(GL_TEXTURE_1D, texture));
+ GL_CALL(glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+ GL_CALL(glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
+ GL_CALL(glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, count + 1, 0, GL_RGB, GL_UNSIGNED_BYTE, palette));
+ free(palette);
+ return texture;
+}
+
+static Color *st_linear_iterpolation(int count, ControlPoint *points, size_t points_count)
+{
+ Color *palette;
+
+ if (points_count < 2)
+ return NULL;
+ if ((palette = malloc(sizeof(Color) * count)) == NULL)
+ return NULL;
+ qsort(points, points_count, sizeof(ControlPoint), st_compar_control_points);
+
+ size_t point_i = 0;
+
+ double x0 = points[point_i].position;
+ double x1 = points[point_i + 1].position;
+
+ double y0 = points[point_i].color.r;
+ double y1 = points[point_i + 1].color.r;
+
+ double delta_x = x1 - x0;
+ double delta_y = y1 - y0;
+
+ double m = delta_x / delta_y;
+ double b = y0 - x0;
+
+ double red = 0;
+ for (int i = 0; i < count; i++)
+ {
+ palette[i].r = (uint8_t)(255.0 * (m * red + b));
+ red += 1.0 / (double)count;
+ if (red >= x1)
+ {
+ if (point_i >= points_count)
+ break;
+ x0 = x1;
+ point_i++;
+ x1 = points[point_i + 1].position;
+ }
+ palette[i].g = 0;
+ palette[i].b = 0;
+ printf("%d\n", i);
+ }
+ return palette;
+}
+
+static int st_compar_control_points(const void *ptr1, const void *ptr2)
+{
+ const ControlPoint *point1 = ptr1;
+ const ControlPoint *point2 = ptr2;
+
+ if (point1->position < point2->position)
+ return -1;
+ if (point1->position > point2->position)
+ return 1;
+ return 0;
+}
+
+static Color *st_hsl_rainbow(int count)
+{
+ ColorHSL hsl;
+ Color *palette;
+
+ if ((palette = malloc(sizeof(Color) * count)) == NULL)
+ return NULL;
for (int i = 0; i < count; i++)
{
hsl.h = (uint8_t)(255.0 * ((double)i / (double)count));
@@ -27,14 +103,7 @@ unsigned int color_texture_new(int count)
palette[i] = palette[j];
palette[j] = tmp;
}
-
- GL_CALL(glGenTextures(1, &texture));
- GL_CALL(glBindTexture(GL_TEXTURE_1D, texture));
- GL_CALL(glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
- GL_CALL(glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
- GL_CALL(glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, count + 1, 0, GL_RGB, GL_UNSIGNED_BYTE, palette));
- free(palette);
- return texture;
+ return palette;
}
static Color color_hsl_to_rgb(ColorHSL color_hsl)
diff --git a/src/event.c b/src/event.c
index 9d384fc..d5f1180 100644
--- a/src/event.c
+++ b/src/event.c
@@ -6,6 +6,7 @@ static void st_move_horizontal(State *state, bool move_right);
static void st_move_vertical(State *state, bool move_down);
static void st_set_key(SDL_Keycode sym, bool value);
static void st_apply_keys(State *state);
+static void st_resize(State *state, int new_width, int new_height);
static bool g_key_states[] = {
[KEY_UP] = false,
@@ -60,22 +61,37 @@ void event_handle(State *state)
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_RESIZED)
- {
- double w_ratio = (double)state->width / (double)e.window.data1;
- double h_ratio = (double)state->height / (double)e.window.data2;
- SDL_GL_GetDrawableSize(state->window, &state->width, &state->height);
- GL_CALL(glViewport(0, 0, state->width, state->height));
- state->real_start /= w_ratio;
- state->real_end /= w_ratio;
- state->imag_start /= h_ratio;
- state->imag_end /= h_ratio;
- }
+ st_resize(state, e.window.data1, e.window.data2);
break;
}
}
st_apply_keys(state);
}
+void st_resize(State *state, int new_width, int new_height)
+{
+ double w_delta = ((double)new_width - (double)state->width) / 2.0;
+ double h_delta = ((double)new_height - (double)state->height) / 2.0;
+
+ double real_dist = state->real_end - state->real_start;
+ double imag_dist = state->imag_end - state->imag_start;
+
+ double width_real_ratio = (double)state->width / real_dist;
+ double height_imag_ratio = (double)state->height / imag_dist;
+
+ w_delta /= width_real_ratio;
+ h_delta /= height_imag_ratio;
+
+ state->real_start -= w_delta;
+ state->real_end += w_delta;
+
+ state->imag_start -= h_delta;
+ state->imag_end += h_delta;
+
+ SDL_GL_GetDrawableSize(state->window, &state->width, &state->height);
+ GL_CALL(glViewport(0, 0, state->width, state->height));
+}
+
static void st_set_key(SDL_Keycode sym, bool value)
{
switch (sym)
diff --git a/src/state.c b/src/state.c
index f661de6..5df4f02 100644
--- a/src/state.c
+++ b/src/state.c
@@ -54,6 +54,7 @@ bool state_init(State *state)
state->real_end = 2.0;
state->imag_start = -2.0;
state->imag_end = 2.0;
+
state->running = true;
state->smooth = false;
state->samples = 1.0;