|
|
|
@ -9,16 +9,58 @@
|
|
|
|
|
#include "complex.c"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MB_THREADS 7
|
|
|
|
|
#define MB_THREADS 11
|
|
|
|
|
|
|
|
|
|
typedef struct _mb_settings {
|
|
|
|
|
unsigned int width;
|
|
|
|
|
unsigned int iterations;
|
|
|
|
|
double re_start;
|
|
|
|
|
double re_end;
|
|
|
|
|
double im_start;
|
|
|
|
|
double im_end;
|
|
|
|
|
} MandelbrotSettings;
|
|
|
|
|
|
|
|
|
|
MandelbrotSettings mb_settings_default(int width, int iterations) {
|
|
|
|
|
MandelbrotSettings set;
|
|
|
|
|
set.width = width;
|
|
|
|
|
set.iterations = iterations;
|
|
|
|
|
set.re_start = -2;
|
|
|
|
|
set.re_end = 1;
|
|
|
|
|
set.im_start = -1.25;
|
|
|
|
|
set.im_end = 1.25;
|
|
|
|
|
return set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MandelbrotSettings mb_settings_at_pt(int width, int iterations, double re, double im, double px_step) {
|
|
|
|
|
MandelbrotSettings set;
|
|
|
|
|
set.width = width;
|
|
|
|
|
int height = width;
|
|
|
|
|
set.iterations = iterations;
|
|
|
|
|
set.re_start = re - (width * (0.5 *px_step));
|
|
|
|
|
set.re_end = re + (width * (0.5 *px_step));
|
|
|
|
|
set.im_start = im - (height * (0.5 *px_step));
|
|
|
|
|
set.im_end = im + (height * (0.5 *px_step));
|
|
|
|
|
return set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mb_print_settings(MandelbrotSettings set) {
|
|
|
|
|
printf(
|
|
|
|
|
"Settings: {\n\twidth; %d\n\titerations; %d\n\tre_start; %f\n\tre_end; %f\n\tim_start; %f\n\tim_end; %f\n}\n",
|
|
|
|
|
set.width,
|
|
|
|
|
set.iterations,
|
|
|
|
|
set.re_start,
|
|
|
|
|
set.re_end,
|
|
|
|
|
set.im_start,
|
|
|
|
|
set.im_end
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void draw_mandelbrot(int width, int height, int iterations);
|
|
|
|
|
void draw_mandelbrot_auto(int width, int iterations);
|
|
|
|
|
int test_mandelbrot(Complex c, int iterations);
|
|
|
|
|
void draw_mandelbrot(MandelbrotSettings settings);
|
|
|
|
|
unsigned int test_mandelbrot(Complex c, int iterations);
|
|
|
|
|
void* create_shared_memory(size_t size);
|
|
|
|
|
int image_new_shared(int width, int height, Image* img);
|
|
|
|
|
void image_destroy_shared(Image img);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
|
int width = 3000;
|
|
|
|
|
int iterations = 60;
|
|
|
|
@ -29,24 +71,30 @@ int main(int argc, char* argv[]) {
|
|
|
|
|
iterations = atoi(argv[2]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
draw_mandelbrot_auto(width, iterations);
|
|
|
|
|
}
|
|
|
|
|
double step = (1/ (double) 18) / width;
|
|
|
|
|
|
|
|
|
|
void draw_mandelbrot_auto(int width, int iterations) {
|
|
|
|
|
draw_mandelbrot(width, 2.5f * width / 3, iterations);
|
|
|
|
|
MandelbrotSettings set = mb_settings_at_pt(
|
|
|
|
|
width, iterations, -1, -(2.2/(double)9), step
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mb_print_settings(set);
|
|
|
|
|
|
|
|
|
|
draw_mandelbrot(set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void draw_mandelbrot(int width, int height, int iterations) {
|
|
|
|
|
int center_x = 2 * width / 3;
|
|
|
|
|
int center_y = height / 2;
|
|
|
|
|
float step = 3.0f / width;
|
|
|
|
|
|
|
|
|
|
void draw_mandelbrot(MandelbrotSettings set) {
|
|
|
|
|
double step = (set.re_end - set.re_start) / set.width;
|
|
|
|
|
unsigned int height = (set.im_end - set.im_start) / step;
|
|
|
|
|
|
|
|
|
|
printf("Dimensions: %ux%u (step: %f)\n", set.width, height, step);
|
|
|
|
|
|
|
|
|
|
Image img;
|
|
|
|
|
image_new_shared(width, height, &img);
|
|
|
|
|
image_new_shared(set.width, height, &img);
|
|
|
|
|
|
|
|
|
|
int thread_id = 0;
|
|
|
|
|
unsigned int thread_id = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MB_THREADS - 1; i++) {
|
|
|
|
|
for (unsigned int i = 0; i < MB_THREADS - 1; i++) {
|
|
|
|
|
if (fork() == 0) {
|
|
|
|
|
thread_id = i + 1;
|
|
|
|
|
break;
|
|
|
|
@ -54,20 +102,25 @@ void draw_mandelbrot(int width, int height, int iterations) {
|
|
|
|
|
}
|
|
|
|
|
printf("Thread %i reporting for duty\n", thread_id);
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < width; x++) {
|
|
|
|
|
for (unsigned int x = 0; x < set.width; x++) {
|
|
|
|
|
if (x % MB_THREADS != thread_id) continue;
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
|
if (x % (set.width / 100) == 0) {
|
|
|
|
|
printf("Rendering... %02i%%\r", (int) ((x / (float) set.width) * 100));
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (unsigned int y = 0; y < height; y++) {
|
|
|
|
|
Complex c = complex_new(
|
|
|
|
|
(x - center_x) * step,
|
|
|
|
|
(y - center_y) * step
|
|
|
|
|
set.re_start + (x * step),
|
|
|
|
|
set.im_start + (y * step)
|
|
|
|
|
);
|
|
|
|
|
int ret = test_mandelbrot(c, iterations);
|
|
|
|
|
unsigned int ret = test_mandelbrot(c, set.iterations);
|
|
|
|
|
//int r = (ret * 160 / iterations);
|
|
|
|
|
//int g = (ret * 9 / iterations);
|
|
|
|
|
//int b = (ret * 165 / iterations);
|
|
|
|
|
//image_set_px(img, x, y, r,g,b);
|
|
|
|
|
int color = 255 * sqrt(ret / (float) iterations);
|
|
|
|
|
int color = 255 * sqrt(ret / (float) set.iterations);
|
|
|
|
|
image_set_px(img, x, y, color, color, color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -79,7 +132,6 @@ void draw_mandelbrot(int width, int height, int iterations) {
|
|
|
|
|
|
|
|
|
|
int status;
|
|
|
|
|
for (int i = 0; i < MB_THREADS - 1; i++) {
|
|
|
|
|
printf("Waiting for threads... %d/%d\n", i, MB_THREADS - 1);
|
|
|
|
|
while(wait(&status) > 0) {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -89,7 +141,7 @@ void draw_mandelbrot(int width, int height, int iterations) {
|
|
|
|
|
image_destroy_shared(img);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int test_mandelbrot(Complex c, int iterations) {
|
|
|
|
|
unsigned int test_mandelbrot(Complex c, int iterations) {
|
|
|
|
|
Complex z = complex_new(0,0);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < iterations; i++) {
|
|
|
|
|