#ifndef __Terrain__ #define __Terrain__ #include #include class Terrain { private : uint width; uint height; vec3 * heightmap; vec3 * normals; /* texture */ GLuint texture; uint glList; vec3 & getCoords(uint _i, uint _j); vec3 & getNormal(uint _i, uint _j); public : Terrain(uint _width, uint _height, const char * _filename); bool loadTerrain(uint _width, uint _height, const char * _filename); bool loadTexture (const char * _filename); void computeNormals(); void scale(double _s); void createGLList(); void display(); }; #endif ----------------------------[ CPP ]----------------------------------- #include #include #include #include #include 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 : "<normalize(); } void Terrain :: scale(double _s) { for(uint i(0); i < width * height; i++) (heightmap + i)->y /= _s; } void Terrain :: createGLList() { cout << "texture : "<