noise code

4402 단어
// noise



#ifndef _noise_h_
#define _noise_h_
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
float Interpolate(float a,float b,float alpha)
{
	return a + (b-a)*alpha;
}

float* GenEmptyArray(int w, int h)
{
	float *p = (float*)malloc(w*h*sizeof(float));
	memset(p,0,sizeof(float)*w*h);
	return p;
}

inline float* GenWhiteNoise(int w,int h)
{
	srand(1000);
	float *p = GenEmptyArray(w,h);
	for(int i = 0;i < w;i++)
		for(int j = 0; j < h ;j++)
			p[i*w+j] = (rand()%255)/255.0;
	return p;
}

inline float* GenSmoothNoise(float *baseNoise, int w, int h, int octave)
{
	int width = w;
	int height = h;
	float* smoothNoise = GenEmptyArray(w,h);
	int samplePeriod = 1 << octave; // calculates 2 ^ k
	float sampleFrequency = 1.0f / samplePeriod;

	for (int i = 0; i < width; i++)
	{
		//calculate the horizontal sampling indices
		int sample_i0 = (i / samplePeriod) * samplePeriod;
		int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
		float horizontal_blend = (i - sample_i0) * sampleFrequency;

		for (int j = 0; j < height; j++)
		{
			//calculate the vertical sampling indices
			int sample_j0 = (j / samplePeriod) * samplePeriod;
			int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around
			float vertical_blend = (j - sample_j0) * sampleFrequency;

			//blend the top two corners
			float top = Interpolate(baseNoise[sample_i0*width + sample_j0],
				baseNoise[sample_i1* width + sample_j0], horizontal_blend);

			//blend the bottom two corners
			float bottom = Interpolate(baseNoise[sample_i0*width  + sample_j1],
				baseNoise[sample_i1*width + sample_j1], horizontal_blend);

			//final blend
			smoothNoise[i*width + j] = Interpolate(top, bottom, vertical_blend);
		}
	}
	return smoothNoise;
}

inline float* GenPerlinNoise(float* baseNoise,int w,int h, int octaveCount)
{
	int width = w;
	int height = h;

	//float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing
	float **smoothNoise = (float**)malloc(sizeof(float*)*octaveCount);

	float persistance = 0.5f;

	//generate smooth noise
	for (int i = 0; i < octaveCount; i++)
	{
		smoothNoise[i] = GenSmoothNoise(baseNoise,width,height, i);
	}

	float* perlinNoise = GenEmptyArray(width, height);
	float amplitude = 1.0f;
	float totalAmplitude = 0.0f;

	//blend noise together
	for (int octave = octaveCount - 1; octave >= 0; octave--)
	{
		amplitude *= persistance;
		totalAmplitude += amplitude;

		for (int i = 0; i < width; i++)
		{
			for (int j = 0; j < height; j++)
			{
				perlinNoise[i*width + j] += smoothNoise[octave][i*width + j] * amplitude;
			}
		}
	}

	//normalisation
	for (int i = 0; i < width; i++)
	{
		for (int j = 0; j < height; j++)
		{
			perlinNoise[i*width + j] /= totalAmplitude;
		}
	}

	//------------------------------------------
	// some clean work
	for(int i = 0; i < octaveCount;i++)
	{
		free(smoothNoise[i]);
	}
	free(smoothNoise);
	//------------------------------------------

	return perlinNoise;
}

#endif

//cpp
#include "noise.h"
#include"tga.h"
#define p_size 512
int main()
{
    float *baseNoise = GenWhiteNoise(p_size,p_size);
    float *perlinNoise = GenPerlinNoise(baseNoise,p_size,p_size,8);
    unsigned char* b = (unsigned char*)malloc(p_size*p_size*3);
    for(int i = 0;i < p_size*p_size;i++)
    {
        b[i*3] = b[i*3+1] = b[i*3+2] = perlinNoise[i]*255;
        //if(b[i] > 255) b[i] = 255;
    }
    
    Tga tga;
    tga.loadRawRGB24(b,p_size,p_size);
    free(b);
    free(perlinNoise);
    free(baseNoise);
    tga.saveAsTga("d:\\demoo.tga");


}

좋은 웹페이지 즐겨찾기