8 struct SDL_Surface *screen;
9 long double origo_x, origo_y;
10 int motion_x, motion_y;
16 static void putpixel(struct SDL_Surface *screen, const int x, const int y,
17 const unsigned char r, const unsigned char g,
18 const unsigned char b)
20 int offset = y * screen->pitch + x * 4;
21 unsigned char *buf = screen->pixels;
28 #define MAX_ITERATION 1000
30 int get_mandelbrot_iterations(long double x0, long double y0)
32 long double x = 0, y = 0, xtemp;
35 while ((x * x + y * y < 2 * 2) && iteration < MAX_ITERATION) {
37 xtemp = x * x - y * y + x0;
47 int draw_mandelbrot(struct SDL_Surface *screen, long double x1, long double x2,
48 long double y1, long double y2)
50 long double x0, y0, xlen, ylen, xstep, ystep;
51 int iteration, xs, ys;
55 xstep = xlen / (long double)screen->w;
56 ystep = ylen / (long double)screen->h;
59 #pragma omp parallel for private(xs, ys, x0, y0)
60 for (ys = 0; ys < screen->h; ys++) {
63 for (xs = 0; xs < screen->w; xs++) {
64 iteration = get_mandelbrot_iterations(x0, y0);
66 if (iteration == MAX_ITERATION)
67 putpixel(screen, xs, ys, 255, 255, 255);
69 putpixel(screen, xs, ys,
70 iteration * 8, iteration,
80 static int read_events(struct context *ctx)
83 int wait = 1, ret, exit = 0, delayed_exit = 0;
87 SDL_WaitEvent(&event);
90 ret = SDL_PollEvent(&event);
99 switch (event.key.keysym.sym) {
107 switch (event.key.keysym.sym) {
112 case SDL_MOUSEBUTTONDOWN:
113 if (event.button.button == 4) {
117 } else if (event.button.button == 5) {
122 ctx->scroll_enabled = 1;
125 case SDL_MOUSEBUTTONUP:
126 ctx->scroll_enabled = 0;
129 case SDL_MOUSEMOTION:
130 if (!ctx->scroll_enabled)
133 ctx->motion_x -= event.motion.xrel;
134 ctx->motion_y -= event.motion.yrel;
137 case SDL_VIDEORESIZE:
139 SDL_SetVideoMode(event.resize.w,
152 printf("\nExiting. Good bye!\n");
156 static void loop(struct context *ctx)
158 long double aspect_ratio;
159 long double x1, x2, y1, y2;
162 aspect_ratio = ctx->screen->w / ctx->screen->h;
163 ctx->origo_x += ctx->motion_x / ctx->zoom / ctx->screen->w;
164 ctx->origo_y += ctx->motion_y / ctx->zoom / ctx->screen->h;
165 ctx->motion_x = ctx->motion_y = 0;
167 x1 = ctx->origo_x - aspect_ratio / ctx->zoom;
168 x2 = ctx->origo_x + aspect_ratio / ctx->zoom;
169 y1 = ctx->origo_y - 1 / ctx->zoom;
170 y2 = ctx->origo_y + 1 / ctx->zoom;
171 printf("Drawing area (%f, %f)(%f, %f), zoom %d\n",
172 x1, y1, x2, y2, ctx->zooms);
173 draw_mandelbrot(ctx->screen, x1, x2, y1, y2);
174 } while (!read_events(ctx));
177 int main(int argc, char *argv[])
180 int flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_RESIZABLE;
181 int xres = 800, yres = 600;
183 memset(&ctx, 0, sizeof(ctx));
186 if (SDL_Init(SDL_INIT_VIDEO) != 0) {
187 fprintf(stderr, "Unable to initialize SDL: %s\n",
194 ctx.screen = SDL_SetVideoMode(xres, yres, 32, flags);
195 if (ctx.screen == NULL) {
196 fprintf(stderr, "Unable to set video mode: %s\n",
201 SDL_WM_SetCaption(argv[0], NULL);