I have been trying to generate a tile map off of a heightmap but have been running into issues. I am doing it using OpenGL in glOrtho projection so I have been mainly using NeHe Tutorial #34 as reference. The heightmap is being generated by LibNoise (which I will later use to generate random maps each time).
It has worked when I made the array by hand myself, but obviously that is tedious and I want the maps to be random.
This is what I get when I run my program:
http://www.boringbox.com/images/example1.jpg
That is zoomed out so that the entire map is visible. A closer shot:
http://www.boringbox.com/images/example2.jpg
When zoomed in to the normal level, each tile is 32x32.
The heightmap used for that was
http://www.boringbox.com/images/heightmap.bmp
I tried a simpler heightmap (
http://www.boringbox.com/images/heightmap2.bmp) to see if it would help me make any sense out of it. The result for the new map was:
http://www.boringbox.com/images/example3.jpg
As you can see, there seems to be either strips or spaces in between rows, and the map is being generated completely wrong.
Here is the relevant code:
MAP_SIZE and the array
#define MAP_SIZE 256
...
BYTE g_HeightMap[MAP_SIZE*MAP_SIZE]; //Array to hold the heightmap
BMP load function and part of InitGL
void LoadBMPFile(LPSTR strName, int nSize, BYTE *pHeightMap)
{
FILE *pFile = NULL;
// Open The File In Read / Binary Mode.
pFile = fopen( strName, "rb" );
// Check To See If We Found The File And Could Open It
if ( pFile == NULL )
{
// Display Error Message And Stop The Function
MessageBox(NULL, "Can't Find The Height Map!", "Error", MB_OK);
return;
}
fread( pHeightMap, 1, nSize, pFile );
// After We Read The Data, It's A Good Idea To Check If Everything Read Fine
int result = ferror( pFile );
// Check If We Received An Error
if (result)
{
MessageBox(NULL, "Failed To Get Data!", "Error", MB_OK);
}
// Close The File.
fclose(pFile);
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
...
LoadBMPFile("heightmap.bmp", MAP_SIZE * MAP_SIZE, g_HeightMap);
...
return TRUE; // Initialization Went OK
}
The Height() function
int Height(BYTE *pHeightMap, int X, int Y) // This Returns The Height From A Height Map Index
{
int x = X % MAP_SIZE; // Error Check Our x Value
int y = Y % MAP_SIZE; // Error Check Our y Value
if(!pHeightMap) return 0; // Make Sure Our Data Is Valid
return pHeightMap[x + (y * MAP_SIZE)]; // Index Into Our Height Array And Return The Height
}
The Draw function
void RenderWorld(BYTE pHeightMap[])
{
int tile;
int X = 0, Y = 0;
//Loop through the array.
for (Y = 0; Y < MAP_SIZE; Y++)
{
for (X = 0; X < MAP_SIZE; X++)
{
glLoadIdentity();
//tile is equal to the height given by the Height function
tile = Height(pHeightMap, X, Y );
//Basic tiling for test purposes
if (tile < 50)
{
tile = 0; //Deep water
}
if (tile > 49 && tile < 120)
{
tile = 1; //Shallow water
}
if (tile > 119 && tile < 140)
{
tile = 2; //Sand
}
if (tile > 139 && tile < 190)
{
tile = 3; //Grass
}
if (tile > 189 && tile < 200)
{
tile = 6; //Light Brush
}
if (tile > 199 && tile < 245)
{
tile = 8; //Forest
}
if (tile > 244 && tile < 256)
{
tile = 5; //Rock
}
if (tile > 256 || tile < 0)
{
MessageBox(NULL, "Invalid Height Value", "Error", MB_OK); //Check if an invalid number was given
}
//Draw the tiles
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f,1.0f,1.0f);
glBindTexture(GL_TEXTURE_2D, texture[tile].texID); //The texture used is determined by 'tile' above
glBegin(GL_QUADS);
//offsetX/Y currently used for basic camera movement
//Quads are textured backwards due to glOrtho
glTexCoord2f(0.0f, 1.0f); glVertex2d(X + offsetX, (Y + 1) + offsetY); //Top left
glTexCoord2f(1.0f, 1.0f); glVertex2d((X + 1) + offsetX, (Y + 1)+ offsetY); //Top right
glTexCoord2f(1.0f, 0.0f); glVertex2d((X + 1) + offsetX, Y + offsetY); //Bottom right
glTexCoord2f(0.0f, 0.0f); glVertex2d(X + offsetX, Y + offsetY); //Bottom left
glEnd();
glDisable(GL_TEXTURE_2D);
}
}
}
Essentially I am trying to modify NeHe Tutorial #34 for 2d use. Any glaring errors? It is probably something basic that I keep overlooking. But I really don't know why I am getting these results.
Is there any better ways to go about doing this? I understand that since I am using LibNoise I don't need to read the heightmap from a file, but honestly I am not sure how to get the array that LibNoise creates.
Thanks for your time, and I appreciate any help that can be given.