[Change] Some needed cleanup in perlin noise stuff.

This commit is contained in:
Allanis 2013-07-12 22:33:03 +01:00
parent 243795e068
commit 40df85b5ab
2 changed files with 24 additions and 52 deletions

View File

@ -9,8 +9,6 @@
#include "perlin.h" #include "perlin.h"
#define NEBULAE_Z 32
#define NOISE_MAX_OCTAVES 128 #define NOISE_MAX_OCTAVES 128
#define NOISE_DEFAULT_HURST 0.5 #define NOISE_DEFAULT_HURST 0.5
#define NOISE_DEFAULT_LACUNARITY 2. #define NOISE_DEFAULT_LACUNARITY 2.
@ -30,15 +28,13 @@ typedef struct {
float exponent[NOISE_MAX_OCTAVES]; float exponent[NOISE_MAX_OCTAVES];
} perlin_data_t; } perlin_data_t;
static float* genNebulaeMap(const int w, const int h, const int n, float rug); static perlin_data_t* noise_new(float hurst, float lacunarity);
SDL_Surface* surfaceFromNebulaeMap(float* map, const int w, const int h);
static noise_t noise_new(float hurst, float lacunarity);
/* Basic perlin noise. */ /* Basic perlin noise. */
static float noise_get(noise_t noise, float* f); static float noise_get(perlin_data_t* pdata, float* f);
/* Fractional brownian motion. */ /* Fractional brownian motion. */
/* Turbulence. */ /* Turbulence. */
static float noise_turbulence(noise_t noise, float* f, float octaves); static float noise_turbulence(perlin_data_t* noise, float* f, float octaves);
static void noise_delete(noise_t noise); static void noise_delete(perlin_data_t* noise);
static float lattice(perlin_data_t* pdata, int ix, float fx, int iy, static float lattice(perlin_data_t* pdata, int ix, float fx, int iy,
float fy, int iz, float fz) { float fy, int iz, float fz) {
@ -58,8 +54,6 @@ static float lattice(perlin_data_t* pdata, int ix, float fx, int iy,
return value; return value;
} }
#define DEFAULT_SEED 0x15687436
#define DELTA 1e-6f
#define SWAP(a, b, t) t = a; a = b; b = t #define SWAP(a, b, t) t = a; a = b; b = t
#define FLOOR(a) ((int) a - (a < 0 && a != (int)a)) #define FLOOR(a) ((int) a - (a < 0 && a != (int)a))
@ -74,7 +68,7 @@ static void normalize(float f[3]) {
f[2] *= magnitude; f[2] *= magnitude;
} }
static noise_t noise_new(float hurst, float lacunarity) { static perlin_data_t* noise_new(float hurst, float lacunarity) {
perlin_data_t* pdata = (perlin_data_t*)calloc(sizeof(perlin_data_t), 1); perlin_data_t* pdata = (perlin_data_t*)calloc(sizeof(perlin_data_t), 1);
int i, j; int i, j;
unsigned char tmp; unsigned char tmp;
@ -102,8 +96,7 @@ static noise_t noise_new(float hurst, float lacunarity) {
return (noise_t)pdata; return (noise_t)pdata;
} }
static float noise_get(noise_t noise, float *f ) { static float noise_get(perlin_data_t* pdata, float *f ) {
perlin_data_t* pdata = (perlin_data_t*)noise;
int n[3]; /* Indexes to pass to lattice function. */ int n[3]; /* Indexes to pass to lattice function. */
float r[3]; /* Remainders 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 w[3]; /* Cubic values to pass to interpolation function. */
@ -121,6 +114,10 @@ static float noise_get(noise_t noise, float *f ) {
w[1] = CUBIC(r[1]); w[1] = CUBIC(r[1]);
w[2] = CUBIC(r[2]); w[2] = CUBIC(r[2]);
/*
* This is the big ugly part that is in dire need
* of optimisation!!!!
*/
value = LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], 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]), lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2]),
w[0]), w[0]),
@ -140,7 +137,7 @@ static float noise_get(noise_t noise, float *f ) {
return CLAMP(-0.99999f, 0.99999f, value); return CLAMP(-0.99999f, 0.99999f, value);
} }
static float noise_turbulence(noise_t noise, float* f, float octaves) { static float noise_turbulence(perlin_data_t* noise, float* f, float octaves) {
float tf[3]; float tf[3];
perlin_data_t* pdata = (perlin_data_t*) noise; perlin_data_t* pdata = (perlin_data_t*) noise;
/* Init locals. */ /* Init locals. */
@ -152,38 +149,34 @@ static float noise_turbulence(noise_t noise, float* f, float octaves) {
tf[2] = f[2]; tf[2] = f[2];
/* Inner loop of spectral construction, where the fractal is built. */ /* Inner loop of spectral construction, where the fractal is built. */
for(i = 0; i < (int)octaves; i++) { for(i = 0; i < octaves; i++) {
value += ABS(noise_get(noise, tf)) * pdata->exponent[i]; value += ABS(noise_get(noise, tf)) * pdata->exponent[i];
tf[0] *= pdata->lacunarity; tf[0] *= pdata->lacunarity;
tf[1] *= pdata->lacunarity; tf[1] *= pdata->lacunarity;
tf[2] *= pdata->lacunarity; tf[2] *= pdata->lacunarity;
} }
/* Take care of remainders in octaves. */
octaves -= (int)octaves;
if(octaves > DELTA)
value += octaves * ABS(noise_get(noise, tf)) * pdata->exponent[i];
return CLAMP(-0.99999f, 0.99999f, value); return CLAMP(-0.99999f, 0.99999f, value);
} }
void noise_delete(noise_t noise) { void noise_delete(perlin_data_t* noise) {
free((perlin_data_t*)noise); free((perlin_data_t*)noise);
} }
/* Generate a 3d nebulae map of dimensions w,h,n with ruggedness rig. */ /* Generate a 3d nebulae map of dimensions w,h,n with ruggedness rig. */
static float* genNebulaeMap(const int w, const int h, const int n, float rug) { float* noise_genNebulaeMap(const int w, const int h, const int n, float rug) {
int x, y, z; int x, y, z;
float f[3]; float f[3];
float octaves; int octaves;
float hurst; float hurst;
float lacunarity; float lacunarity;
noise_t noise; perlin_data_t* noise;
float* nebulae;; float* nebulae;;
float value; float value;
unsigned int* t, s; unsigned int* t, s;
/* Pretty default values. */ /* Pretty default values. */
octaves = 3.; octaves = 3;
hurst = NOISE_DEFAULT_HURST; hurst = NOISE_DEFAULT_HURST;
lacunarity = NOISE_DEFAULT_LACUNARITY; lacunarity = NOISE_DEFAULT_LACUNARITY;
@ -235,7 +228,7 @@ static float* genNebulaeMap(const int w, const int h, const int n, float rug) {
} }
/* Generate an SDL_Surface from a 2d nebulae map. */ /* Generate an SDL_Surface from a 2d nebulae map. */
SDL_Surface* surfaceFromNebulaeMap(float* map, const int w, const int h) { SDL_Surface* noise_surfaceFromNebulaeMap(float* map, const int w, const int h) {
int i; int i;
SDL_Surface* sur; SDL_Surface* sur;
uint32_t* pix; uint32_t* pix;
@ -255,37 +248,13 @@ SDL_Surface* surfaceFromNebulaeMap(float* map, const int w, const int h) {
return sur; return sur;
} }
/* Generate nebulae and save them for late use. */
void noise_generateNebulae(const int w, const int h) {
int i;
float* nebu;
SDL_Surface* sur;
char nebu_file[PATH_MAX];
/* Generate all the nebulae. */
nebu = genNebulaeMap(w, h, NEBULAE_Z, 15.);
/* Save each nebulae as an image. */
for(i = 0; i < NEBULAE_Z; i++) {
sur = surfaceFromNebulaeMap(&nebu[i*w*h], w, h);
snprintf(nebu_file, PATH_MAX, "%s/nebu_%02d.png", lfile_basePath(), i);
SDL_savePNG(sur, nebu_file);
SDL_FreeSurface(sur);
}
/* Cleanup. */
free(nebu);
}
glTexture* noise_genCloud(const int w, const int h, double rug) { glTexture* noise_genCloud(const int w, const int h, double rug) {
float* map; float* map;
SDL_Surface* sur; SDL_Surface* sur;
glTexture* tex; glTexture* tex;
/*noise_generateNebulae(w, h);*/ map = noise_genNebulaeMap(w, h, 1, rug);
sur = noise_surfaceFromNebulaeMap(map, w, h);
map = genNebulaeMap(w, h, 1, rug);
sur = surfaceFromNebulaeMap(map, w, h);
free(map); free(map);
tex = gl_loadImage(sur); tex = gl_loadImage(sur);

View File

@ -1,6 +1,9 @@
#pragma once #pragma once
#include "opengl.h" #include "opengl.h"
void noise_generateNebulae(const int w, const int h); float* noise_genNebulaeMap(const int w, const int h, const int n, float rug);
SDL_Surface* noise_surfaceFromNebulaeMap(float* map, const int w, const int h);
glTexture* noise_genCloud(const int w, const int h, double rug); glTexture* noise_genCloud(const int w, const int h, double rug);