aboutsummaryrefslogtreecommitdiff
path: root/graphics.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics.c')
-rw-r--r--graphics.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/graphics.c b/graphics.c
index 4d29d2f..84aa20d 100644
--- a/graphics.c
+++ b/graphics.c
@@ -6,35 +6,48 @@
#define WINDOW_TITLE "Mandelbrot"
#define WINDOW_X 20
#define WINDOW_Y 20
-#define WINDOW_W 300
-#define WINDOW_H 300
-#define REFRESH_RATE 3
+#define WINDOW_W 500
+#define WINDOW_H 500
+#define REFRESH_RATE 1
#define MOVE_SIZE 0.1
#define ZOOM_SIZE 0.1
-#define BRIGHTNESS_LO 0
-#define BRIGHTNESS_HI 10
+#define RED_MASK 0xFF0000
+#define GREEN_MASK 0x00FF00
+#define BLUE_MASK 0x0000FF
+#define RED(c) ((c & RED_MASK) >> (8 * 2))
+#define GREEN(c) ((c & GREEN_MASK) >> 8)
+#define BLUE(c) (c & BLUE_MASK)
+#define MERGE_RGB(r, g, b) ((r) << (8 * 2) | (g) << 8 | (b))
+#define PALETTE_START 0x334455
+#define PALETTE_END 0xFFFFFF
+#define SET_DRAW_COLOR_RGB(renderer, c) ( \
+ SDL_SetRenderDrawColor(renderer, RED(c), GREEN(c), BLUE(c), SDL_ALPHA_OPAQUE))
+#define IN_SET_COLOR 0x000000
static void update(GState *state);
static void event_handler(GState *state);
+static Color *create_palette(Color start, Color end);
static void destroy_state(GState *state);
static void error_exit_state(GState *state, const char *msg);
static void error_exit(const char *msg);
GState *graphics_init(void)
{
- GState *state = (GState*)malloc(sizeof(GState));
- if (state == NULL)
- return NULL;
if (SDL_Init(SDL_INIT_VIDEO) < 0)
error_exit("unable to init SDL");
+ GState *state = (GState*)malloc(sizeof(GState));
+ if (state == NULL)
+ error_exit("state allocation failed");
state->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_X, WINDOW_Y,
WINDOW_W, WINDOW_H, 0);
if (state->window == NULL)
- error_exit("unable to create window");
+ error_exit_state(state, "unable to create window");
state->renderer = SDL_CreateRenderer(state->window, -1, 0);
if (state->renderer == NULL)
error_exit_state(state, "unable to create renderer");
+ if ((state->palette = create_palette(PALETTE_START, PALETTE_END)) == NULL)
+ error_exit_state(state, "unable to create color palette");
state->running = true;
state->window_w = WINDOW_W;
state->window_h = WINDOW_H;
@@ -63,8 +76,8 @@ void graphics_run(GState *state)
static void update(GState *state)
{
- double a, b, brightness;
- SDL_SetRenderDrawColor(state->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
+ double a, b;
+ SET_DRAW_COLOR_RGB(state->renderer, IN_SET_COLOR);
SDL_RenderClear(state->renderer);
for (int x = 0; x < state->window_w; x++)
{
@@ -76,10 +89,7 @@ static void update(GState *state)
int steps = mandelbrot_in_set(mapped_z);
if (steps == -1)
continue;
- brightness = map_range(steps, state->real_lo, state->real_hi,
- BRIGHTNESS_LO, BRIGHTNESS_HI);
- SDL_SetRenderDrawColor(state->renderer, brightness, brightness,
- brightness, SDL_ALPHA_OPAQUE);
+ SET_DRAW_COLOR_RGB(state->renderer, state->palette[steps]);
SDL_RenderDrawPoint(state->renderer, x, y);
}
}
@@ -96,42 +106,67 @@ static void event_handler(GState *state)
case SDL_QUIT:
state->running = false;
break;
- case SDL_KEYUP:
+ case SDL_KEYDOWN:
switch (e.key.keysym.sym)
{
case SDLK_UP:
+ case SDLK_k:
state->imag_lo -= MOVE_SIZE;
state->imag_hi -= MOVE_SIZE;
break;
case SDLK_DOWN:
+ case SDLK_j:
state->imag_lo += MOVE_SIZE;
state->imag_hi += MOVE_SIZE;
break;
case SDLK_LEFT:
+ case SDLK_h:
state->real_lo -= MOVE_SIZE;
state->real_hi -= MOVE_SIZE;
break;
case SDLK_RIGHT:
+ case SDLK_l:
state->real_lo += MOVE_SIZE;
state->real_hi += MOVE_SIZE;
break;
+ case SDLK_PLUS:
case SDLK_p:
state->real_lo += ZOOM_SIZE;
state->real_hi -= ZOOM_SIZE;
state->imag_lo += ZOOM_SIZE;
state->imag_hi -= ZOOM_SIZE;
break;
+ case SDLK_MINUS:
case SDLK_m:
state->real_lo -= ZOOM_SIZE;
state->real_hi += ZOOM_SIZE;
state->imag_lo -= ZOOM_SIZE;
state->imag_hi += ZOOM_SIZE;
break;
+ case SDLK_q:
+ state->running = false;
+ break;
}
}
}
}
+static Color *create_palette(Color start, Color end)
+{
+ Color red_step = abs(RED(end) - RED(start)) / MAX_ITERATION;
+ Color green_step = abs(GREEN(end) - GREEN(start)) / MAX_ITERATION;
+ Color blue_step = abs(BLUE(end) - BLUE(start)) / MAX_ITERATION;
+
+ Color *palette = (Color*)malloc(sizeof(Color) * MAX_ITERATION);
+ if (palette == NULL)
+ return NULL;
+ for (int i = 0; i < MAX_ITERATION; i++)
+ palette[i] = MERGE_RGB(i * red_step + RED(start),
+ i * green_step + GREEN(start),
+ i * blue_step + BLUE(start));
+ return palette;
+}
+
static void destroy_state(GState *state)
{
if (state == NULL)