Permalink
Fetching contributors…
Cannot retrieve contributors at this time
127 lines (94 sloc) 3.01 KB
/*
* See Licensing and Copyright notice in naev.h
*/
#include "plasmaf.h"
#include "naev.h"
#include "math.h"
#include "SDL.h"
#include "log.h"
#include "rng.h"
#include "opengl.h"
/*
* prototypes
*/
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 );
/*
* actually generates 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, 0 );
return tex;
}
/*
* generates a map representing the fractal
*/
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 */
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.;
}