Libnoise producing completely random noise
- by Doodlemeat
I am using libnoise in C++ taken and I have some problems with getting coherent noise. I mean, the noise produced now are completely random and it doesn't look like a noise.
Here's a to the image produced by my game.
I am diving the map into several chunks, but I can't seem to find any problem doing that since libnoise supports tileable noise. The code can be found below.
Every chunk is 8x8 tiles large. Every tile is 64x64 pixels.
I am also providing a link to download the entire project. It was made in Visual Studio 2013. Download link
This is the code for generating a chunk
Chunk *World::loadChunk(sf::Vector2i pPosition)
{
sf::Vector2i chunkPos = pPosition;
pPosition.x *= mChunkTileSize.x;
pPosition.y *= mChunkTileSize.y;
sf::FloatRect bounds(static_cast<sf::Vector2f>(pPosition), sf::Vector2f(static_cast<float>(mChunkTileSize.x), static_cast<float>(mChunkTileSize.y)));
utils::NoiseMap heightMap;
utils::NoiseMapBuilderPlane heightMapBuilder;
heightMapBuilder.SetSourceModule(mNoiseModule);
heightMapBuilder.SetDestNoiseMap(heightMap);
heightMapBuilder.SetDestSize(mChunkTileSize.x, mChunkTileSize.y);
heightMapBuilder.SetBounds(bounds.left, bounds.left + bounds.width - 1, bounds.top, bounds.top + bounds.height - 1);
heightMapBuilder.Build();
Chunk *chunk = new Chunk(this);
chunk->setPosition(chunkPos);
chunk->buildChunk(&heightMap);
chunk->setTexture(&mTileset);
mChunks.push_back(chunk);
return chunk;
}
This is the code for building the chunk
void Chunk::buildChunk(utils::NoiseMap *pHeightMap)
{
// Resize the tiles space
mTiles.resize(pHeightMap->GetWidth());
for (int x = 0; x < mTiles.size(); x++)
{
mTiles[x].resize(pHeightMap->GetHeight());
}
// Set vertices type and size
mVertices.setPrimitiveType(sf::Quads);
mVertices.resize(pHeightMap->GetWidth() * pHeightMap->GetWidth() * 4);
// Get the offset position of all tiles position
sf::Vector2i tileSize = mWorld->getTileSize();
sf::Vector2i chunkSize = mWorld->getChunkSize();
sf::Vector2f offsetPositon = sf::Vector2f(mPosition);
offsetPositon.x *= chunkSize.x;
offsetPositon.y *= chunkSize.y;
// Build tiles
for (int x = 0; x < mTiles.size(); x++)
{
for (int y = 0; y < mTiles[x].size(); y++)
{
// Sometimes libnoise can return a value over 1.0, better be sure to cap the top and bottom..
float heightValue = pHeightMap->GetValue(x, y);
if (heightValue > 1.f) heightValue = 1.f;
if (heightValue < -1.f) heightValue = -1.f;
// Instantiate a new Tile object with the noise value, this doesn't do anything yet..
mTiles[x][y] = new Tile(this, pHeightMap->GetValue(x, y));
// Get a pointer to the current tile's quad
sf::Vertex *quad = &mVertices[(y + x * pHeightMap->GetWidth()) * 4];
quad[0].position = sf::Vector2f(offsetPositon.x + x * tileSize.x, offsetPositon.y + y * tileSize.y);
quad[1].position = sf::Vector2f(offsetPositon.x + (x + 1) * tileSize.x, offsetPositon.y + y * tileSize.y);
quad[2].position = sf::Vector2f(offsetPositon.x + (x + 1) * tileSize.x, offsetPositon.y + (y + 1) * tileSize.y);
quad[3].position = sf::Vector2f(offsetPositon.x + x * tileSize.x, offsetPositon.y + (y + 1) * tileSize.y);
// find out which type of tile to render, atm only air or stone
TileStop *tilestop = mWorld->getTileStopAt(heightValue);
sf::Vector2i texturePos = tilestop->getTexturePosition();
// define its 4 texture coordinates
quad[0].texCoords = sf::Vector2f(texturePos.x, texturePos.y);
quad[1].texCoords = sf::Vector2f(texturePos.x + 64, texturePos.y);
quad[2].texCoords = sf::Vector2f(texturePos.x + 64, texturePos.y + 64);
quad[3].texCoords = sf::Vector2f(texturePos.x, texturePos.y + 64);
}
}
}
All the code that uses libnoise in some way are World.cpp, World.h and Chunk.cpp, Chunk.h in the project.