void NoiseGenerator::generatePerlinNoise ( int seed, int width, int height ) {
	this->width = width;
	this->height = height;
	srand(seed);
	
	generatedNoise = getArray();
	
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			generatedNoise[x][y] = 0;
		}
	}
	
	int numOctaves = 8;
	
	float*** octaves = new float**[numOctaves];
	for (int i = 0; i < numOctaves; i++) {
		octaves[i] = new float*[width];
		
		for (int j = 0; j < width; j++) {
			octaves[i][j] = new float[height];
		}
	}
	
	float** baseNoise = generateWhiteNoise();
	
	for (int i = 0; i < numOctaves; i++) {
		octaves[i] = generateSmoothNoise(baseNoise, i);
	}
	
	float amplitude = 1.0f;
	float totalAmplitude = 0.0f;
	float persistence = 0.5f;
	
	for (int i = numOctaves - 1; i >= 0; i--) {
		amplitude *= persistence;
		totalAmplitude += amplitude;
		
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				generatedNoise[x][y] += octaves[i][x][y] * amplitude;
			}
		}
	}
	
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			generatedNoise[x][y] /= totalAmplitude;
		}
	}
}
Exemplo n.º 2
0
bool termite::generatePerlinNoise(FloatMatrix* perlinNoise, const FloatMatrix* baseNoise, int octaveCount,
                         float persistance, bx::AllocatorI* alloc)
{
    int width = baseNoise->width;
    int height = baseNoise->height;

    FloatMatrix* buff = (FloatMatrix*)alloca(sizeof(FloatMatrix)*octaveCount);
    FloatMatrix** smoothNoise = (FloatMatrix**)alloca(sizeof(FloatMatrix*)*octaveCount);
    if (!smoothNoise)
        return false;
    for (int i = 0; i < octaveCount; i++) {
        smoothNoise[i] = new(buff + i) FloatMatrix(alloc);
        generateSmoothNoise(smoothNoise[i], baseNoise, i);
    }

    if (!perlinNoise->create(width, height))
        return false;
    float amplitude = 1.0f;
    float totalAmplitude = 0;

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

        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {
                float f = perlinNoise->get(i, j);
                perlinNoise->set(i, j, f + smoothNoise[octave]->get(i, j)*amplitude);
            }
        }
    }

    // normalize
    int total = width*height;
    for (int i = 0; i < total; i++)
        perlinNoise->mtx[i] /= totalAmplitude;

    for (int i = 0; i < octaveCount; i++)
        smoothNoise[i]->destroy();

    return true;
}
Exemplo n.º 3
0
SDL_Surface* Sprite::generatePerlinNoise(float** baseNoise, int octaveCount)
{
    int width = w;
    int height = h;

    // 3 dimensional container for the 2D slices of noise
    float*** smoothNoises = tbox.giveFloatArray3D(octaveCount, w, h);

    float persistence = 1.1;
 
    // Generate instances of smooth noise, based on the octave
    // They are slices in our 3D "cube". Voxels of sort

    for (int i = 0; i < octaveCount; i++)
    {
        generateSmoothNoise(baseNoise, i, smoothNoises, width, height);
    }

    float** perlinNoise = tbox.giveFloatArray2D(width, height);
    tbox.clearFloatArray2D(perlinNoise, width, height);
    float amplitude = 1.25f;
    float totalAmplitude = 0.0f;

    SDL_Color temp;
    SDL_Surface* out = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0, 0, 0, 0);

    number_of_threads = 8;
    int work_per_thread = floor(float(w) / float(number_of_threads));
    std::vector<boost::thread*> threadContainer;
    threads_ready = 0;

    // Blend all the slices of the noise together into one 2D slice
    // This is multithreaded too. Each thread handles texture slices from some x1 to some x2
    for (int octave = octaveCount - 1; octave >= 0; octave--)
    {
        amplitude *= persistence;
        totalAmplitude += amplitude;
        threads_ready = 0;

        for (int i = 0; i < number_of_threads; i++)
        {
            boost::thread noiseMerger(mergeNoises, amplitude, octave, smoothNoises, perlinNoise, out, i*work_per_thread, (i+1)*work_per_thread, 0, h);
            boost::thread* threadPtr = &noiseMerger;
            threadContainer.push_back(threadPtr);
        }

        fprintf(stderr, "Waiting for threads to finish at octave %d\n", octave);

        while (threads_ready < number_of_threads)
        {
        }

        std::vector<boost::thread*>::iterator iter;
        for (iter = threadContainer.begin(); iter != threadContainer.end(); iter++)
        {
            (*iter)->join();
        }
    }

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

    // Free some memory
    tbox.deleteFloatArray3D(smoothNoises, octaveCount, width);
    
    return out;
}