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 the image produced by my game.
I am dividing 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.
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);
}
}
}