Advertisement
Guest User

Mandlebrot Fractal Animation using SDL2

a guest
Jan 29th, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.11 KB | None | 0 0
  1. /*
  2.     <one line to give the program's name and a brief idea of what it does.>
  3.     Copyright (C) 2015 Bryan Palmer <interruptrequestlevel@gmail.com>
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. //cl /I SDL2\include /I SDL2_ttf\include /MD main.c /link SDL2\lib\x86\SDL2.lib SDL2\lib\x86\SDL2main.lib\SDL2_ttf\lib\x86\SDL2_ttf.lib /SUBSYSTEM:CONSOLE
  20.  
  21. #include "SDL.h"
  22. #include "SDL_TTF.h"
  23.  
  24. #define MANDLEBROT_MAX_ITER 1000
  25. #define INC_AMOUNT 1
  26. #define WIN_WIDTH 1280
  27. #define WIN_HEIGHT 780
  28.  
  29. #define COLOR_THRES_R 0
  30. #define COLOR_THRES_G 2
  31. #define COLOR_THRES_B 16
  32.  
  33. #define COLOR_FACTOR_R 255
  34. #define COLOR_FACTOR_G 16
  35. #define COLOR_FACTOR_B 10
  36.  
  37. #define COLOR_STEP 2
  38.  
  39. #define DEBUG_COLORS 0
  40. #define FULLSCREEN 0
  41.  
  42. #define MAX_FRAMES 25 * 60
  43. #define RENDER_FMT "frames/frame%i.bmp"
  44.  
  45. /* XPM */
  46. static const char *arrow[] = {
  47.   /* width height num_colors chars_per_pixel */
  48.   "    32    32        3            1",
  49.   /* colors */
  50.   "X c #000000",
  51.   ". c #ffffff",
  52.   "  c None",
  53.   /* pixels */
  54.   "X                               ",
  55.   "XX                              ",
  56.   "X.X                             ",
  57.   "X..X                            ",
  58.   "X...X                           ",
  59.   "X....X                          ",
  60.   "X.....X                         ",
  61.   "X......X                        ",
  62.   "X.......X                       ",
  63.   "X........X                      ",
  64.   "X.....XXXXX                     ",
  65.   "X..X..X                         ",
  66.   "X.X X..X                        ",
  67.   "XX  X..X                        ",
  68.   "X    X..X                       ",
  69.   "     X..X                       ",
  70.   "      X..X                      ",
  71.   "      X..X                      ",
  72.   "       XX                       ",
  73.   "                                ",
  74.   "                                ",
  75.   "                                ",
  76.   "                                ",
  77.   "                                ",
  78.   "                                ",
  79.   "                                ",
  80.   "                                ",
  81.   "                                ",
  82.   "                                ",
  83.   "                                ",
  84.   "                                ",
  85.   "                                ",
  86.   "0,0"
  87. };
  88.  
  89. static SDL_Cursor *init_system_cursor(const char *image[])
  90. {
  91.   int i, row, col;
  92.   Uint8 data[4*32];
  93.   Uint8 mask[4*32];
  94.   int hot_x, hot_y;
  95.  
  96.   i = -1;
  97.   for (row=0; row<32; ++row) {
  98.     for (col=0; col<32; ++col) {
  99.       if (col % 8) {
  100.         data[i] <<= 1;
  101.         mask[i] <<= 1;
  102.       } else {
  103.         ++i;
  104.         data[i] = mask[i] = 0;
  105.       }
  106.       switch (image[4+row][col]) {
  107.         case 'X':
  108.           data[i] |= 0x01;
  109.           mask[i] |= 0x01;
  110.           break;
  111.         case '.':
  112.           mask[i] |= 0x01;
  113.           break;
  114.         case ' ':
  115.           break;
  116.       }
  117.     }
  118.   }
  119.   sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
  120.   return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
  121. }
  122.  
  123. int trip_vector = 0;
  124.  
  125. int factorR = COLOR_FACTOR_R;
  126. int factorG = COLOR_FACTOR_G;
  127. int factorB = COLOR_FACTOR_B;
  128.  
  129. void draw_mandlebrot(SDL_Renderer* renderer, int width, int height, double offsetX, double offsetY, double zoom) {
  130.     int pixelY;
  131.     int pixelX;
  132.     int iter;
  133.    
  134.     int thresR = COLOR_THRES_R;
  135.     int thresG = COLOR_THRES_G;
  136.     int thresB = COLOR_THRES_B;
  137.  
  138.     for(pixelY = 0; pixelY < height; pixelY += INC_AMOUNT) {
  139.         for(pixelX = 0; pixelX < width; pixelX += INC_AMOUNT) {
  140.  
  141.             double x0 = (((double)pixelX * 3.5) / (width * zoom)) - (offsetX / zoom);
  142.             double y0 = (((double)pixelY * 2.0) / (height * zoom)) - (offsetY / zoom);
  143.  
  144.             double x = 0;
  145.             double y = 0;
  146.  
  147.             int max_iter = MANDLEBROT_MAX_ITER;
  148.  
  149.             //for(iter = 0;(x*x + y*y < 4.0) && iter < max_iter; iter++) {
  150.             for(iter = 0;(x*x + y*y < 4.0) && iter < max_iter; iter++) {
  151.                 double xtemp = x*x - y*y + x0;
  152.                 y = 2 * x * y + y0;
  153.                 x = xtemp;
  154.             }
  155.  
  156.             /*SDL_Color clrFg = {255,255,255,0};
  157.             SDL_Surface *sText = TTF_RenderText_Solid(font, "Test", clrFg);
  158.             SDL_Texture *txtTexture = SDL_CreateTextureFromSurface(renderer, sText);
  159.            
  160.             SDL_Rect dstRect;
  161.            
  162.             dstRect.x = 10;
  163.             dstRect.y = 10;
  164.             dstRect.w = 100;
  165.             dstRect.h = 20;*/
  166.  
  167.             //SDL_SetRenderDrawColor(renderer, (pixelY % 255) * 255, (pixelX % 255) * 255, 0, 255);
  168.  
  169.             SDL_SetRenderDrawColor(renderer,
  170.                 (iter > 999)?0:((iter > thresR)?(unsigned char)(iter * factorR):0),
  171.                 (iter > 999)?0:((iter > thresG)?(unsigned char)(iter * factorG):0),
  172.                 (iter > 999)?0:((iter > thresB)?(unsigned char)(iter * factorB):0),
  173.                 0);
  174.             //SDL_RenderClear(renderer);
  175.  
  176.             //SDL_RenderCopy(renderer, txtTexture, NULL, &dstRect);
  177.  
  178.             SDL_RenderDrawPoint(renderer, pixelX, pixelY);
  179.         }
  180.     }
  181.    
  182.     /*switch(trip_vector) {
  183.     case 0:
  184.         factorR -= 5;
  185.         if(factorR < 1)
  186.             trip_vector = 1;
  187.         break;
  188.     case 1:
  189.         factorG += 5;
  190.         if(factorG > 254)
  191.             trip_vector = 2;
  192.         break;
  193.     case 2:
  194.         factorG -= 5;
  195.         if(factorG < 1)
  196.             trip_vector = 3;
  197.         break;
  198.     case 3:
  199.         factorB += 5;
  200.         if(factorB > 254)
  201.             trip_vector = 4;
  202.         break;
  203.     case 4:
  204.         factorB -= 5;
  205.         if(factorB < 1)
  206.             trip_vector = 5;
  207.         break;
  208.     case 5:
  209.         factorR += 5;
  210.         if(factorR > 254)
  211.             trip_vector = 0;
  212.         break;
  213.     default:
  214.         break;
  215.     }*/
  216.  
  217.     switch(trip_vector) {
  218.     case 0:
  219.         factorR -= (factorR < 10)?0:COLOR_STEP;
  220.         factorG += (factorG > 254)?0:COLOR_STEP;
  221.         if(factorR < 10)
  222.             trip_vector = 1;
  223.         break;
  224.     case 1:
  225.         factorG -= (factorG < 10)?0:COLOR_STEP;
  226.         factorB += (factorB > 254)?0:COLOR_STEP;
  227.         if(factorG < 10)
  228.             trip_vector = 2;
  229.         break;
  230.     case 2:
  231.         factorB -= (factorB < 10)?0:COLOR_STEP;
  232.         factorR += (factorR > 254)?0:COLOR_STEP;
  233.         if(factorB < 10)
  234.             trip_vector = 0;
  235.         break;
  236.     default:
  237.         break;
  238.     }
  239.  
  240.     SDL_RenderPresent(renderer);
  241. }
  242.  
  243. int main(int argc, char** args)
  244. {
  245.     SDL_Color *palette[MANDLEBROT_MAX_ITER + 1];
  246.     SDL_Window *win;
  247.     SDL_Renderer *renderer;
  248.  
  249.     TTF_Font *font;
  250.  
  251.     int width = WIN_WIDTH;
  252.     int height = WIN_HEIGHT;
  253.    
  254.     double currentX = 1.2;
  255.     double currentY = 1.0;
  256.     double currentZ = 1.0;
  257.    
  258.     double currentXfactor = 0.9;
  259.    
  260.     int iter;
  261.     int frames = 0;
  262.    
  263.     //Start SDL
  264.     SDL_Init(SDL_INIT_VIDEO);
  265.  
  266.     win = SDL_CreateWindow("s2v", 100, 100, width, height, SDL_WINDOW_ALLOW_HIGHDPI | ((FULLSCREEN)?SDL_WINDOW_FULLSCREEN:0));
  267.  
  268.     renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
  269.  
  270.     SDL_ShowCursor(SDL_DISABLE);
  271.  
  272.     TTF_Init();
  273.     font = TTF_OpenFont("arial.ttf", 12);
  274.  
  275.     SDL_SetCursor(init_system_cursor(arrow));
  276.     SDL_ShowCursor(1);
  277.    
  278.     if(DEBUG_COLORS)
  279.         draw_mandlebrot(renderer, width, height, 7.5, 1, 4);
  280.  
  281.     for(iter = 0; frames < MAX_FRAMES; frames++) {
  282.         SDL_Event e;
  283.         if(SDL_PollEvent(&e)) {
  284.             if(e.type == SDL_QUIT) {
  285.                 break;
  286.             }
  287.             /*else if(e.type == SDL_MOUSEBUTTONDOWN) {             
  288.                 if(e.button.button == SDL_BUTTON_LEFT) {
  289.                     currentX = ((e.button.x / (double)width) * 2.5);
  290.                     currentY = (e.button.y / (double)height);
  291.                     draw_mandlebrot(renderer, palette, width, height, currentX, currentY, currentZ);
  292.                 }
  293.             }
  294.             else if(e.type == SDL_MOUSEWHEEL) {
  295.                 currentZ += e.wheel.y;
  296.                 currentX *= currentZ;
  297.                 currentY *= currentZ;
  298.                 draw_mandlebrot(renderer, palette, width, height, currentX, currentY, currentZ);
  299.             }*/
  300.         }
  301.        
  302.         if(/* SDL_GetTicks() % 2 ==  */1 && !DEBUG_COLORS) {
  303.             if(iter == 0 && (currentZ == 1 || currentZ < -30)) {
  304.                 iter = 1;
  305.                 currentXfactor += 0.1;
  306.             } else if(iter == 1 && currentZ > 10)
  307.                 iter = 0;
  308.  
  309.             if(iter) {
  310.                 currentZ += 0.15;
  311.                 currentX += 0.25 * currentXfactor;
  312.             }
  313.             else {
  314.                 currentZ -= 0.15;
  315.                 currentX -= 0.25 * currentXfactor;
  316.             }
  317.             draw_mandlebrot(renderer, width, height, currentX, currentY, currentZ);
  318.            
  319.             {
  320.                 // Create an empty RGB surface that will be used to create the screenshot bmp file
  321.                 SDL_Surface* pScreenShot = SDL_CreateRGBSurface(0, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
  322.  
  323.                 if(pScreenShot)
  324.                 {
  325.                     char *fname = (char *)malloc(256);
  326.                     sprintf(fname, RENDER_FMT, frames);
  327.                     // Read the pixels from the current render target and save them onto the surface
  328.                     SDL_RenderReadPixels(renderer, NULL, SDL_GetWindowPixelFormat(win), pScreenShot->pixels, pScreenShot->pitch);
  329.  
  330.                     // Create the bmp screenshot file
  331.                     SDL_SaveBMP(pScreenShot, fname);
  332.                     free(fname);
  333.  
  334.                     // Destroy the screenshot surface
  335.                     SDL_FreeSurface(pScreenShot);
  336.                 }
  337.             }
  338.         }
  339.     }
  340.  
  341.     TTF_CloseFont(font);
  342.     SDL_DestroyRenderer(renderer);
  343.     SDL_DestroyWindow(win);
  344.    
  345.     //Quit SDL
  346.     TTF_Quit();
  347.     SDL_Quit();
  348.    
  349.     return 0;    
  350. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement