All pastes #790830 Raw Edit

houlala

public cpp v1 · immutable
·published 2007-11-20 17:00 UTC
rendered paste body
#include <terrain.h>#include <iostream>#include <fstream>#include <GL/gl.h>#include <GL/glu.h>using namespace std;Terrain :: Terrain(){	width	   = 0;	height	   = 0;		heightmap = NULL;	texture   = NULL;	normals	  = NULL;		glTexture  = 0;	glList     = 0;		isTextured = false;}inline vec3 & Terrain :: getCoords(uint _i, uint _j){	return *(heightmap + _j * width + _i);}inline vec3 & Terrain :: getNormal(uint _i, uint _j){	return *(normals + _j * width + _i);}bool Terrain :: loadTexture(const char * _filename, int & _w, int & _h){	ifstream file(_filename, ios::binary);		string magic, line;	int offset, w, h, val;		if(texture != NULL)		delete [] texture;		isTextured = false;		if(file.is_open() == false)	{		cerr << "[-] Terrain::loadPPMTexture - Impossible d'ouvrir le fichier " << _filename << endl;		return false;	}		file >> magic;	if(magic != "P3" && magic != "P6")	{		cerr << "[-] Terrain::loadPPMTexture - Le fichier n'est pas au format PPM (format : " << magic << "). Abandon du chargement." << endl;		return false;	}		file >> std::ws;	while(file.peek() == '#')		getline(file, line);		file >> w;	file >> h;	file >> offset;		file >> std::ws;		if(offset > 255)	{		cerr << "[-] Terrain::loadPPMTexture - Les pixels ne sont pas codes sur 1 octet. Abandon du chargement." << endl;		return false;	}		if(w <= 0 || h <= 0)	{		cerr << "[Image::loadPNM] Erreur. Les dimensions de l'image sont incorrectes (x : " << w << ", y : " << h << "). Abandon du chargement." << endl;		return false;	}		texture = new unsigned char[w * h * 3];		if(magic == "P6")	{		for(int j(0); j < h; j++)			file.read((char *)&texture[j * w * 3], w * 3 * sizeof(char));	}	else	{		for(int j(0); j < h; j++)			for(int i(0); i < w; i++)				for(int k(0); k < 3; k++)				{					file >> val;					texture[(j * w + i) * 3 + k] = (unsigned char)val;				}	}		file.close();	/*	glGenTextures(1, &glTexture);	glBindTexture(GL_TEXTURE_2D, glTexture);		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, texture);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	*/	isTextured = true;	_w = w;	_h = h;		//delete [] texture;	return true;}bool Terrain :: load(const char * _filename, int _width, int _height, const char * _texture){	ifstream fileTerrain(_filename, ios::binary);		string magic, line;	int offset, w, h;		double center, max, min;		if(heightmap != NULL)		delete [] heightmap;		if(normals != NULL)		delete [] normals;			if(_texture != NULL)	{		if(loadTexture(_texture, w, h) == true)		{			if(_width == -1 && _height == -1)			{				width  = w;				height = h;			}			else			{				if(_width != w || _height != h)				{					cerr << "[-] Terrain::load - Le terrain et la texture ne sont pas de meme dimensions. Abandon du chargement." << endl;					return false;				}			}		}		else		{			if(_width == -1 && _height == -1)			{				cerr << "[-] Terrain::load - Impossible de trouver les dimensions du terrain. Abandon du chargement." << endl;				return false;			}			else			{				width  = _width;				height = _height;			}		}	}			if(fileTerrain.is_open() == false)	{		cerr << "[-] Terrain::load - Impossible d'ouvrir le fichier " << _filename << ". Abandon du chargement." << endl;		return false;	}		if(_width == -1 && _height == -1)	{		fileTerrain >> magic;		if(magic != "P2" && magic != "P5")		{			cerr << "[-] Terrain::load - Le terrain n'est pas au format PGM. Abandon du chargement." << endl;			return false;		}		else		{			fileTerrain >> std::ws;			while(fileTerrain.peek() == '#')				getline(fileTerrain, line);					fileTerrain >> w;			fileTerrain >> h;			fileTerrain >> offset;				fileTerrain >> std::ws;						if(offset > 255)			{				cerr << "[-] Terrain::load - Les coordonnees du terrain ne sont pas codees sur 1 octet. Abandon du chargement." << endl;				return false;			}						if(w <= 0 || h <= 0)			{				cerr << "[-] Terrain::load - Les dimensions du terrain sont incorrectes (x : " << w << ", y : " << h << "). Abandon du chargement." << endl;				return false;			}						width  = w;			height = h;						heightmap = new vec3[width * height];						max = 0;			min = 255;						int p;			if(magic == "P5")			{				cout << "ici" << endl;				unsigned char pix[width * height];				fileTerrain.read((char *)&pix, sizeof(char) * width * height);								for(uint j(0); j < height; j++)					for(uint i(0); i < width; i++)					{						p = *(pix + j * width + i);												getCoords(i, j).x = i - width / 2.0;						getCoords(i, j).y = p;						getCoords(i, j).z = j - height / 2.0;												if(min > p)							min = p;												if(max < p)							max = p;					}			}			else			{				for(uint j(0); j < height; j++)					for(uint i(0); i < width; i++)					{						fileTerrain >> p;												getCoords(i, j).x = i - width / 2.0;						getCoords(i, j).y = p;						getCoords(i, j).z = j - height / 2.0;												if(min > p)							min = p;												if(max < p)							max = p;					}			}		}			}	else	{		short pix[_width * _height], p;				width  = _width;		height = _height;						heightmap = new vec3[width * height];				fileTerrain.read((char *)&pix, sizeof(short) * width * height);				max = pix[0];		min = pix[0];				for(uint j(0); j < height; j++)			for(uint i(0); i < width; i++)			{				p = *(pix + j * width + i);								getCoords(i, j).x = i - width / 2.0;				getCoords(i, j).y = (float)p;				getCoords(i, j).z = j - height / 2.0;								if(min > p)					min = p;								if(max < p)					max = p;			}	}		center = (max + min) / 2.0;	for(uint i(0); i < width * height; i++)			(heightmap + i)->y -= center;		normals = new vec3[width * height];		fileTerrain.close();	return true;}void Terrain :: computeNormals(){	for(uint i(0); i < width * height; i++)		*(normals + i) = vec3::zero;		vec3 v1, v2, normal;		for(uint j(0); j < height - 1; j++)	{		for(uint i(0); i < width - 1; i++)		{			vec3 & p1 = getCoords(i    , j    );			vec3 & p2 = getCoords(i + 1, j    );			vec3 & p3 = getCoords(i + 1, j + 1);			vec3 & p4 = getCoords(i    , j + 1);						v1 = p2 - p1;			v2 = p4 - p1;						normal = v1 ^ v2;						getNormal(i    , j    ) += normal;			getNormal(i + 1, j    ) += normal;			getNormal(i    , j + 1) += normal;						v1 = p4 - p3;			v2 = p2 - p3;						normal = v1 ^ v2;						getNormal(i + 1, j + 1) += normal;			getNormal(i + 1, j    ) += normal;			getNormal(i    , j + 1) += normal;		}	}		for(uint i(0); i < width * height; i++)		(normals + i)->normalize();}void Terrain :: scale(double _s){	for(uint i(0); i < width * height; i++)		(heightmap + i)->y /= _s;}void Terrain :: createGLList(){	if(glList != 0)		glDeleteLists(glList, 1);		glList = glGenLists(1);	glNewList(glList, GL_COMPILE);		if(isTextured == true)	{		glGenTextures(1, &glTexture);		glBindTexture(GL_TEXTURE_2D, glTexture);				gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, texture);			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);				glEnable(GL_TEXTURE_2D);		glColor3f(1, 1, 1);		glBindTexture(GL_TEXTURE_2D, glTexture);	}		for(uint j(0); j < height - 1; j++)	{		glBegin(GL_TRIANGLE_STRIP);		for(uint i(0); i < width; i++)		{						if(glTexture != 0)				glTexCoord2f((float)i / width, (float)(j + 1)/height);					glNormal3fv(getNormal(i, j));				glVertex3fv(getCoords(i, j));						if(glTexture != 0)				glTexCoord2f((float)i / width, (float)(j)/height);					glNormal3fv(getNormal(i, j + 1));			glVertex3fv(getCoords(i, j + 1));		}					glEnd();	}		if(isTextured == true)	{		glDisable(GL_TEXTURE_2D);	}		glEndList();}void Terrain :: display(){	//glEnable(GL_TEXTURE_2D);	glCallList(glList);	//glDisable(GL_TEXTURE_2D);}