#include "SDL.h" #include "log.h" #include "rng.h" #include "opengl.h" #include "plasmaf.h" static double* pf_genFractalMap(const int w, const int h, double rug); static void pf_divFractal(double* map, const double x, const double y, const double w, const double h, const double rw, const double rh, double c1, double c2, double c3, double c4, double rug); /* Acutally generate the fractal and loads it up in an opengl texture. */ glTexture* pf_genFractal(const int w, const int h, double rug) { int i; double* map; SDL_Surface* sur; uint32_t* pix; glTexture* tex; double c; map = pf_genFractalMap(w, h, rug); sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBAMASK); pix = sur->pixels; /* Convert from mapping to actual colours. */ SDL_LockSurface(sur); for(i = 0; i < h*w; i++) { c = map[i]; pix[i] = RMASK + BMASK + GMASK + (AMASK & (uint32_t)(AMASK*c)); } SDL_UnlockSurface(sur); free(map); tex = gl_loadImage(sur); return tex; } static double* pf_genFractalMap(const int w, const int h, double rug) { double* map; /* We'll use it to map out the fractal before saving. */ double cx, cy; map = malloc(w*h * sizeof(double)); if(map == NULL) { WARN("Out of memory"); return NULL; } /* Set up initial values. */ cx = (double)w/2; cy = (double)h/2; /* Start by doing the four squares. */ pf_divFractal(map, 0, 0, cx, cy, w, h, 0., 0., 1., 0., rug); pf_divFractal(map, cx, 0, cx, cy, w, h, 0., 0., 0., 1., rug); pf_divFractal(map, cx, cy, cx, cy, w, h, 1., 0., 0., 0., rug); pf_divFractal(map, 0, cy, cx, cy, w, h, 0., 1., 0., 0., rug); return map; } static void pf_divFractal(double* map, const double x, const double y, const double w, const double h, const double rw, const double rh, double c1, double c2, double c3, double c4, double rug) { double nw, nh; /* New dimensions. */ double m, e1, e2, e3, e4; /* Middle and edges. */ /* Still need to subdivide. */ if((w>1.) || (h>1.)) { /* Calculate new dimensions. */ nw = w/2.; nh = h/2.; /* Edges. */ m = (c1 + c2 + c3 + c4)/4.; e1 = (c1 + c2)/2.; e2 = (c2 + c3)/2.; e3 = (c3 + c4)/2.; e4 = (c4 + c1)/2.; /* Now change the middle colour. */ /*DEBUG("%f + %f", m, rug*(RNGF()-0.5) * ((nw+nh)/(rw+rh)*1000)); */ m += rug*(RNGF()-0.5)*((nw+nh)/(rw+rh)*3.); if(m < 0.) m = 0.; else if(m>1.) m = 1.; /* Recursivation. */ pf_divFractal(map, x, y, nw, nh, rw, rh, c1, e1, m, e4, rug); pf_divFractal(map, x+nw, y, nw, nh, rw, rh, e1, c2, e2, m, rug); pf_divFractal(map, x+nw, y+nh, nw, nh, rw, rh, m, e2, c3, e3, rug); pf_divFractal(map, x, y+nh, nw, nh, rw, rh, e4, m, e3, c4, rug); } else /* Actually write the pixel. */ map[(int)y*(int)rw + (int)x] = (c1 + c2 + c3 + c4)/4.; }