Sign in to follow this  
jake_Ghost

Problem rendering heightmap with screenshots

Recommended Posts

jake_Ghost    103
I have been working on this for a while and I can't seem to fix it. I have to images to show you guys: 1 - the rendered heightmap, 2 - the data loaded draw as an image where black is 0 height and bright red is max height. Also, when you look at the 2D and 3D heightmap, that back wall shouldn't be there, I don't know why thats happening. It seems that the data saved in a byte array is not working so good. I don't know what is causing this so I hope you guys can find it out. Here's the terrain loading/rendering code...
BOOL cTerrain :: LoadRawFile(std::string strName, int nSize, int ID, std::string TexBase, std::string TexDetail, int MapX, int MapY)
{
	FILE *pFile = NULL;

	// Let's open the file in Read/Binary mode.
	pFile = fopen( strName.c_str(), "rb" );

	// Check to see if we found the file and could open it
	if ( pFile == NULL )	
	{
		// Display our error message and stop the function
		MessageBox(HWND_DESKTOP, "Can't find the height map!", "Map Error", MB_OK);
		Write("Can't find height map " + strName);
		return FALSE;
	}

	TERRAIN tmpTerrain;

	terrain.push_back(tmpTerrain);
	TerrainCount += 1;

	terrain[TerrainCount - 1].HeightMap = new BYTE[MAP_SIZE * MAP_SIZE];
	terrain[TerrainCount - 1].MAPSIZE = nSize;
	terrain[TerrainCount - 1].ID = ID;
	terrain[TerrainCount - 1].TexBase = TexBase;
	terrain[TerrainCount - 1].TexDetail = TexDetail;
	terrain[TerrainCount - 1].x = MapX;
	terrain[TerrainCount - 1].y = MapY;

	// Here we load the .raw file into our pHeightMap data array.
	// We are only reading in '1', and the size is the (width * height)
	fread( terrain[TerrainCount - 1].HeightMap, 1, (MAP_SIZE * MAP_SIZE), 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)
	{
		Write("Error loading terrain " + strName);
		MessageBox(NULL, "Can't get data!", "Map Error", MB_OK);
	}

	Write("Loaded terrain " + strName);

	if(!bmp.FindTexture(TexBase))
	{
		bmp.LoadGLTextures(TexBase,3);
	}

	if(!bmp.FindTexture(TexDetail))
	{
		bmp.LoadGLTextures(TexDetail,3);
	}

	terrain[TerrainCount - 1].MapList = glGenLists(1);

	glNewList(terrain[TerrainCount - 1].MapList,GL_COMPILE);

		glEnable(GL_FOG);

		int X = terrain[TerrainCount - 1].x, Y = terrain[TerrainCount - 1].y;						// Create some variables to walk the array with.
		int x, y, z;							// Create some variables for readability
		bool bSwitchSides = false;
		BYTE *pHeightMap;

		pHeightMap = terrain[TerrainCount - 1].HeightMap;

		// Activate the first texture ID and bind the tree background to it
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glEnable(GL_TEXTURE_2D);

		if(bmp.FindTexture(terrain[TerrainCount - 1].TexBase))
		{
			glBindTexture(GL_TEXTURE_2D, bmp.Texture(terrain[TerrainCount - 1].TexBase));
		}

			// Activate the second texture ID and bind the fog texture to it
			glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
				
			// Here we turn on the COMBINE properties and increase our RGB
			// gamma for the detail texture.  2 seems to work just right.
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
					
			// Bind the detail texture
			if(bmp.FindTexture(terrain[TerrainCount - 1].TexDetail))
			{
				glBindTexture(GL_TEXTURE_2D, bmp.Texture(terrain[TerrainCount - 1].TexDetail));
			}
				
			// Now we want to enter the texture matrix.  This will allow us
			// to change the tiling of the detail texture.
			glMatrixMode(GL_TEXTURE);

				// Reset the current matrix and apply our chosen scale value
				glLoadIdentity();
				glScalef((float)4, (float)4, 1);

			// Leave the texture matrix and set us back in the model view matrix
			glMatrixMode(GL_MODELVIEW);

			glBegin(GL_TRIANGLE_STRIP);
				for (int x = terrain[TerrainCount - 1].x; x < MAP_SIZE + terrain[TerrainCount - 1].x; x += STEP_SIZE)
				{
					for (int y = terrain[TerrainCount - 1].y; y < MAP_SIZE + terrain[TerrainCount - 1].y; y += STEP_SIZE)
					{
						SetTextureCoord( (float)x, (float)y, TerrainCount - 1 );
						glVertex3f(x,Height(pHeightMap, x, y, TerrainCount - 1 ),y);

						SetTextureCoord( (float)x + STEP_SIZE, (float)y, TerrainCount - 1 );
						glVertex3f(x + STEP_SIZE,Height(pHeightMap, x+ STEP_SIZE, y, TerrainCount - 1 ),y);

						SetTextureCoord( (float)x, (float)y + STEP_SIZE, TerrainCount - 1 );
						glVertex3f(x,Height(pHeightMap, x, y+ STEP_SIZE, TerrainCount - 1 ),y + STEP_SIZE);

						SetTextureCoord( (float)x + STEP_SIZE, (float)y, TerrainCount - 1 );
						glVertex3f(x + STEP_SIZE,Height(pHeightMap, x+ STEP_SIZE, y, TerrainCount - 1 ),y);

						SetTextureCoord( (float)x + STEP_SIZE, (float)y + STEP_SIZE, TerrainCount - 1 );
						glVertex3f(x + STEP_SIZE,Height(pHeightMap, x+ STEP_SIZE, y+ STEP_SIZE, TerrainCount - 1 ),y + STEP_SIZE);

						SetTextureCoord( (float)x, (float)y + STEP_SIZE, TerrainCount - 1 );
						glVertex3f(x,Height(pHeightMap, x, y+ STEP_SIZE, TerrainCount - 1 ),y + STEP_SIZE);
					}
				}
			glEnd();

			// Turn the second multitexture pass off
			glActiveTextureARB(GL_TEXTURE1_ARB);
			glDisable(GL_TEXTURE_2D);

		// Turn the first multitexture pass off
		glActiveTextureARB(GL_TEXTURE0_ARB);		
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_FOG);
	glEndList();
	
	pHeightMap = NULL;

	// Close the file.
	fclose(pFile);

	return TRUE;
}





Here is my map, which draws a 2d version of the heightmap...
MapList = glGenLists(1);

	glNewList(MapList, GL_COMPILE);
		BYTE *pHeightMap;

		pHeightMap = cTer.terrain[i].HeightMap;

		glDisable(GL_TEXTURE_2D);

		glBegin(GL_QUADS);
			for (int x = 0; x < MAP_SIZE; x += 16)
			{
				for (int y = 0; y < MAP_SIZE; y += 16)
				{
					glColor3ub(cTer.Height(pHeightMap, x, y, i ),0,0);
					glVertex2f(x,y);

					glColor3ub(cTer.Height(pHeightMap, x, y + 16, i ),0,0);
					glVertex2f(x, y + 16);

					glColor3ub(cTer.Height(pHeightMap, x + 16, y + 16, i ),0,0);
					glVertex2f(x + 16, y + 16);

					glColor3ub(cTer.Height(pHeightMap, x + 16, y, i ),0,0);
					glVertex2f(x + 16, y);
				}
			}
		glEnd();

		glEnable(GL_TEXTURE_2D);
	glEndList();





Anyone know why this might be happening? Jake [Edited by - jake_Ghost on June 28, 2005 11:35:03 AM]

Share this post


Link to post
Share on other sites
Boruki    698
From my experience with heightmaps, I'd say doing one small thing should fix it.

Move the line:
glBegin(GL_QUADS);

So that it comes after:
for (int x = 0; x < MAP_SIZE; x += 16)

And also move the appropriate glEnd();

It worked for me in the past :) (I use the triangle strip method at the moment).

Share this post


Link to post
Share on other sites
jake_Ghost    103
I added that line of code to my terrain as well and those strips on top of the terrain disappeared, but that back wall didn't. The wall shouldn't bee there.

Share this post


Link to post
Share on other sites
Boruki    698
Ok, you need to change these lines:

for (int x = 0; x < MAP_SIZE; x += 16)

and

for (int y = 0; y < MAP_SIZE; y += 16)

After MAP_SIZE put -1

That should remove the wall.

Share this post


Link to post
Share on other sites
jake_Ghost    103
I added the - 1 but it didn't do anything. I put - 16 and now the wall is gone but I have all these spaces in between my terrain now. So now all the terrain is 1008 x 1008 instead of 1024 x 1024.

Jake

Share this post


Link to post
Share on other sites
Boruki    698
Can you post how the code looks now? You have some weirdass thing with all your 16's. I'll see what I can do when you've posted that code.

Share this post


Link to post
Share on other sites
jake_Ghost    103
Here's my entire Terrain.cpp file...




#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The GLaux Library
#include <math.h>
#include "main.h"
#include "terrain.h"
#include "bmp.h"

// This stores the desired depth that we want to fog
extern float g_FogDepth;

// This is our fog extension function pointer to set a vertice's depth
extern PFNGLFOGCOORDFEXTPROC glFogCoordfEXT;

int cTerrain :: Height(BYTE *pHeightMap, int X, int Y,int ID)
{
// Make sure we don't go past our array size
int x = X % MAP_SIZE; // Error check our x value
int y = Y % MAP_SIZE; // Error check our y value

//if(!terrain[ID].HeightMap) return 0; // Make sure our data is valid

// Use the equation: index = (x + (y * arrayWidth) ) to find the current height
return (pHeightMap[x + (y * MAP_SIZE)]); // Index into our height array and return the height
}

int cTerrain :: Height(int X, int Y,int ID)
{
// Make sure we don't go past our array size
int x = X % MAP_SIZE; // Error check our x value
int y = Y % MAP_SIZE; // Error check our y value

//if(!terrain[ID].HeightMap) return 0; // Make sure our data is valid

//for (int i = 0; i < TerrainCount; i++)
//{
// if (terrain[i].ID = i)
// {
// Use the equation: index = (x + (y * arrayWidth) ) to find the current height
return (terrain[ID].HeightMap[x + (y * MAP_SIZE)]); // Index into our height array and return the height
// }
//}
}

int cTerrain :: GetID(int ID)
{
for (int i = 0; i < TerrainCount; i++)
{
if (terrain[i].ID == i)
{
return i;
}
}

return -1;
}

void cTerrain :: SetTextureCoord(float x, float z, int ID)
{
// Find the (u, v) coordinate for the current vertex
float u = (float)x / (float)MAP_SIZE;
float v = -(float)z / (float)MAP_SIZE;

// Give OpenGL the current terrain texture coordinate for our height map
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, u, v);

// Give OpenGL the current detail texture coordinate for our height map
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, u, v);
}


void SetFogCoord(float depth, float height)
{

float fogY = 0;

// Check if the height of this vertex is greater than the depth (needs no fog)
if(height > depth)
fogY = 0;
// Otherwise, calculate the fog depth for the current vertex
else
fogY = -(height - depth);

// Assign the fog coordinate for this vertex using our extension function pointer
glFogCoordfEXT(fogY);
}

void cTerrain :: RenderHeightMap(int ID)
{
for (int i = 0; i < TerrainCount; i++)
{
if (terrain[i].ID == ID)
{
if(!terrain[i].HeightMap) return;

glCallList(terrain[i].MapList);
}
}
}

BOOL cTerrain :: LoadRawFile(std::string strName, int nSize, int ID, std::string TexBase, std::string TexDetail, int MapX, int MapY)
{
FILE *pFile = NULL;

// Let's open the file in Read/Binary mode.
pFile = fopen( strName.c_str(), "rb" );

// Check to see if we found the file and could open it
if ( pFile == NULL )
{
// Display our error message and stop the function
MessageBox(HWND_DESKTOP, "Can't find the height map!", "Map Error", MB_OK);
Write("Can't find height map " + strName);
return FALSE;
}

TERRAIN tmpTerrain;

terrain.push_back(tmpTerrain);
TerrainCount += 1;

terrain[TerrainCount - 1].HeightMap = new BYTE[MAP_SIZE * MAP_SIZE];
terrain[TerrainCount - 1].MAPSIZE = nSize;
terrain[TerrainCount - 1].ID = ID;
terrain[TerrainCount - 1].TexBase = TexBase;
terrain[TerrainCount - 1].TexDetail = TexDetail;
terrain[TerrainCount - 1].x = MapX;
terrain[TerrainCount - 1].y = MapY;

// Here we load the .raw file into our pHeightMap data array.
// We are only reading in '1', and the size is the (width * height)
fread( terrain[TerrainCount - 1].HeightMap, 1, (MAP_SIZE * MAP_SIZE), 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)
{
Write("Error loading terrain " + strName);
MessageBox(NULL, "Can't get data!", "Map Error", MB_OK);
}

Write("Loaded terrain " + strName);

if(!bmp.FindTexture(TexBase))
{
bmp.LoadGLTextures(TexBase,3);
}

if(!bmp.FindTexture(TexDetail))
{
bmp.LoadGLTextures(TexDetail,3);
}

terrain[TerrainCount - 1].MapList = glGenLists(1);

glNewList(terrain[TerrainCount - 1].MapList,GL_COMPILE);

glEnable(GL_FOG);

int X = terrain[TerrainCount - 1].x, Y = terrain[TerrainCount - 1].y; // Create some variables to walk the array with.
int x, y, z; // Create some variables for readability
bool bSwitchSides = false;
BYTE *pHeightMap;

pHeightMap = terrain[TerrainCount - 1].HeightMap;

// Activate the first texture ID and bind the tree background to it
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);

if(bmp.FindTexture(terrain[TerrainCount - 1].TexBase))
{
glBindTexture(GL_TEXTURE_2D, bmp.Texture(terrain[TerrainCount - 1].TexBase));
}

// Activate the second texture ID and bind the fog texture to it
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);

// Here we turn on the COMBINE properties and increase our RGB
// gamma for the detail texture. 2 seems to work just right.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);

// Bind the detail texture
if(bmp.FindTexture(terrain[TerrainCount - 1].TexDetail))
{
glBindTexture(GL_TEXTURE_2D, bmp.Texture(terrain[TerrainCount - 1].TexDetail));
}

// Now we want to enter the texture matrix. This will allow us
// to change the tiling of the detail texture.
glMatrixMode(GL_TEXTURE);

// Reset the current matrix and apply our chosen scale value
glLoadIdentity();
glScalef((float)4, (float)4, 1);

// Leave the texture matrix and set us back in the model view matrix
glMatrixMode(GL_MODELVIEW);

for (int x = terrain[TerrainCount - 1].x; x < MAP_SIZE + terrain[TerrainCount - 1].x - 16; x += STEP_SIZE)
{
for (int y = terrain[TerrainCount - 1].y; y < MAP_SIZE + terrain[TerrainCount - 1].y - 16; y += STEP_SIZE)
{
glBegin(GL_TRIANGLE_STRIP);
SetTextureCoord( (float)x, (float)y, TerrainCount - 1 );
glVertex3f(x,Height(pHeightMap, x, y, TerrainCount - 1 ),y);

SetTextureCoord( (float)x + STEP_SIZE, (float)y, TerrainCount - 1 );
glVertex3f(x + STEP_SIZE,Height(pHeightMap, x+ STEP_SIZE, y, TerrainCount - 1 ),y);

SetTextureCoord( (float)x, (float)y + STEP_SIZE, TerrainCount - 1 );
glVertex3f(x,Height(pHeightMap, x, y+ STEP_SIZE, TerrainCount - 1 ),y + STEP_SIZE);

SetTextureCoord( (float)x + STEP_SIZE, (float)y, TerrainCount - 1 );
glVertex3f(x + STEP_SIZE,Height(pHeightMap, x+ STEP_SIZE, y, TerrainCount - 1 ),y);

SetTextureCoord( (float)x + STEP_SIZE, (float)y + STEP_SIZE, TerrainCount - 1 );
glVertex3f(x + STEP_SIZE,Height(pHeightMap, x+ STEP_SIZE, y+ STEP_SIZE, TerrainCount - 1 ),y + STEP_SIZE);

SetTextureCoord( (float)x, (float)y + STEP_SIZE, TerrainCount - 1 );
glVertex3f(x,Height(pHeightMap, x, y+ STEP_SIZE, TerrainCount - 1 ),y + STEP_SIZE);
glEnd();
}
}

// Turn the second multitexture pass off
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

// Turn the first multitexture pass off
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_FOG);
glEndList();

pHeightMap = NULL;

// Close the file.
fclose(pFile);

return TRUE;
}

cTerrain :: cTerrain()
{

}

cTerrain :: ~cTerrain()
{
for (int i = 0; i < TerrainCount; i++)
{
delete [] terrain[i].HeightMap;
}

terrain.clear();
}

Share this post


Link to post
Share on other sites
Boruki    698
Did you change either of these lines based on what I said?

for (int x = terrain[TerrainCount - 1].x; x < MAP_SIZE + terrain[TerrainCount - 1].x - 16; x += STEP_SIZE)

for (int y = terrain[TerrainCount - 1].y; y < MAP_SIZE + terrain[TerrainCount - 1].y - 16; y += STEP_SIZE)

What I meant by the -1 was like this:

for (int x = terrain[TerrainCount - 1].x; x < MAP_SIZE-1 + terrain[TerrainCount - 1].x - 16; x += STEP_SIZE)

for (int y = terrain[TerrainCount - 1].y; y < MAP_SIZE-1 + terrain[TerrainCount - 1].y - 16; y += STEP_SIZE)

Share this post


Link to post
Share on other sites
jake_Ghost    103
- 15 has no effect. I put - 16 because then it doesn't draw the last 16 pixels of terrain. I think it might have to do with the loading of the terrain or something cause the heightmap data seems to be wrong.

Jake

PS. you can see that it is wrong from the second picture in the first post I made

Share this post


Link to post
Share on other sites
Boruki    698
for (int x = terrain[TerrainCount - 1].x; x < MAP_SIZE + terrain[TerrainCount - 1].x - 16; x += STEP_SIZE) {
glBegin(GL_TRIANGLE_STRIP); <----- this should be between these lines, not after the next one (move glEnd() too)
for (int y = terrain[TerrainCount - 1].y; y < MAP_SIZE + terrain[TerrainCount - 1].y - 16; y += STEP_SIZE) {

Share this post


Link to post
Share on other sites
jake_Ghost    103
Ok I did that no effect. I'm learning toward a problem loading the data as you can see by the comparison I made in my last post. Becuase it seems to be rendering properly now but it is drawn improperly because the data loaded seems to be messed up.

Jake

Share this post


Link to post
Share on other sites
Boruki    698
Ok. Well.. I never used .raw files.. so you'll have to hope someone else comes along to give you a hand with that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this