Hello,
I’m working on the procedural terrain and trying to implement a different noise type. The problem I have is with the floats. It seems to work but oddly the color is cycling isntead of 0 to 1. I’m getting 0 to 1, 0 to 1, repeatedly. Basically destryoing the elevation.
Here is the code and a link to the results from it.
en.wikipedia.org/wiki/Diamond-sq … _algorithm
Current results picture.
tinypic.com/view.php?pic=2kotwx&s=8
[code]/// Cold to create noise through the Diamond method. Requires offset and better hash table to create random heightmaps but repeatable
bool Image::generateDiamondMethod1 (float * buffer,const int &width, const int &height, const float &maxYcoords,const float &minYcoords)
{
//an initial seed value for the corners of the data
float SEED = 0.0f;
unsigned int DATA_SIZE=width+1;
float diamond[DATA_SIZE][DATA_SIZE];
//initialise the values of the corners++
diamond[0][0] = SEED;
diamond[0][DATA_SIZE-1] = SEED;
diamond[DATA_SIZE-1][0] = SEED;
diamond[DATA_SIZE-1][DATA_SIZE-1] = SEED;
float h =100.0; //the range (-h -> h) for the average offset
srand(1); //seed the random generator
//side length is the distance of a single square side
//or distance of diagonal in diamond
//each iteration we are looking at smaller squares and diamonds, we decrease the variation of the offset
for (int sideLength = DATA_SIZE-1; sideLength >= 2; sideLength /= 2, h /= 2.0)
{
int halfSide = sideLength/2;
//generate new square values
for(int x=0; x<DATA_SIZE-1; x+=sideLength)
{
for(int y=0; y<DATA_SIZE-1; y+=sideLength)
{
//x,y is upper left corner of the square
//calculate average of existing corners
float avg = diamond[x][y] + //top left
diamond[x+sideLength][y] + //top right
diamond[x][y+sideLength] + //lower left
diamond[x+sideLength][y+sideLength]; //lower right
avg /= 4.0;
//center is average plus random offset in the range (-h, h)
float offset = (-h) + rand() * (h - (-h)) / RAND_MAX;
diamond[x+halfSide][y+halfSide] = avg + offset;
} //for y
} // for x
//Generate the diamond values
//Since diamonds are staggered, we only move x by half side
//NOTE: if the data shouldn't wrap the x < DATA_SIZE and y < DATA_SIZE
for (int x=0; x<DATA_SIZE-1; x+=halfSide)
{
for (int y=(x+halfSide)%sideLength; y<DATA_SIZE-1; y+=sideLength)
{
//x,y is center of diamond
//we must use mod and add DATA_SIZE for subtraction
//so that we can wrap around the array to find the corners
float avg =
diamond[(x-halfSide+DATA_SIZE)%DATA_SIZE][y] + //left of center
diamond[(x+halfSide)%DATA_SIZE][y] + //right of center
diamond[x][(y+halfSide)%DATA_SIZE] + //below center
diamond[x][(y-halfSide+DATA_SIZE)%DATA_SIZE]; //above center
avg /= 4.0;
//new value = average plus random offset
//calc random value in the range (-h,+h)
float offset = (-h) + rand() * (h - (-h)) / RAND_MAX;
avg = avg + offset;
//update value for center of diamond
diamond[x][y] = avg;
//wrap values on the edges
//remove this and adjust loop condition above
//for non-wrapping values
if (x == 0) diamond[DATA_SIZE-1][y] = avg;
if (y == 0) diamond[x][DATA_SIZE-1] = avg;
} //for y
} //for x
} //for sideLength
/// Set maxY and minY to 0.0f
float maxY = diamond[1][1];
float minY = diamond[1][1];
/// Calculate minY and maxY values
for (int x = 0; x<DATA_SIZE-1; x++)
{
for(int y=0; y<DATA_SIZE-1; y++)
{
if (diamond[x][y] > maxY)
maxY = diamond[x][y];
if (diamond[x][y] < minY)
minY = diamond[x][y];
}
}
/// Calculate height from 0 to 1
for(int x=0; x < DATA_SIZE-1; x++)
{
for(int y=0; y < DATA_SIZE-1; y++)
{
//change range to 0..1
diamond[x][y] = (diamond[x][y] - minY) / (maxY - minY);
}
}
/// Copy color float from create texture
for(unsigned x = 0; x<width; x++)
{
for(unsigned y = 0; y<height; y++)
{
/// incremennt memory which seems to work
int index = x+(y*width);
buffer[index]=diamond[x][y];
}
}
return true;
}[/code]
Code to produce output
[code]/// generate perlin output
bool Image::GenerateBuild(float * buffer, unsigned *output)
{
int width=width_;
int height=height_;
int components=components_;
int depth=1;
// loop through all the floats then convert to grayscale setting the color basis to .5 (forcing values 0 to 1)
for(unsigned x = 0; x<width; x++)
{
for(unsigned y = 0; y<height; y++)
{
/// incremennt memory which seems to work
int index = x+(y*height);
unsigned col = buffer[index]* 255; /// create color value
col = rgba32ToUInt(col,col,col, 255);
output[index] = col; /// set grayscale - rgba is not needed. it seems to be screwy with this type of code.
}
}
return true;
}
[/code]