Hello, All.
So, I been working on the code. The design of it replicates libnoise. I have to addition select transition like libnoise, cell noise, and less intensive computation. I am posting the code so maybe something has a faster solution for the loops.
The GenerateSelectBuild(…) selects the perlin. It should act more like libnoise.sourceforge.net/tutoria … rial5.html.
Anyway, I would love feedback.
Vivienne
Image.h
/// GeneratePerlin
unsigned rgba32ToUInt(unsigned r, unsigned g, unsigned b, unsigned a);
bool GenerateProcedural(const int &width, const int &height,const unsigned &octaves,
const float &o1,
const float &o2,
const float &o3,
const float &o4,
const float &o5,
const float &o6,
const float &o7,
const float &o8);
float * GenerateSelectBuild(float * inputdata1, float * inputdata2, float *controldata1);
unsigned int * GenerateBuild(float * buffer);
void generatePerlinNoise1( float * buffer,
unsigned width,
unsigned height,
unsigned octaves,
float xOffset,
float yOffset,
float zOffset,
int xWrap,
int yWrap,
int zWrap,
float o1,
float o2,
float o3,
float o4,
float o5,
float o6,
float o7,
float o8);
void CopyData(const unsigned char* pixelData);[/code]
Image.Cpp
[code]
bool Image::GenerateProcedural(const int &width, const int &height,const unsigned &octaves,
const float &o1,
const float &o2,
const float &o3,
const float&o4,
const float &o5,
const float &o6,
const float &o7,
const float &o8)
{
/// Create a pointer location for pixelData
unsigned char* pixelData; /// data location of final output
unsigned int* perlinOutput; /// final perlin output
float * perlininput1; /// perlininput11
float * perlininput2; /// perlininput11
float * controlinput1; /// perlininput11
float * controloutput1; /// perlininput11
unsigned int components=4;
unsigned int depth=1;
/// calculate memory needed to match pixelData and perlininput1
unsigned int dataSize = width*height*width;
/// Allocate perlininput1
perlininput1 = ( float *) malloc(dataSize);
perlininput2 = ( float *) malloc(dataSize);
controlinput1 = ( float *) malloc(dataSize);
controloutput1= ( float *) malloc(dataSize);
perlinOutput = (unsigned int *) malloc(dataSize);
/// Set Size components of the image
SetSize(width, height, 1, components);
/// Generate noise - Currently 8 octaves
generatePerlinNoise1(perlininput1,width,height,2,0.0f,0.0f,0.0f,0,0,0,o1,o2,o3,o4,o5,o6,o7,o8);
/// Generate noise - Currently 8 octaves
generatePerlinNoise1(perlininput2,width,height,7,0.0f,0.0f,0.0f,0,0,0,0.3f,0.6f,o3,o4,o5,o6,o7,o8);
/// Generate noise - Currently 8 octaves
generatePerlinNoise1(controlinput1,width,height,2,0.0f,0.0f,0.0f,0,0,0,0.4f,0.4f,o3,o4,o5,o6,o7,o8);
/// Produce Output
controloutput1=GenerateSelectBuild(perlininput1,perlininput2,controlinput1);
perlinOutput=GenerateBuild(controloutput1);
/// Point pixelData to perlininput1 memory
pixelData = (unsigned char *) perlinOutput;
/// Set image size
CopyData(pixelData);
/// Free Memory
FreeImageData(pixelData);
// free up memory
free(perlininput1);
free(perlininput2);
free(controlinput1);
free(controloutput1);
return true;
}
unsigned Image::rgba32ToUInt(unsigned r, unsigned g, unsigned b, unsigned a)
{
return (r&255) + ((g&255) << 8) + ((b&255) << 16) + ((a&255) << 24);
}
///
void Image::generatePerlinNoise1(
float * buffer,
unsigned width,
unsigned height,
unsigned octaves,
float xOffset,
float yOffset,
float zOffset,
int xWrap,
int yWrap,
int zWrap,
float o1,
float o2,
float o3,
float o4,
float o5,
float o6,
float o7,
float o8
)
{
float mag[] = {o1, o2, o3, o4, o5, o6, o7, o8};
// allocate memory
float * tempdata_;
tempdata_ = (float *) malloc (width*height*width);
/// set range keeping scale
float NewMax = 1.0f;
float NewMin = 0.0f;
float NewRange = (NewMax - NewMin);
float lowfloat=0;
float highfloat=0;
for (unsigned o = 0; o<octaves; o++)
{
float oSize = (o+1) << o;
float oxDiv = oSize / width;
float oyDiv = oSize / height;
for(unsigned x = 0; x<width; x++)
{
for(unsigned y = 0; y<height; y++)
{
// scale perlin based on octave size
float hx = (float)x / (float)width;
float hy = (float)y / (float)height;
float noise = stb_perlin_noise3(x*oxDiv,y*oyDiv,zOffset,xWrap,yWrap,zWrap);
int index = x+y*width;
noise *= mag[o];
if(o)
{
// Add additinal noise
// Determine high point and low point
tempdata_[index]= tempdata_[index]+noise;
if(tempdata_[index]>highfloat)
{
highfloat=tempdata_[index];
}
if(tempdata_[index]<lowfloat)
{
lowfloat=tempdata_[index];
}
}
else
{
//Set initial noise
//Set high and low point
tempdata_[index]= noise;
if(tempdata_[index]>highfloat)
{
highfloat=tempdata_[index];
}
if(tempdata_[index]<lowfloat)
{
lowfloat=tempdata_[index];
}
}
}
}
}
// Set range
float OldRange = (highfloat-lowfloat);
/// loop through all the values then scale down by number of octaves
for(unsigned x = 0; x<width; x++)
{
for(unsigned y = 0; y<height; y++)
{
int index = x+y*width;
// slower but scales the value range from 0.0f to 1.0f
tempdata_[index]= (((tempdata_[index] - lowfloat) * NewRange) / OldRange) + NewMin;
}
}
// copy memory
memcpy (buffer, tempdata_, width*height*width);
/// free memory
free(tempdata_);
return;
}
/// generate perlin output
unsigned int * Image::GenerateBuild(float * buffer)
{
int width=width_;
int height=height_;
int components=components_;
int depth=1;
// create new memory
unsigned * output_;
output_ = (unsigned int *) malloc (width*height*width);
// 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*width;
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 output_;
}
/// generate perlin select
float * Image::GenerateSelectBuild(float * inputdata1, float * inputdata2, float *controldata1)
{
int width=width_;
int height=height_;
int components=components_;
int depth=1;
// create new memory
float * output_;
output_ = (float *) malloc (width*height*width);
// 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*width;
if((controldata1[index]-.5)<0)
{
output_[index]=inputdata1[index];
}else
{
output_[index]=inputdata2[index]*.7;
}
}
}
return output_;
}[/code]
Terrain.cpp
[code]bool Terrain::GenerateProceduralHeightMap()
{
/// Generate Image
Image * perlinimage = new Image(context_);
bool success = false;
///// Create Image
if(!perlinimage->GenerateProcedural(1024,1024,3,0.1f,0.1f,0.1f,0.4f,0.1f,0.2f,0.2f,0.2f))
{
return false;
}
perlinimage->SavePNG(String("/media/home2/vivienne/Existence/Bin/test.png"));
success = SetHeightMapInternal(perlinimage, true);
return success;
}
[/code]
terrain.h
[code] /// Load Terrain Using libnoise
bool GenerateProceduralHeightMap();