-i arg for max iterations and lots of new bugs fixed!

parent e00e1adf
...@@ -19,7 +19,7 @@ CC = clang ...@@ -19,7 +19,7 @@ CC = clang
OBJS = $(BIULDDIR)/mouse.o $(BIULDDIR)/ui.o OBJS = $(BIULDDIR)/mouse.o $(BIULDDIR)/ui.o
all: mandelbrot all: mandelbrot fast
mandelbrot: $(SRCDIR)/mandelbrot.c $(OBJS) mandelbrot: $(SRCDIR)/mandelbrot.c $(OBJS)
$(CC) $(CFLAGS) $(DEBUG_FLAGS) $(LDLIBS) $^ -o $@ $(CC) $(CFLAGS) $(DEBUG_FLAGS) $(LDLIBS) $^ -o $@
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
*/ */
int int
mandelbrot_avx(Complex c) mandelbrot_avx(Complex c, unsigned max_iterations)
{ {
__m256 cr = _mm256_set1_pd(c.real); __m256 cr = _mm256_set1_pd(c.real);
__m256 ci = _mm256_set1_pd(c.imag); __m256 ci = _mm256_set1_pd(c.imag);
...@@ -42,11 +42,11 @@ mandelbrot_avx(Complex c) ...@@ -42,11 +42,11 @@ mandelbrot_avx(Complex c)
__m256 threshold = _mm256_set1_pd(4); __m256 threshold = _mm256_set1_pd(4);
int k = 1; unsigned int k = 1;
__m256 mk = _mm256_set1_pd(k); __m256 mk = _mm256_set1_pd(k);
__m256 one = _mm256_set1_pd(1); __m256 one = _mm256_set1_pd(1);
while (++k < MAX_ITERATIONS){ while (++k < max_iterations){
/* Compute z1 from z0 */ /* Compute z1 from z0 */
__m256 zr2 = _mm256_mul_pd(zr, zr); __m256 zr2 = _mm256_mul_pd(zr, zr);
__m256 zi2 = _mm256_mul_pd(zi, zi); __m256 zi2 = _mm256_mul_pd(zi, zi);
...@@ -72,11 +72,11 @@ mandelbrot_avx(Complex c) ...@@ -72,11 +72,11 @@ mandelbrot_avx(Complex c)
int int
mandelbrot(Complex c) { mandelbrot(Complex c, unsigned int max_iterations) {
Complex z = {0.0, 0.0}; Complex z = {0.0, 0.0};
int i; unsigned int i;
for (i = 0; i < MAX_ITERATIONS; i++) { for (i = 0; i < max_iterations; i++) {
long double temp_real = z.real * z.real - z.imag * z.imag + c.real; long double temp_real = z.real * z.real - z.imag * z.imag + c.real;
long double temp_imag = 2 * z.real * z.imag + c.imag; long double temp_imag = 2 * z.real * z.imag + c.imag;
z.real = temp_real; z.real = temp_real;
...@@ -85,7 +85,7 @@ mandelbrot(Complex c) { ...@@ -85,7 +85,7 @@ mandelbrot(Complex c) {
if (__builtin_hypot(z.real, z.imag) > 2) if (__builtin_hypot(z.real, z.imag) > 2)
return i; return i;
} }
return MAX_ITERATIONS; return max_iterations;
} }
typedef struct{ typedef struct{
...@@ -101,9 +101,9 @@ typedef struct { ...@@ -101,9 +101,9 @@ typedef struct {
}Array; }Array;
void void
calculate_set(Array *arr, int height, int width, ViewInfo view, short unsigned use_avx) calculate_set(Array *arr, int height, int width, ViewInfo view, short unsigned use_avx, unsigned int max_iterations)
{ {
int (*mandelbrot_func)(Complex C); int (*mandelbrot_func)(Complex C, unsigned);
if (use_avx == 0) if (use_avx == 0)
mandelbrot_func = mandelbrot; mandelbrot_func = mandelbrot;
...@@ -116,15 +116,15 @@ calculate_set(Array *arr, int height, int width, ViewInfo view, short unsigned u ...@@ -116,15 +116,15 @@ calculate_set(Array *arr, int height, int width, ViewInfo view, short unsigned u
long double imag = view.y_min + (y * (view.y_max - view.y_min)) / height; long double imag = view.y_min + (y * (view.y_max - view.y_min)) / height;
Complex c = {real, imag}; Complex c = {real, imag};
int iterations = mandelbrot_func(c); unsigned int iterations = mandelbrot_func(c, max_iterations);
if (iterations == MAX_ITERATIONS){ if (iterations == max_iterations){
arr->pointer[y * width + x].r = 0; arr->pointer[y * width + x].r = 0;
arr->pointer[y * width + x].g = 0; arr->pointer[y * width + x].g = 0;
arr->pointer[y * width + x].b = 0; arr->pointer[y * width + x].b = 0;
arr->pointer[y * width + x].a = 0; arr->pointer[y * width + x].a = 0;
} else { } else {
double t = (double)iterations / MAX_ITERATIONS; double t = (double)iterations / max_iterations;
t = 0.5 + 0.5 * tan(log(t + 0.0001) * 3.0); t = 0.5 + 0.5 * tan(log(t + 0.0001) * 3.0);
arr->pointer[y * width + x].r = 255 * t * 0.5; arr->pointer[y * width + x].r = 255 * t * 0.5;
...@@ -137,9 +137,9 @@ calculate_set(Array *arr, int height, int width, ViewInfo view, short unsigned u ...@@ -137,9 +137,9 @@ calculate_set(Array *arr, int height, int width, ViewInfo view, short unsigned u
} }
void void
calculate_set_omp(Array *arr, int height, int width, ViewInfo view, short unsigned use_avx) calculate_set_omp(Array *arr, int height, int width, ViewInfo view, short unsigned use_avx, unsigned int max_iterations)
{ {
int (*mandelbrot_func)(Complex C); int (*mandelbrot_func)(Complex, unsigned);
if (use_avx == 0) if (use_avx == 0)
mandelbrot_func = mandelbrot; mandelbrot_func = mandelbrot;
...@@ -153,15 +153,15 @@ calculate_set_omp(Array *arr, int height, int width, ViewInfo view, short unsign ...@@ -153,15 +153,15 @@ calculate_set_omp(Array *arr, int height, int width, ViewInfo view, short unsign
long double imag = view.y_min + (y * (view.y_max - view.y_min)) / height; long double imag = view.y_min + (y * (view.y_max - view.y_min)) / height;
Complex c = {real, imag}; Complex c = {real, imag};
int iterations = mandelbrot_func(c); unsigned int iterations = mandelbrot_func(c, max_iterations);
if (iterations == MAX_ITERATIONS){ if (iterations == max_iterations){
arr->pointer[y * width + x].r = 0; arr->pointer[y * width + x].r = 0;
arr->pointer[y * width + x].g = 0; arr->pointer[y * width + x].g = 0;
arr->pointer[y * width + x].b = 0; arr->pointer[y * width + x].b = 0;
arr->pointer[y * width + x].a = 0; arr->pointer[y * width + x].a = 0;
} else { } else {
double t = (double)iterations / MAX_ITERATIONS; double t = (double)iterations / max_iterations;
t = 0.5 + 0.5 * tan(log(t + 0.0001) * 3.0); t = 0.5 + 0.5 * tan(log(t + 0.0001) * 3.0);
arr->pointer[y * width + x].r = 255 * t * 0.5; arr->pointer[y * width + x].r = 255 * t * 0.5;
...@@ -194,9 +194,10 @@ struct arguments ...@@ -194,9 +194,10 @@ struct arguments
char *output_file; char *output_file;
int width; int width;
int height; int height;
unsigned int max_iterations;
short unsigned use_avx; short unsigned use_avx;
short unsigned use_omp; short unsigned use_omp;
int redcalc; int recalc;
double x_min; double x_min;
double x_max; double x_max;
...@@ -209,12 +210,13 @@ struct arguments ...@@ -209,12 +210,13 @@ struct arguments
static struct argp_option options[] = static struct argp_option options[] =
{ {
{"output file", 'o', "FILE", 0, "Render to image"}, {"output file", 'o', "FILE", 0, "Render to image, default False"},
{"width", 'w', "WIDTH", 0, "Width of window/image"}, {"width", 'w', "WIDTH", 0, "Width of window/image, default 640"},
{"height", 'h', "HEIGHT", 0, "Height of window/image"}, {"height", 'h', "HEIGHT", 0, "Height of window/image, default 480"},
{"dont_use_avx", 'x', 0, 0, "NOT use avx for calculations"}, {"iterations", 'i', "ITERATIONS", 0, "Max iterations, default 250."},
{"dont_use_omp", 't', 0, 0, "NOT use openmpfor calculations"}, {"dont_use_avx", 'x', 0, 0, "NOT use avx for calculations, default False"},
{"recalc", 'r', 0, 0, "Recalculate set on every frame"}, {"dont_use_omp", 't', 0, 0, "NOT use openmpfor calculations, default False"},
{"recalc", 'r', 0, 0, "Recalculate set on every frame, default False"},
{"x_min", 'a', "VALUE", 0, "X min"}, {"x_min", 'a', "VALUE", 0, "X min"},
{"x_max", 'b', "VALUE", 0, "X max"}, {"x_max", 'b', "VALUE", 0, "X max"},
...@@ -231,6 +233,9 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -231,6 +233,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
struct arguments *arguments = state->input; struct arguments *arguments = state->input;
switch (key) switch (key)
{ {
case 'i':
arguments->max_iterations = atoi(arg);
break;
case 'o': case 'o':
arguments->output_file = arg; arguments->output_file = arg;
break; break;
...@@ -247,20 +252,20 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -247,20 +252,20 @@ parse_opt (int key, char *arg, struct argp_state *state)
arguments->use_omp = 0; arguments->use_omp = 0;
break; break;
case 'r': case 'r':
arguments->redcalc = 1; arguments->recalc = 1;
break; break;
case 'a': case 'a':
arguments->x_min = atoi(arg); arguments->x_max = atoi(arg);
break; break;
case 'b': case 'b':
arguments->redcalc = atoi(arg); arguments->x_min = atoi(arg);
break; break;
case 'c': case 'c':
arguments->redcalc = atoi(arg); arguments->y_max= atoi(arg);
break; break;
case 'd': case 'd':
arguments->redcalc = atoi(arg); arguments->y_min= atoi(arg);
break; break;
case 'z': case 'z':
arguments->zoom= atof(arg); arguments->zoom= atof(arg);
...@@ -280,10 +285,11 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -280,10 +285,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
static struct argp argp = {options, parse_opt, NULL, NULL}; static struct argp argp = {options, parse_opt, NULL, NULL};
void void
render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, int height, ViewInfo *view, short unsigned use_avx, short unsigned use_omp, short unsigned *needs_recalc) { render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, int height, ViewInfo *view,
short unsigned use_avx, short unsigned use_omp, short unsigned *needs_recalc, unsigned int max_iterations) {
void (*calculate_set_func)(Array *arr, int height, int width, void (*calculate_set_func)(Array *arr, int height, int width,
ViewInfo view, short unsigned use_avx); ViewInfo view, short unsigned use_avx, unsigned max_iterations);
calculate_set_func = use_omp ? calculate_set_omp : calculate_set; calculate_set_func = use_omp ? calculate_set_omp : calculate_set;
...@@ -294,8 +300,8 @@ render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, i ...@@ -294,8 +300,8 @@ render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, i
arr->pointer = realloc(arr->pointer, height * width * sizeof(Color)); arr->pointer = realloc(arr->pointer, height * width * sizeof(Color));
arr->size = height * width * sizeof(Color); arr->size = height * width * sizeof(Color);
} }
if (needs_recalc){ if (*needs_recalc){
calculate_set_func(arr, height, width, *view, use_avx); calculate_set_func(arr, height, width, *view, use_avx, max_iterations);
*needs_recalc = 0; *needs_recalc = 0;
} }
...@@ -306,7 +312,7 @@ render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, i ...@@ -306,7 +312,7 @@ render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, i
short unsigned short unsigned
render_headless(ViewInfo view, const char* filename, render_headless(ViewInfo view, const char* filename,
int width, int height, int width, int height, unsigned int max_iterations,
short unsigned use_avx, short unsigned use_omp) { short unsigned use_avx, short unsigned use_omp) {
SDL_Surface* surface = SDL_CreateRGBSurface(0, SDL_Surface* surface = SDL_CreateRGBSurface(0,
width, height, width, height,
...@@ -329,12 +335,9 @@ render_headless(ViewInfo view, const char* filename, ...@@ -329,12 +335,9 @@ render_headless(ViewInfo view, const char* filename,
width * height * sizeof(Color) width * height * sizeof(Color)
}; };
void (*calculate_set_func)(Array*, int, int, ViewInfo, short unsigned);
calculate_set_func = use_omp ? calculate_set_omp : calculate_set;
short unsigned int plug; short unsigned int plug;
render_cl(&arr, texture, renderer, width, height, &view, use_avx, use_omp, &plug); render_cl(&arr, texture, renderer, width, height, &view, use_avx, use_omp, &plug, max_iterations);
IMG_SavePNG(surface, filename); IMG_SavePNG(surface, filename);
free(arr.pointer); free(arr.pointer);
...@@ -349,8 +352,8 @@ main(int argc, char **argv) ...@@ -349,8 +352,8 @@ main(int argc, char **argv)
struct arguments args = { struct arguments args = {
NULL, NULL,
640, 480, 640, 480,
1, 1, 0, 250, 1, 0,
-2.0, 1.0, -1.5, 1.5, 1.0 0,-2.0, 1.0, -1.5, 1.5, 1.0,
}; };
argp_parse(&argp, argc, argv, 0, 0, &args); argp_parse(&argp, argc, argv, 0, 0, &args);
...@@ -370,7 +373,8 @@ main(int argc, char **argv) ...@@ -370,7 +373,8 @@ main(int argc, char **argv)
if (args.output_file) { if (args.output_file) {
render_headless(view, args.output_file, render_headless(view, args.output_file,
args.width, args.height, args.width, args.height,
args.use_avx, args.use_omp); args.use_avx, args.use_omp,
args.max_iterations);
SDL_Quit(); SDL_Quit();
return 0; return 0;
} }
...@@ -388,7 +392,7 @@ main(int argc, char **argv) ...@@ -388,7 +392,7 @@ main(int argc, char **argv)
SDL_TEXTUREACCESS_STREAMING, SDL_TEXTUREACCESS_STREAMING,
args.width, args.height), args.width, args.height),
args.height, args.height,
args.height, args.width,
1, 1,
0 0
}; };
...@@ -478,8 +482,13 @@ main(int argc, char **argv) ...@@ -478,8 +482,13 @@ main(int argc, char **argv)
} }
default: default:
//returns one if recalc needed //returns one if recalc needed
app.needs_recalc = app.needs_recalc == 0 ? handle_mouse(event, &mouse, &view) : 1; if (event.type == SDL_MOUSEBUTTONDOWN ||
app.needs_recalc = (app.needs_recalc || args.redcalc); event.type == SDL_MOUSEBUTTONUP ||
event.type == SDL_MOUSEWHEEL ||
event.type == SDL_MOUSEMOTION) {
app.needs_recalc = handle_mouse(event, &mouse, &view);
}
app.needs_recalc = (app.needs_recalc || args.recalc);
break; break;
} }
...@@ -489,7 +498,10 @@ main(int argc, char **argv) ...@@ -489,7 +498,10 @@ main(int argc, char **argv)
SDL_SetRenderDrawColor(app.renderer, 0xff, 0xff, 0xff, 0xff); SDL_SetRenderDrawColor(app.renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(app.renderer); SDL_RenderClear(app.renderer);
render_cl(&screen, app.texture, app.renderer, app.win_width, app.win_height, &view, args.use_avx, args.use_omp, &app.needs_recalc); printf("needs_recalc: %i\n", app.needs_recalc);
render_cl(&screen, app.texture, app.renderer, app.win_width, app.win_height, &view, args.use_avx, args.use_omp,
&app.needs_recalc, args.max_iterations);
int msec = SDL_GetTicks() - frame_start; int msec = SDL_GetTicks() - frame_start;
float fps = 0; float fps = 0;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define SCREEN_WIDTH 640 #define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480 #define SCREEN_HEIGHT 480
#define MAX_ITERATIONS 250
typedef struct { typedef struct {
long double real; long double real;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment