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

parent e00e1adf
......@@ -19,7 +19,7 @@ CC = clang
OBJS = $(BIULDDIR)/mouse.o $(BIULDDIR)/ui.o
all: mandelbrot
all: mandelbrot fast
mandelbrot: $(SRCDIR)/mandelbrot.c $(OBJS)
$(CC) $(CFLAGS) $(DEBUG_FLAGS) $(LDLIBS) $^ -o $@
......
......@@ -32,7 +32,7 @@
*/
int
mandelbrot_avx(Complex c)
mandelbrot_avx(Complex c, unsigned max_iterations)
{
__m256 cr = _mm256_set1_pd(c.real);
__m256 ci = _mm256_set1_pd(c.imag);
......@@ -42,11 +42,11 @@ mandelbrot_avx(Complex c)
__m256 threshold = _mm256_set1_pd(4);
int k = 1;
unsigned int k = 1;
__m256 mk = _mm256_set1_pd(k);
__m256 one = _mm256_set1_pd(1);
while (++k < MAX_ITERATIONS){
while (++k < max_iterations){
/* Compute z1 from z0 */
__m256 zr2 = _mm256_mul_pd(zr, zr);
__m256 zi2 = _mm256_mul_pd(zi, zi);
......@@ -72,11 +72,11 @@ mandelbrot_avx(Complex c)
int
mandelbrot(Complex c) {
mandelbrot(Complex c, unsigned int max_iterations) {
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_imag = 2 * z.real * z.imag + c.imag;
z.real = temp_real;
......@@ -85,7 +85,7 @@ mandelbrot(Complex c) {
if (__builtin_hypot(z.real, z.imag) > 2)
return i;
}
return MAX_ITERATIONS;
return max_iterations;
}
typedef struct{
......@@ -101,9 +101,9 @@ typedef struct {
}Array;
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)
mandelbrot_func = mandelbrot;
......@@ -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;
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].g = 0;
arr->pointer[y * width + x].b = 0;
arr->pointer[y * width + x].a = 0;
} 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);
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
}
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)
mandelbrot_func = mandelbrot;
......@@ -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;
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].g = 0;
arr->pointer[y * width + x].b = 0;
arr->pointer[y * width + x].a = 0;
} 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);
arr->pointer[y * width + x].r = 255 * t * 0.5;
......@@ -194,9 +194,10 @@ struct arguments
char *output_file;
int width;
int height;
unsigned int max_iterations;
short unsigned use_avx;
short unsigned use_omp;
int redcalc;
int recalc;
double x_min;
double x_max;
......@@ -209,12 +210,13 @@ struct arguments
static struct argp_option options[] =
{
{"output file", 'o', "FILE", 0, "Render to image"},
{"width", 'w', "WIDTH", 0, "Width of window/image"},
{"height", 'h', "HEIGHT", 0, "Height of window/image"},
{"dont_use_avx", 'x', 0, 0, "NOT use avx for calculations"},
{"dont_use_omp", 't', 0, 0, "NOT use openmpfor calculations"},
{"recalc", 'r', 0, 0, "Recalculate set on every frame"},
{"output file", 'o', "FILE", 0, "Render to image, default False"},
{"width", 'w', "WIDTH", 0, "Width of window/image, default 640"},
{"height", 'h', "HEIGHT", 0, "Height of window/image, default 480"},
{"iterations", 'i', "ITERATIONS", 0, "Max iterations, default 250."},
{"dont_use_avx", 'x', 0, 0, "NOT use avx for calculations, default False"},
{"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_max", 'b', "VALUE", 0, "X max"},
......@@ -231,6 +233,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
struct arguments *arguments = state->input;
switch (key)
{
case 'i':
arguments->max_iterations = atoi(arg);
break;
case 'o':
arguments->output_file = arg;
break;
......@@ -247,20 +252,20 @@ parse_opt (int key, char *arg, struct argp_state *state)
arguments->use_omp = 0;
break;
case 'r':
arguments->redcalc = 1;
arguments->recalc = 1;
break;
case 'a':
arguments->x_min = atoi(arg);
arguments->x_max = atoi(arg);
break;
case 'b':
arguments->redcalc = atoi(arg);
arguments->x_min = atoi(arg);
break;
case 'c':
arguments->redcalc = atoi(arg);
arguments->y_max= atoi(arg);
break;
case 'd':
arguments->redcalc = atoi(arg);
arguments->y_min= atoi(arg);
break;
case 'z':
arguments->zoom= atof(arg);
......@@ -280,10 +285,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
static struct argp argp = {options, parse_opt, NULL, NULL};
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,
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;
......@@ -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->size = height * width * sizeof(Color);
}
if (needs_recalc){
calculate_set_func(arr, height, width, *view, use_avx);
if (*needs_recalc){
calculate_set_func(arr, height, width, *view, use_avx, max_iterations);
*needs_recalc = 0;
}
......@@ -306,7 +312,7 @@ render_cl(Array *arr, SDL_Texture *texture, SDL_Renderer *renderer, int width, i
short unsigned
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) {
SDL_Surface* surface = SDL_CreateRGBSurface(0,
width, height,
......@@ -329,12 +335,9 @@ render_headless(ViewInfo view, const char* filename,
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;
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);
free(arr.pointer);
......@@ -349,8 +352,8 @@ main(int argc, char **argv)
struct arguments args = {
NULL,
640, 480,
1, 1, 0,
-2.0, 1.0, -1.5, 1.5, 1.0
250, 1, 0,
0,-2.0, 1.0, -1.5, 1.5, 1.0,
};
argp_parse(&argp, argc, argv, 0, 0, &args);
......@@ -370,7 +373,8 @@ main(int argc, char **argv)
if (args.output_file) {
render_headless(view, args.output_file,
args.width, args.height,
args.use_avx, args.use_omp);
args.use_avx, args.use_omp,
args.max_iterations);
SDL_Quit();
return 0;
}
......@@ -388,7 +392,7 @@ main(int argc, char **argv)
SDL_TEXTUREACCESS_STREAMING,
args.width, args.height),
args.height,
args.height,
args.width,
1,
0
};
......@@ -478,8 +482,13 @@ main(int argc, char **argv)
}
default:
//returns one if recalc needed
app.needs_recalc = app.needs_recalc == 0 ? handle_mouse(event, &mouse, &view) : 1;
app.needs_recalc = (app.needs_recalc || args.redcalc);
if (event.type == SDL_MOUSEBUTTONDOWN ||
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;
}
......@@ -489,7 +498,10 @@ main(int argc, char **argv)
SDL_SetRenderDrawColor(app.renderer, 0xff, 0xff, 0xff, 0xff);
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;
float fps = 0;
......
......@@ -6,7 +6,6 @@
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define MAX_ITERATIONS 250
typedef struct {
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