diff --git a/src/perlin.c b/src/perlin.c index 72bbb08..12f4043 100644 --- a/src/perlin.c +++ b/src/perlin.c @@ -2,10 +2,6 @@ #include #include -#ifdef __SSE__ -#include -#endif /* __SSE__ */ - #include "lephisto.h" #include "log.h" #include "rng.h" @@ -16,7 +12,6 @@ #define NEBULAE_Z 32 #define NOISE_MAX_OCTAVES 128 -#define NOISE_MAX_DIMENSIONS 4 #define NOISE_DEFAULT_HURST 0.5 #define NOISE_DEFAULT_LACUNARITY 2. @@ -27,71 +22,40 @@ typedef void* noise_t; /* Used internally. */ typedef struct { - int ndim; - unsigned char map[256]; /* Randomized map of indexes into buffer. */ - float buffer[256][NOISE_MAX_DIMENSIONS]; // Random 256 x ndim buffer. */ + unsigned char map[256]; /* Randomized map of indexes into buffer. */ + float buffer[256][3]; /* Random 256x3 buffer. */ /* Fractal stuff. */ float H; float lacunarity; float exponent[NOISE_MAX_OCTAVES]; -} perling_data_t; +} perlin_data_t; static float* genNebulaeMap(const int w, const int h, const int n, float rug); SDL_Surface* surfaceFromNebulaeMap(float* map, const int w, const int h); -static noise_t noise_new(int dimensions, float hurst, float lacunarity); +static noise_t noise_new(float hurst, float lacunarity); /* Basic perlin noise. */ static float noise_get(noise_t noise, float* f); /* Fractional brownian motion. */ -/*static float noise_fbm(noise_t noise, float* f, float octaves);*/ /* Turbulence. */ static float noise_turbulence(noise_t noise, float* f, float octaves); static void noise_delete(noise_t noise); -static float lattice(perling_data_t* pdata, int ix, float fx, int iy, - float fy, int iz, float fz, int iw, float fw) { -#ifdef __SSE__ - (void)iw; - (void)fw; +static float lattice(perlin_data_t* pdata, int ix, float fx, int iy, + float fy, int iz, float fz) { + int nindex; - __m128 a, b, c; - + float value; + nindex = 0; nindex = pdata->map[(nindex + ix) & 0xFF]; nindex = pdata->map[(nindex + iy) & 0xFF]; nindex = pdata->map[(nindex + iz) & 0xFF]; - float inp_sse1[4] __attribute__((aligned(16))) = { - pdata->buffer[nindex][0], - pdata->buffer[nindex][1], - pdata->buffer[nindex][2], - 0. - }; - float inp_sse2[4] __attribute__ ((aligned(16))) = { - fx, fy, fz, 0. - }; - float out_sse[4] __attribute__((aligned(16))); - - a = _mm_load_ps(inp_sse1); - b = _mm_load_ps(inp_sse2); - c = _mm_mul_ps(a, b); - _mm_store_ps(out_sse, c); - - return out_sse[0] + out_sse[1] + out_sse[2]; - -#else /* __SSE__ */ - int n[4] = { ix, iy, iz, iw }; - float f[4] = { fx, fy, fz, fw }; - int nindex = 0; - int i; - float value = 0; - - for(i = 0; i < pdata->ndim; i++) - nindex = pdata->map[(nindex + n[i]) & 0xFF]; - for(i = 0; i < pdata->ndim; i++) - value += pdata->buffer[nindex][i] * f[i]; + value = pdata->buffer[nindex][0] * fx; + value += pdata->buffer[nindex][1] * fy; + value += pdata->buffer[nindex][2] * fz; return value; -#endif /* __SSE__ */ } #define DEFAULT_SEED 0x15687436 @@ -101,27 +65,26 @@ static float lattice(perling_data_t* pdata, int ix, float fx, int iy, #define FLOOR(a) ((int) a - (a < 0 && a != (int)a)) #define CUBIC(a) (a * a * (3 - 2 * a)) -static void normalize(perling_data_t* pdata, float* f) { - float magnitude = 0; - int i; - for(i = 0; i < pdata->ndim; i++) - magnitude += f[i] * f[i]; - magnitude = 1 / sqrtf(magnitude); - for(i = 0; i < pdata->ndim; i++) - f[i] *= magnitude; +static void normalize(float f[3]) { + float magnitude; + + magnitude = 1. / sqrtf(f[0]*f[0] + f[1]*f[1] + f[2]*f[2]); + f[0] *= magnitude; + f[1] *= magnitude; + f[2] *= magnitude; } -static noise_t noise_new(int ndim, float hurst, float lacunarity) { - perling_data_t* pdata=(perling_data_t*)calloc(sizeof(perling_data_t), 1); +static noise_t noise_new(float hurst, float lacunarity) { + perlin_data_t* pdata = (perlin_data_t*)calloc(sizeof(perlin_data_t), 1); int i, j; unsigned char tmp; float f = 1; - pdata->ndim = ndim; for(i = 0; i < 256; i++) { - pdata->map[i] = (unsigned char) i; - for(j = 0; j < pdata->ndim; j++) - pdata->buffer[i][j] = RNGF()-0.5; - normalize(pdata, pdata->buffer[i]); + pdata->map[i] = (unsigned char)i; + pdata->buffer[i][0] = RNGF()-0.5; + pdata->buffer[i][1] = RNGF()-0.5; + pdata->buffer[i][2] = RNGF()-0.5; + normalize(pdata->buffer[i]); } while(--i) { @@ -132,133 +95,68 @@ static noise_t noise_new(int ndim, float hurst, float lacunarity) { pdata->H = hurst; pdata->lacunarity = lacunarity; for(i = 0; i < NOISE_MAX_OCTAVES; i++) { - /*exponent[i] = powf(f, -H); */ - pdata->exponent[i] = 1.0f / f; + /*exponent[i] = powf(f, -H);*/ + pdata->exponent[i] = 1. / f; f *= lacunarity; } return (noise_t)pdata; } -static float noise_get(noise_t noise, float *f ) -{ - perling_data_t* pdata = (perling_data_t*) noise; - int n[NOISE_MAX_DIMENSIONS]; /* Indexes to pass to lattice function */ - int i; - float r[NOISE_MAX_DIMENSIONS]; /* Remainders to pass to lattice function */ - float w[NOISE_MAX_DIMENSIONS]; /* Cubic values to pass to interpolation function */ - float value; +static float noise_get(noise_t noise, float *f ) { + perlin_data_t* pdata = (perlin_data_t*)noise; + int n[3]; /* Indexes to pass to lattice function. */ + float r[3]; /* Remainders to pass to lattice function. */ + float w[3]; /* Cubic values to pass to interpolation function. */ + float value; - for(i=0; indim; i++) { - n[i] = FLOOR(f[i]); - r[i] = f[i] - n[i]; - w[i] = CUBIC(r[i]); - } + n[0] = FLOOR(f[0]); + n[1] = FLOOR(f[1]); + n[2] = FLOOR(f[2]); - switch(pdata->ndim) { - case 1: - value = LERP(lattice(pdata,n[0], r[0],0,0,0,0,0,0), - lattice(pdata,n[0]+1, r[0]-1,0,0,0,0,0,0), - w[0]); - break; - case 2: - value = LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1],0,0,0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1],0,0,0,0), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1,0,0,0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1,0,0,0,0), - w[0]), - w[1]); - break; - case 3: - value = LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2],0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2],0,0), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2],0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2],0,0), - w[0]), - w[1]), - LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1,0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1,0,0), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), - w[0]), - w[1]), - w[2]); - break; - case 4: - default: - value = LERP(LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2], n[3], r[3]), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2], n[3], r[3]), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2], n[3], r[3]), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2], n[3], r[3]), - w[0]), - w[1]), - LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1, n[3], r[3]), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1, n[3], r[3]), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1, n[3], r[3]), - w[0]), - w[1]), - w[2]), - LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2], n[3]+1, r[3]-1), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2], n[3]+1, r[3]-1), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2], n[3]+1, r[3]-1), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2], n[3]+1, r[3]-1), - w[0]), - w[1]), - LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1, n[3]+1, r[3]-1), - lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1, n[3]+1, r[3]-1), - w[0]), - LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), - lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1, n[3]+1, r[3]-1), - w[0]), - w[1]), - w[2]), - w[3]); - break; - } + r[0] = f[0] - n[0]; + r[1] = f[1] - n[1]; + r[2] = f[2] - n[2]; + + w[0] = CUBIC(r[0]); + w[1] = CUBIC(r[1]); + w[2] = CUBIC(r[2]); + + value = LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2]), + lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2]), + w[0]), + LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2]), + lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2]), + w[0]), + w[1]), + LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1), + lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1), + w[0]), + LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1), + lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1), + w[0]), + w[1]), + w[2]); + return CLAMP(-0.99999f, 0.99999f, value); } -#if 0 -float noise_fbm(noise_t noise, float* f, float octaves) { - float tf[NOISE_MAX_DIMENSIONS]; - perling_data_t* pdata = (perling_data_t*) noise; - /* Init locals. */ - float value = 0; - int i, j; - memcpy(tf, f, sizeof(float) * pdata->ndim); - - /* Inner loop for spectral construction, where the fractal is build. */ - for(i = 0; i < (int)octaves; i++) { - value += noise_get(noise, tf) * pdata->exponent[i]; - for(j = 0; j < pdata->ndim; j++) tf[j] *= pdata->lacunarity; - } - - /* Take care of remainder in octaves. */ - octaves -= (int)octaves; - if(octaves > DELTA) - value += octaves * noise_get(noise, tf) * pdata->exponent[i]; - return CLAMP(-0.99999f, 0.99999f, value); -} -#endif - static float noise_turbulence(noise_t noise, float* f, float octaves) { - float tf[NOISE_MAX_DIMENSIONS]; - perling_data_t* pdata = (perling_data_t*) noise; + float tf[3]; + perlin_data_t* pdata = (perlin_data_t*) noise; /* Init locals. */ float value = 0; - int i, j; - memcpy(tf, f, sizeof(float) * pdata->ndim); + int i; + + tf[0] = f[0]; + tf[1] = f[1]; + tf[2] = f[2]; /* Inner loop of spectral construction, where the fractal is built. */ for(i = 0; i < (int)octaves; i++) { value += ABS(noise_get(noise, tf)) * pdata->exponent[i]; - for(j = 0; j < pdata->ndim; j++) tf[j] *= pdata->lacunarity; + tf[0] *= pdata->lacunarity; + tf[1] *= pdata->lacunarity; + tf[2] *= pdata->lacunarity; } /* Take care of remainders in octaves. */ @@ -269,7 +167,7 @@ static float noise_turbulence(noise_t noise, float* f, float octaves) { } void noise_delete(noise_t noise) { - free((perling_data_t*)noise); + free((perlin_data_t*)noise); } /* Generate a 3d nebulae map of dimensions w,h,n with ruggedness rig. */ @@ -290,7 +188,7 @@ static float* genNebulaeMap(const int w, const int h, const int n, float rug) { lacunarity = NOISE_DEFAULT_LACUNARITY; /* Create noiuse and data. */ - noise = noise_new(2, hurst, lacunarity); + noise = noise_new(hurst, lacunarity); nebulae = malloc(sizeof(float)*w*h*n); if(nebulae == NULL) { diff --git a/src/plasmaf.c b/src/plasmaf.c index 3a6bda9..6d8b74b 100644 --- a/src/plasmaf.c +++ b/src/plasmaf.c @@ -22,7 +22,7 @@ glTexture* pf_genFractal(const int w, const int h, double rug) { map = pf_genFractalMap(w, h, rug); - sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBMASK); + sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBAMASK); pix = sur->pixels; /* Convert from mapping to actual colours. */