Original Post
I am using Ken Perlin's improved noise, which can be found here http://mrl.nyu.edu/~perlin/noise/ to try and develop my own 3d noise. Right now, I just use the sdl graphics library to view 2d slices of the noise, but to my dismay the noise function always returns a value of just 0 for any location in the noise (meaning that only solid blackness is displayed). I admit I do not quite understand fully what is going on, but I have attempted to basically port his java code to C and view the results in SDL. I do not really see a difference between mine and his code, but I have posted mine below, in case anybody may have a clue what is wrong here. I appreciate any help I can get.
#include <windows.h>
#include <sdl.h>
#include <math.h>
//basic graphic routines
void blit( SDL_Surface*, SDL_Surface*, int, int, int, int, int, int);
void putpixel(SDL_Surface*, int, int, Uint32);
//noise functions
double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); }
double lerp(double t, double a, double b) { return a + t * (b - a); }
double grad(int, double, double, double);
double noise(double, double, double);
//noise tables
int p[512],
permutation[] = { 151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,
142,8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,
203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,
74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,
220,105,92,41,55,46,245,40,244,102,143,54, 65,25,63,161, 1,216,80,73,209,76,
132,187,208, 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,
186, 3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,
206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152, 2,44,154,
163, 70,221,153,101,155,167,43,172,9,129,22,39,253, 19,98,108,110,79,113,
224,232,178,185, 112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,
179,162,241, 81,51,145,235,249,14,239,107,49,192,214, 31,181,199,106,157,
184, 84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,
24,72,243,141,128,195,78,66,215,61,156,180 };
int main( int argc, char* argv[] )
{
//initalizing noise table
for(int i=0; i < 256 ; i++)
p[256+i] = p = permutation;
//create console to output noise for debugging
AllocConsole();
freopen("CONOUT$", "w", stdout );
//initialize and setup SDL to display graphics
int w = 256, h = 256;
SDL_Init ( SDL_INIT_VIDEO ) ;
SDL_Surface* screen = SDL_SetVideoMode ( w , h , 0, SDL_RESIZABLE );
Uint32 color;
double value;
/////////////////////////////////////////////////////////////////////////
//use noise function to display a 2d slice of the 3d noise on screen //
/////////////////////////////////////////////////////////////////////////
SDL_Surface* layer = SDL_CreateRGBSurface( SDL_HWSURFACE, w, h, 32, SDL_GetVideoSurface()->format->Rmask, SDL_GetVideoSurface()->format->Gmask, SDL_GetVideoSurface()->format->Bmask, SDL_GetVideoSurface()->format->Amask );
for( int i = 0; i < w; i++ )
for( int j = 0; j < h; j++ )
{
value = noise(i,j,7);
printf("%f\n",value);
color = SDL_MapRGB( screen->format,value, value, value);
putpixel( layer, i, j, color );
}
blit( layer, screen, 0,0, w, h, 0, 0 );
//basic event loop to keep program checking for quit or exit messages, not too impotant
SDL_Event event;
while(1)
{
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
return 0;
}
}
SDL_Flip( screen );
}
return 0;
}
double grad(int hash, double x, double y, double z)
{
int h = hash & 15;
double u = h<8 ? x : y, v = h<4 ? y : h==12||h==14 ? x : z;
return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
}
double noise(double x, double y, double z)
{
int X = (int)floor(x) & 255, // FIND UNIT CUBE THAT
Y = (int)floor(y) & 255, // CONTAINS POINT.
Z = (int)floor(z) & 255;
x -= floor(x); // FIND RELATIVE X,Y,Z
y -= floor(y); // OF POINT IN CUBE.
z -= floor(z);
double u = fade(x), // COMPUTE FADE CURVES
v = fade(y), // FOR EACH OF X,Y,Z.
w = fade(z);
int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, // HASH COORDINATES OF
B = p[X+1]+Y, BA = p+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS,
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD
grad(p[BA ], x-1, y , z )), // BLENDED
lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS
grad(p[BB ], x-1, y-1, z ))),// FROM 8
lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS
grad(p[BA+1], x-1, y , z-1 )), // OF CUBE
lerp(u, grad(p[AB+1], x , y-1, z-1 ),
grad(p[BB+1], x-1, y-1, z-1 ))));
}
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*pix = pixel;
break;
case 2:
*(Uint16 *)pix = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
pix[0] = (pixel >> 16) & 0xff;
pix[1] = (pixel >> 8) & 0xff;
pix[2] = pixel & 0xff;
} else {
pix[0] = pixel & 0xff;
pix[1] = (pixel >> 8) & 0xff;
pix[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)pix = pixel;
break;
}
}
void blit( SDL_Surface* source, SDL_Surface* target, int xs, int ys, int width, int height, int xt, int yt )
{
SDL_Rect s, t;
s.x = xs;
s.y = ys;
s.w = width;
s.h = height;
t.x = xt;
t.y = yt;
SDL_BlitSurface (source, &s, target, &t );
}