Sign in to follow this  
Timmmay

Loading a .raw file into a vertex array and render in a display map

Recommended Posts

I am trying to load a 257 x 257 8 bit .raw file generated in terragen as a heightmap. I've been at it for a few hours now and can not think anymore :(.....can somebody please tell me what I'm doing wrong? I think when I load the height map into arrayHeightmap it stores the height values in binary. And when I take the values from arrayHeightmap and add X and Z components (in decimal) to them in arrayVertex it messes up? I tried many different approaches, but none seemed to work :( Any help would be greatly appreciated :)
#ifndef LOADTERRAIN_H
#define LOADTERRAIN_H

#include "loadTarga.h";

class heightMap
{
public:
	int mapXsize, mapYsize;
	unsigned char * arrayHeightmap;	// Holds the coordinates of the heightmap
	unsigned char * arrayVertex;	// Holds all the vertices of the current height map
	unsigned char * arrayTexture;	// Holds the texture coordinates of the height map texture

	GLuint dlistHeightmap;			// Display list handle

	void loadHeightmap(string filename, int rows, int cols);
	void drawHeightmap(const textureImage &textures);

	static void dlistFuncHeightmap(int mapXsize, int mapYsize);

	heightMap()
	{
	}
};


void heightMap::loadHeightmap(string filename, int rows, int cols)
{
	/* 
	   #	Part 1:
	   #		* Open the file
	   #		* Load the height map into an array
	*/

	// Set the width and height
	this->mapXsize = rows;
	this->mapYsize = cols;

	// declare array big enough for height map
	this->arrayHeightmap = new unsigned char[ this->mapXsize * this->mapYsize ];

	ifstream in;
	in.open( filename.c_str(), ios::binary );	// open file in binary mode

	if(!in)
	{
		cout << "Failed to open file" << endl;
		return;
	}

	// read in the height map
	in.read( (char*)this->arrayHeightmap, (this->mapXsize *	this->mapYsize) );	
												// read in (rows*cols) bytes from file
												// referred to by "in" -- (which is the
												// height map FILE

	in.close();									// close the file


	/* 
	   #	Part 2:
	   #		* Create a new vertex array (3 * current size) 
	   #		* Store X and Z coordinate for every height map point in the new array
	   #		* The old array will still be useful to keep player above the terrain
	   #		* Create a new texture array (2 * current size)
	   #		* Store X and Y texture coordinates in the new array
	*/

	// The vertex array should be 3 times the size of the height map array to store the X and Z components
	this->arrayVertex = new unsigned char[ this->mapXsize * this->mapYsize * 3 ];
	
	// The texture array should be 2 times the size of the height map array to store X and Y coordinate of the array
	this->arrayTexture = new unsigned char[ this->mapXsize * this->mapYsize * 2 ];

	// Create indices for the new vertex and texture arrays
	int vIndex = 0;		// Vertex array index
	int tIndex = 0;		// Texture array index

	// Start filling in the arrays that were just created
	for(int row = 0; row < this->mapYsize; row++)
	{
		for(int col = 0; col < this->mapXsize; col++)
		{

			int index = row * this->mapXsize + col;
			float y = this->arrayHeightmap[index] * 0.1f;
			
			// Fill in the texture coordinate for the current point
			this->arrayTexture[tIndex] = col /( float)this->mapYsize;
			this->arrayTexture[tIndex + 1] = row / (float)this->mapXsize;
			
			// Fill in the vertex coordinate for the current point
			this->arrayVertex[vIndex] = col;
			this->arrayVertex[vIndex + 1] = y;
			this->arrayVertex[vIndex + 2] = row;
			
			// Update the vertex and texture array indices
			vIndex += 3;
			tIndex += 2;
		}
	}


	/* 
	   #	Part 3:
	   #		* Store the height map array as a vertex array
	   #		* Store it's texture coordinates in a texture array
	*/

	// Enable vertex arrays (vertex and texture)
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	// Point the vertex arrays (vertex and texture) to the arrays containing the corresponding info
	glVertexPointer(3, GL_FLOAT, 0, this->arrayVertex);
	glTexCoordPointer(2, GL_FLOAT, 0, this->arrayTexture);


	/* 
	   #	Part 4:
	   #		* Set up a display list to draw the arrays
	*/

	this->dlistHeightmap = glGenLists(1);
	glNewList(this->dlistHeightmap, GL_COMPILE);
	this->dlistFuncHeightmap(this->mapXsize, this->mapYsize);
	glEndList();
	
}

void heightMap::dlistFuncHeightmap(int mapXsize, int mapYsize)
{
	static GLuint * indices;
	indices = new GLuint[mapXsize * 2];

	// Index of the vertex array
	int i;

	for (int y = 0; y < (mapYsize - 1); y++)
	{
		i = 0;

		for (int x = 0; x < mapXsize; x++)
		{
			indices[i] = (mapXsize * y) + x + mapXsize;
			indices[i+1] = (mapXsize * y) + x;

			i += 2;
		}

		glDrawElements(GL_TRIANGLE_STRIP, mapXsize * 2, GL_UNSIGNED_INT, indices);
	}
}

void heightMap::drawHeightmap(const textureImage &textures)
{
	glBindTexture( GL_TEXTURE_2D, textures.texture[TX_TERRAIN_MAIN_ID] );	// "pick" the height map texture
	
	glEnable(GL_TEXTURE_2D);												
	
	glCallList(this->dlistHeightmap);
	
	glDisable(GL_TEXTURE_2D);
}

#endif

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