Back to Projects

Procedural Infinite Terrain Generator

Previous Pause Next

Time: 8 days
Date: Winter 2012
Tools: C++ and OpenGL
Description:

A procedural terrain generator in which everything is generated from algorithms. The terrain is split up into several different chunks allowing pieces of the terrain to be generated on the fly. The data required for the chunks are generated on a worker thread creating a smooth experience when exploring the terrain. All textures and heightmaps used in this project are generated using a combination of different algorithms, from Worley noise to drawing simple lines.




Grass texture generation class
#include "TextureModuleGrass.h"
#include "../Utility/Random.h"

using namespace TexGen;

TextureModuleGrass::TextureModuleGrass(void)
: TextureModuleBase("ProceduralGrass")
, m_NumberOfGrassIterations(100000)
{
	SetupParameters();
}

TextureModuleGrass::~TextureModuleGrass(void)
{
}

void TextureModuleGrass::DoModuleProcess()
{
	ColorValue green = ColorValue(0.231f, 0.294f, 0.007f, 1.0f);
	ColorValue darkGreen = ColorValue(0.407f, 0.396f, 0.180f, 1.0f);

	//Clear the whole image with a random color between our green and darkGreen color values
	for(int y = 0; y < m_HeightInPixels; ++y)
	{
		for(int x = 0; x < m_WidthInPixels; ++x)
		{
			float colorLerp = Util::Random::Range(0.0f, 1.0f);
			ColorValue resultColor = (green * colorLerp) + (darkGreen * (1.0f - colorLerp));

			SetPixel(x, y, resultColor);
		}
	}

	//Now we 'make' the grass by drawing a number of lines over the texture.
	for(int grassIteration = 0; grassIteration < m_NumberOfGrassIterations; ++grassIteration)
	{
		//We get a random start position
		float startX = Util::Random::Range(0.0f, (float)m_WidthInPixels);
		float startY = Util::Random::Range(0.0f, (float)m_HeightInPixels);

		//A random direction
		float directionX = Util::Random::Range(-1.0f, 1.0f);
		float directionY = Util::Random::Range(-1.0f, 1.0f);
		
		//A length
		int length = Util::Random::Range(2, 10);

		//And a random color
		float colorLerp = Util::Random::Range(0.0f, 1.0f);
		ColorValue grassColor = (green * colorLerp) + (darkGreen * (1.0f - colorLerp));

		for(int step = 0; step < length; ++step)
		{
			//Get the x and y coordinates for our current step.
			int x = (int)(startX + (directionX * (float)step));
			int y = (int)(startY + (directionY * (float)step));

			//Wrap our coordinates around the texture boundaries
			x = x % m_WidthInPixels;
			y = y % m_HeightInPixels;
			while(x < 0)
				x += m_WidthInPixels;
			while(y < 0)
				y += m_HeightInPixels;

			//Plot the pixel color
			SetPixel(x, y, grassColor);
		}
	}
}

void TextureModuleGrass::SetupParameters()
{
	//Register our parameters so we can edit them when the application is running.
	AddParameter("GrassIterations", &m_NumberOfGrassIterations);
}


Back to Projects