aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2019-09-22 11:44:30 +0200
committerCharles <sircharlesaze@gmail.com>2019-09-22 11:44:30 +0200
commitc5008a4e62fb83eb71f5f94f622c01f2d8fe8b6b (patch)
tree02d1f84aca29c95e999156848a86d61c292b7208
parent5efde1e3e65af769cb629d55f0a4dd4f87caebe9 (diff)
downloadmandelbrot_cpu-c5008a4e62fb83eb71f5f94f622c01f2d8fe8b6b.tar.gz
mandelbrot_cpu-c5008a4e62fb83eb71f5f94f622c01f2d8fe8b6b.tar.bz2
mandelbrot_cpu-c5008a4e62fb83eb71f5f94f622c01f2d8fe8b6b.zip
Supersampling
- Random supersampling (prettier but quite slow) - WIP: bette color gradient
-rw-r--r--Makefile2
-rw-r--r--README.md5
-rw-r--r--graphics.c6
-rw-r--r--header.h8
-rw-r--r--helper.c50
-rw-r--r--mandelbrot.c36
6 files changed, 85 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index 85660a0..11997f9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
NAME = mandel
CC = gcc
CCFLAGS = -Wall -Wextra
-LDFLAGS = -lpthread $(shell sdl2-config --libs --cflags)
+LDFLAGS = -lm -lpthread $(shell sdl2-config --libs --cflags)
HEADER = header.h
SRC = main.c graphics.c mandelbrot.c helper.c
diff --git a/README.md b/README.md
index 24a5002..0cae1d4 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,13 @@ SDL2: `sudo apt install libsdl2-dev`
## TODO
-- [ ] Create color spectrum.
+- [ ] Color gradient with control points and cubic iterpolation
+ like <https://stackoverflow.com/a/25816111>
- [ ] Smooth shading for out of set iteration colors.
- [ ] Draw to bmp image.
- [x] Create pixel array and update the render line by line.
- [ ] Display coordinates and other useful info.
- [x] Computation done in parallel.
- [x] Command line options
+- [x] Anti-aliasing with supersampling
+- [ ] Other (not random?) supersampling algorithm
diff --git a/graphics.c b/graphics.c
index d8c6997..e422071 100644
--- a/graphics.c
+++ b/graphics.c
@@ -17,6 +17,8 @@
#define IN_SET_COLOR 0x050505
#define PALETTE_START 0x000022
#define PALETTE_END 0xd62f2f
+/* #define PALETTE_START 0x000000 */
+/* #define PALETTE_END 0xffffff */
#define SET_DRAW_COLOR(renderer, c) ( \
SDL_SetRenderDrawColor(renderer, c.rgb.r, c.rgb.g, c.rgb.b, SDL_ALPHA_OPAQUE));
@@ -185,7 +187,7 @@ static void event_handler(GState *state)
zoom_out(state, ZOOM_RATIO);
break;
case SDL_MOUSEBUTTONDOWN:
- printf("> %d, %d\n", e.button.x, e.button.y);
+ /* printf("> %d, %d\n", e.button.x, e.button.y); */
if (e.button.button == SDL_BUTTON_RIGHT)
recenter(state, e.button.x, e.button.y);
// TODO
@@ -222,6 +224,8 @@ static void event_handler(GState *state)
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;
diff --git a/header.h b/header.h
index fbaca08..92b4d83 100644
--- a/header.h
+++ b/header.h
@@ -4,8 +4,8 @@
# include <stdbool.h>
# include <SDL2/SDL.h>
-# define MAX_ITERATION 210
-# define ESCAPE_RADIUS 2
+# define MAX_ITERATION 200
+# define ESCAPE_RADIUS 10
# define ESCAPE_RADIUS_SQUARED (ESCAPE_RADIUS * ESCAPE_RADIUS)
# define PIXELS_CHANELS 3
@@ -62,6 +62,7 @@ typedef struct
{
double real_lo;
double real_hi;
+ double imag_step;
int width;
double imag;
Color *palette;
@@ -81,6 +82,7 @@ void graphics_run(GState *state);
// helper.c
double map_range(double x, double src_lo, double src_hi, double dest_lo, double dest_hi);
-int *inclusive_range(int start, int end);
+Color helper_HSL_to_RGB(int hue, double saturation, double lightness);
+double double_rand(void);
#endif
diff --git a/helper.c b/helper.c
index 0290563..3e02182 100644
--- a/helper.c
+++ b/helper.c
@@ -1,22 +1,48 @@
#include <math.h>
#include "header.h"
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MIN3(x, y, z) (MIN(x, MIN(y, z)))
+
double map_range(double x, double src_lo, double src_hi, double dest_lo, double dest_hi)
{
- double src_len = fabs(src_hi - src_lo);
- double dest_len = fabs(dest_hi - dest_lo);
-
+ double src_len = src_hi - src_lo;
+ double dest_len = dest_hi - dest_lo;
return (x - src_lo) / src_len * dest_len + dest_lo;
}
-int *inclusive_range(int start, int end)
+Color helper_HSL_to_RGB(int hue, double saturation, double lightness)
+{
+ /* double chroma = (1 - fabs(2 * lightness - 1)) * saturation; */
+ /* int hue_p = hue / 60; */
+ /* double x = chroma * (1 - abs(hue_p % 2 - 1)); */
+ Color color;
+
+ /* if (hue == 0) */
+ /* { */
+ /* color.hexcode = 0x000000; */
+ /* return color; */
+ /* } */
+ /* */
+ /* if (hue_p */
+
+ double a = saturation * MIN(lightness, 1 - lightness);
+ int kn0 = (0 + hue / 30) % 12;
+ int kn8 = (8 + hue / 30) % 12;
+ int kn4 = (4 + hue / 30) % 12;
+ Byte f0 = lightness - a * MAX(MIN3(kn0 - 3, 9 - kn0, 1), -1);
+ Byte f8 = lightness - a * MAX(MIN3(kn8 - 3, 9 - kn8, 1), -1);
+ Byte f4 = lightness - a * MAX(MIN3(kn4 - 3, 9 - kn4, 1), -1);
+
+ color.rgb.r = f0;
+ color.rgb.g = f8;
+ color.rgb.b = f4;
+
+ return color;
+}
+
+double double_rand(void)
{
- if (end < start)
- return NULL;
- int *range = malloc(sizeof(int) * (end - start + 1));
- if (range == NULL)
- return NULL;
- for (int i = 0; start < end; i++)
- range[i] = start++;
- return range;
+ return (double)rand() / RAND_MAX;
}
diff --git a/mandelbrot.c b/mandelbrot.c
index 1112575..7017a54 100644
--- a/mandelbrot.c
+++ b/mandelbrot.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <math.h>
#include <pthread.h>
#include "header.h"
@@ -9,6 +10,7 @@
#define AXIS_DIV 46.0
#define REAL_AXIS_STEP ((PRINT_REAL_HI - PRINT_REAL_LO) / AXIS_DIV)
#define IMAG_AXIS_STEP ((PRINT_IMAG_HI - PRINT_IMAG_LO) / AXIS_DIV)
+#define SAMPLES 1
#define IN_CHAR '*'
#define OUT_CHAR ' '
@@ -37,6 +39,16 @@ int mandelbrot_in_set(double ca, double cb)
return n;
}
+
+int mandelbrot_in_set_super_sampled(double ca, double cb, double real_step, double imag_step)
+{
+ int total = 0;
+ for (int i = 0; i < SAMPLES; i++)
+ total += mandelbrot_in_set(ca - (double_rand() * real_step) / 2,
+ cb - (double_rand() * imag_step) / 2);
+ return total / SAMPLES;
+}
+
void *mandelbrot_pixels(double real_lo, double real_hi, double imag_lo,
double imag_hi, int width, int height, Color *palette)
{
@@ -55,6 +67,7 @@ void *mandelbrot_pixels(double real_lo, double real_hi, double imag_lo,
args->real_hi = real_hi;
args->width = width;
args->imag = map_range((double)y, 0, height, imag_lo, imag_hi);
+ args->imag_step = (imag_hi - imag_lo) / (0.5 + (height - 1));
args->palette = palette;
args->row = pixels + PIXELS_CHANELS * width * y;
pthread_create(&threads[y], NULL, pixel_row, args);
@@ -68,13 +81,28 @@ void *mandelbrot_pixels(double real_lo, double real_hi, double imag_lo,
static void *pixel_row(void *void_args)
{
ThreadArgs *args = (ThreadArgs*)void_args;
+ int iterations;
+ double real_step = (args->real_hi - args->real_lo) / (0.5 + (args->width - 1));
for (int x = 0; x < args->width; x++)
{
double a = map_range((double)x, 0, args->width, args->real_lo, args->real_hi);
- Color color = args->palette[mandelbrot_in_set(a, args->imag)];
- args->row[x * PIXELS_CHANELS] = color.rgb.r;
- args->row[x * PIXELS_CHANELS + 1] = color.rgb.g;
- args->row[x * PIXELS_CHANELS + 2] = color.rgb.b;
+ if (SAMPLES == 1)
+ iterations = mandelbrot_in_set(a, args->imag);
+ else
+ {
+ iterations = mandelbrot_in_set_super_sampled(
+ a, args->imag, real_step, args->imag_step);
+ }
+
+ /* double logBase = 1.0 / log(2.0); */
+ /* double logHalfBase = log(0.5) * logBase; */
+ /* int color_index = (int)(5 + iterations - logHalfBase */
+ /* - log(log(a * a + args->imag * args->imag)) * logBase); */
+ Color color = args->palette[iterations];
+ int row_index = x * PIXELS_CHANELS;
+ args->row[row_index] = color.rgb.r;
+ args->row[row_index + 1] = color.rgb.g;
+ args->row[row_index + 2] = color.rgb.b;
}
free(args);
return NULL;