1 #include "sdl_extra.h" 2 #include <stdbool.h> 3 #include <complex.h> 4 5 #define BG_COLOR 0x191919FF 6 #define MAX_IT 500 7 8 #define DEFAULT_WIN_WIDTH 1024 9 #define DEFAULT_WIN_HEIGHT 720 10 11 #define WIDTH 640 12 #define HEIGHT 480 13 14 #define UNHEX(color) \ 15 ((color) >> (8 * 3)) & 0xFF, \ 16 ((color) >> (8 * 2)) & 0xFF, \ 17 ((color) >> (8 * 1)) & 0xFF, \ 18 ((color) >> (8 * 0)) & 0xFF 19 20 #define Re(z) creal(z) 21 #define Im(z) cimag(z) 22 23 float map(float x, float in_min, float in_max, float out_min, float out_max) { 24 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 25 } 26 27 size_t get_iterations(const float complex z0) { 28 size_t it; 29 float complex z = 0.0 + 0.0 * I; 30 31 for(it = 0; (it <= MAX_IT) && (Re(z)*Re(z) + Im(z)*Im(z) <= 4); it++) 32 z = Re(z)*Re(z) - Im(z)*Im(z) + Re(z0) + (2*Re(z)*Im(z) + Im(z0)) * I; 33 34 return it; 35 } 36 37 void render_mandelbrot(int win_w, int win_h, int width, int height, SDL_Renderer *rend) { 38 size_t i, j, it; 39 float complex z0; 40 float fg; 41 for(i = 0; i < width; i++) { 42 for(j = 0; j < height; j++) { 43 z0 = map(i, 0, width, -2.50, 1.50) + map(j, 0, height, -1.00, 1.00) * I; 44 45 it = get_iterations(z0); 46 47 fg = map(it, 0, MAX_IT, 0, 1); 48 uint8_t b = map(sqrt(fg), 0, 1, 0, 255); 49 50 uint32_t color = (b << 24) + (b << 16) + (b << 8) + 0xFF; 51 52 if(it == MAX_IT) { 53 color = (0xFF << 24) + (0x00 << 16) + (0x00 << 8) + 0x00; 54 printf("MAX_IT reached\n"); 55 } 56 57 SDL_SetRenderDrawColor(rend, UNHEX(color)); 58 SDL_RenderDrawPoint(rend, 59 (win_w / 2) - (width / 2) + i, 60 (win_h / 2) - (height / 2) + j); 61 } 62 } 63 } 64 65 int main (int argc, char *argv[]) { 66 SDL_Window *win; 67 SDL_Renderer *rend; 68 SDL_Event event; 69 70 status_t st; 71 bool run = true; 72 int win_w = DEFAULT_WIN_WIDTH, win_h = DEFAULT_WIN_HEIGHT; 73 74 if((st = SDL_setup(&win, &rend)) != OK) { 75 fprintf(stderr, "%s: couldn't initialize SDL2", argv[0]); 76 return st; 77 } 78 79 while(run) { 80 while(SDL_PollEvent(&event)) { 81 switch(event.type) { 82 case SDL_QUIT: 83 run = false; 84 break; 85 case SDL_WINDOWEVENT: 86 switch(event.window.event) { 87 case SDL_WINDOWEVENT_RESIZED: 88 win_w = event.window.data1; 89 win_h = event.window.data2; 90 91 SDL_SetRenderDrawColor(rend, UNHEX(BG_COLOR)); 92 SDL_RenderClear(rend); 93 94 render_mandelbrot(win_w, win_h, 1600, 800, rend); 95 96 SDL_RenderPresent(rend); 97 break; 98 default: break; 99 } 100 default: break; 101 } 102 } 103 104 } 105 106 SDL_cleanup(win, rend); 107 return 0; 108 }