Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<SDL/SDL.h>
- #include<iostream>
- #include<math.h>
- void putpixel(SDL_Surface* surface, int x, int y, Uint32 pixel);
- void draw_line(SDL_Surface* scr, int x, int y, int x2, int y2, Uint32 color);
- bool user_quit(SDL_Event &event);
- double mandelbrot_percent(double x, double y, double offset_x, double offset_y,
- int iterations, double zoom);
- int main (int argc, char** argv)
- {
- // grab commandline args for height and width
- if(argc < 3)
- {
- std::cout << "You did not specify width then height" << std::endl;
- return 1;
- }
- int SCREEN_WIDTH = atoi(argv[1]);
- int SCREEN_HEIGHT = atoi(argv[2]);
- // initialize SDL video
- if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
- {
- std::cout << "Unable to init SDL" << SDL_GetError() << "\n" << std::endl;
- return 1;
- }
- // make sure SDL cleans up before exit
- atexit(SDL_Quit);
- // create a new window
- SDL_Surface* screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16,
- SDL_HWSURFACE|SDL_DOUBLEBUF);
- if(!screen)
- {
- printf("Unable to set video mode.\n", SDL_GetError());
- return 1;
- }
- // generate the 'brot
- SDL_LockSurface(screen);
- for(int y = 0; y < SCREEN_HEIGHT; ++y)
- {
- for(int x = 0; x < SCREEN_WIDTH; ++x)
- {
- double p = mandelbrot_percent(x, y, SCREEN_WIDTH/2.0,
- SCREEN_HEIGHT/2.0, 100, SCREEN_HEIGHT/3.14);
- if( p == -1) // -1 means within the set
- {
- putpixel(screen, x, y,0);
- }
- else
- {
- // TODO ensure that p min and p max are accounted for with gradient
- // sometimes the lowerbound of p is never 0 while the upperbound is
- // never the full iterations, this should be fixed later.
- // Ideally a grid should be populated with P values, and the upper
- // and lower should be noted. The gradient band currently assumes
- // that the lowerbound is 0 and upper is iteration max.
- // use sin interpolation to make the bands stretch a bit more
- p = sin(p/100 * 3.1416); // this is set for 100 iterations per pixel
- // match it with the iterations passed into mandelbrot_percent
- // define two mixing colors for area outside
- Uint8 r1,r2,g1,g2,b1,b2;
- r1 = 64;
- g1 = 0;
- b1 = 64;
- r2 = 0;
- g2 = 255;
- b2 = 0;
- // TODO make the gradient fit the upper and lower bounds for the values
- r1 += (r2 - r1) * p;
- g1 += (g2 - g1) * p;
- b1 += (b2 - b1) * p;
- putpixel(screen, x, y,SDL_MapRGB(screen->format,r1, g1, b1));
- }
- }
- }
- SDL_UnlockSurface(screen);
- SDL_Event event;
- while(user_quit(event) == false)
- {
- SDL_Flip(screen);
- }
- return 0;
- }
- bool user_quit(SDL_Event &event)
- {
- SDL_PollEvent(&event);
- switch (event.type)
- {
- case SDL_QUIT:
- return true;
- break;
- case SDL_KEYDOWN:
- {
- if (event.key.keysym.sym == SDLK_ESCAPE)
- return true;
- break;
- }
- default:
- return false;
- }
- }
- void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
- {
- int bpp = surface->format->BytesPerPixel;
- /* Here p is the address to the pixel we want to set */
- Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
- switch(bpp)
- {
- case 1:
- *p = pixel;
- break;
- case 2:
- *(Uint16 *)p = pixel;
- break;
- case 3:
- if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
- {
- p[0] = (pixel >> 16) & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = pixel & 0xff;
- }
- else
- {
- p[0] = pixel & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = (pixel >> 16) & 0xff;
- }
- break;
- case 4:
- *(Uint32 *)p = pixel;
- break;
- }
- }
- double mandelbrot_percent(double x, double y, double offset_x,
- double offset_y, int iterations, double zoom)
- {
- // this function returns -1 if the value is inside the set
- // otherwise returns a fraction if outside
- x -= offset_x;
- y -= offset_y;
- x /= zoom;
- y /= zoom;
- double r = x;
- double s = y;
- double old_r = r;
- double old_s = s;
- // If the position survives this iteration loop it is "inside"
- for(int i = 0; i < iterations + 1; ++i)
- {
- if(r*r + s*s > 4)
- return i; // escaped the set, color it!
- else
- {
- r = (old_r * old_r - old_s * old_s) + x;
- s = 2 * old_r * old_s + y;
- old_r = r;
- old_s = s;
- }
- }
- return -1; // in the set, return -1
- }
Add Comment
Please, Sign In to add comment