rendered paste body#include <terrain.h>
#include <iostream>
#include <fstream>
#include <GL/gl.h>
#include <fstream>
using namespace std;
Terrain :: Terrain(uint _width, uint _height, const char * _filename)
{
glList = 0;
texture = 0;
loadTerrain(_width, _height, _filename);
}
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 :: loadTerrain(uint _width, uint _height, const char * _filename)
{
ifstream file;
double center, max, min;
width = _width;
height = _height;
file.open(_filename, ios::binary);
if(file.is_open() == false)
{
cerr << "[-] Terrain::loadTerrain - Impossible d'ouvrir le fichier " << _filename << endl;
return false;
}
heightmap = new vec3[width * height];
normals = new vec3[width * height];
short pix[width * height], p;
file.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 = 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;
file.close();
return true;
}
bool Terrain :: loadTexture (const char * _filename)
{
char buff[16];
int l, h, maxval;
/* ouverture du fichier PPM */
ifstream img (_filename, ios::in | ios::binary);
if (!img.is_open())
{
cout << "[-] Terrain::loadTexture > Impossible d'ouvrir le fichier " << _filename << endl;
return false;
}
/* lecture de la magic value */
img.read(buff, 3);
if (img.bad())
{
cout << "[-] Terrain::loadTexture > Impossible de lire le fichier " << _filename << endl;
return false;
}
if (buff[0]!='P' || buff[1]!='6')
{
cout << "[-] Terrain::loadTexture > MagicValue incorrecte (pas P6)" << endl;
return false;
}
if (buff[2] != 0x0a)
img.seekg(-1,ios::cur);
while (img.read(buff, 1), buff[0]=='#')
{
while (img.read(buff, 1), buff[0]!='\n');
}
img.seekg(-1,ios::cur);
/* taille de la texture */
img >> l;
img >> h;
if (l<=0 || h<=0 || l!=(int)width || h!=(int)height)
{
cout << "[-] Terrain::loadTexture > Dimensions de l'image incorrectes.\n";
return false;
}
img >> maxval;
while (img.read(buff, 1), buff[0]!='\n');
/* allocation mémoire */
char *texture_temp = new char[3*width*height];
if (!texture_temp)
{
cout << "[-] Terrain::loadTexture > Impossible d'allouer la variable texture_temp.\n";
return false;
}
/* mise en mémoire de l'image */
img.read (texture_temp, 3*width*height);
/* fermeture du fichier */
img.close();
/* création d'une texture */
cout << "texture : "<<texture<<endl;
cout << glGenTextures(1, &texture) << endl;
cout << "texture : "<<texture<<endl;
glBindTexture(GL_TEXTURE_2D, texture);
cout << "texture : "<<texture<<endl;
/*
cout << "GLU : avt" << endl;
int test = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, texture_temp);
cout << "GLU : " << test << endl;
*/
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, width, height,0,GL_RGB,GL_UNSIGNED_BYTE, texture_temp);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* libération de la mémoire allouée */
delete [] texture_temp;
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()
{
cout << "texture : "<<texture<<endl;
if(glList != 0)
glDeleteLists(glList, 1);
glList = glGenLists(1);
glNewList(glList, GL_COMPILE);
if (texture != 0)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
cout << "on bind !\n";
}
for(uint j(0); j < height - 1; j++)
{
glBegin(GL_TRIANGLE_STRIP);
for(uint i(0); i < width; i++)
{
glNormal3fv(getNormal(i, j));
if (texture != 0)
glTexCoord2f ((float)i/width, (float)(j+1)/height);
glVertex3fv(getCoords(i, j));
glNormal3fv(getNormal(i, j + 1));
if (texture != 0)
glTexCoord2f ((float)i/width, (float)j/height);
glVertex3fv(getCoords(i, j + 1));
}
glEnd();
}
glEndList();
}
void Terrain :: display()
{
if (glList == 0)
createGLList();
glCallList(glList);
}