/**************************************************************************** Copyright (C) 2002-2008 Gilles Debunne. All rights reserved. This file is part of the QGLViewer library version 2.3.6. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License versions 2.0 or 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. In addition, as a special exception, Gilles Debunne gives you certain additional rights, described in the file GPL_EXCEPTION in this package. libQGLViewer uses dual licensing. Commercial/proprietary software must purchase a libQGLViewer Commercial License. This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *****************************************************************************/ // TP OpenGL: Joerg Liebelt, Serigne Sow // classe abstraite pour regrouper differentes approches // .. pour la generation de terrain #ifndef __TERRAIN_H__ #define __TERRAIN_H__ #include <stdlib.h> #include <qimage.h> #include <QGLViewer/qglviewer.h> //pour qglwidget #define TRN_NUM_TILES 5 // structure contenant le hauteur du terrain struct HEIGHTMAP { unsigned char* arrayHeightMap; // la liste int sizeHeightMap; // sa taille (puissance 2) }; //structure contenant les positions d'ombres struct LIGHTMAP { unsigned char* arrayLightMap; int sizeLightMap; }; // 4 types de textures bases selon les hauteurs du terrain enum TEXTURETYPE { LOWEST= 0, //sable MEDIUM, //herbe HIGH, //pierres HIGHEST //sommet de montagne }; // pour melanger les textures de bases, on definit des intervalles d'hauteurs acceptable pour le placement struct TEXTUREREGION { int lowHeight; // acceptance 0 int optimalHeight; // acceptance 100 int highHeight; // acceptance 0 }; // structure contenant les textures de base et les infos correspondantes struct TEXTURE { TEXTUREREGION region[TRN_NUM_TILES]; QImage data[TRN_NUM_TILES]; int numTextures; }; // classe abstraite class TERRAIN { protected: HEIGHTMAP heightMap; float scaleHeightMap; // facteur d'echelle pour surelever le terrain float scaleSize; //facteur d'echelle pour la taille du terrain TEXTURE textures; //gestion de textures QImage myTexture; //texture de couleur QImage myDetailMap; //texture de detail int repeatDetailMap; bool haveMultitexture; bool paintTextures; //gestion de lumiere / ombres LIGHTMAP lightMap; float rLight,gLight,bLight; float minBrightness, maxBrightness; float lightSoftness; int directionX, directionZ; bool paintLighting; //fcts. d'aide pour la generation de terrain fractale (filtrage) void NormalizeTerrain( float* heightData ); void SmoothTerrain(float* heightData, int kernelSize); void Smooth1DTerrain(float* heightData, int kernelSize); //fcts. d'aide de generation de textures float RegionPercent( int type, unsigned char height ); void GetTexCoords( QImage texture, unsigned int* x, unsigned int* y ); unsigned char InterpolateHeight( int x, int z, float heightToTexRatio ); public: int sizeHeightMap; virtual void Render( void )= 0; //fct. abstraite, a remplir par implementations bool LoadHeightMap( const QString& szFilename, int iSize ); //gestion des cartes d'hauteurs de terrain bool SaveHeightMap( const QString& szFilename ); bool UnloadHeightMap( void ); //generation de terrain fractale bool MakeTerrainFault( int size, int iterations, int min, int max, int smooth ); //smooth=1,3,5,7 //generation de textures unsigned int textureColorID; //pour identifier les textures aupres de opengl unsigned int textureDetailID; void GenerateTextureMap( unsigned int size ); bool LoadTexture( const QString& filename ); bool LoadDetailMap( const QString& filename ); //fonctions de lumiere void CalculateLighting( void ); void StepLightingDirection(void); //determiner l'echelle d'hauteur inline void SetHeightScale( float scale ) { scaleHeightMap = scale; } inline void SetSizeScale( float scale ) { scaleSize = scale; } inline void SetHeightAtPoint( unsigned char height, int X, int Z) { heightMap.arrayHeightMap[( Z*sizeHeightMap )+X]= height; } //renvoyer hauteur sans echelle inline unsigned char GetTrueHeightAtPoint( int X, int Z ) { return ( heightMap.arrayHeightMap[( Z*sizeHeightMap )+X] ); } inline float GetScaledHeightAtPoint( int X, int Z ) { if (X>=sizeHeightMap) X=sizeHeightMap-1; //eviter les effets de bord if (Z>=sizeHeightMap) Z=sizeHeightMap-1; return ( ( float )( heightMap.arrayHeightMap[( Z*sizeHeightMap )+X] )*scaleHeightMap ); } inline bool SaveTextureMap( const QString& filename ) { if( !myTexture.isNull( ) ) return ( myTexture.save( filename , "BMP")); return false; } inline void UnloadTexture( void ) { #if QT_VERSION < 0x040000 myTexture.reset( ); #endif } inline void UnloadDetailMap( void ) { #if QT_VERSION < 0x040000 myDetailMap.reset( ); #endif } inline void DoMultitexturing( bool have ) { haveMultitexture= have; } inline void DoTexturing( bool doIt ) { paintTextures= doIt; } inline void DoLighting( bool doIt ) { paintLighting= doIt; } inline bool isTexture() { return paintTextures;} inline bool isLighted() { return paintLighting;} inline bool LoadTile( TEXTURETYPE type, const QString& filename ) { return textures.data[type].load( filename ); } inline void UnloadTile(TEXTURETYPE type) { #if QT_VERSION < 0x040000 textures.data[type].reset(); #else Q_UNUSED(type) #endif } inline void UnloadAllTextures( void ) { UnloadTile( LOWEST ); UnloadTile( MEDIUM ); UnloadTile( HIGH ); UnloadTile( HIGHEST ); } //gestion des fct. pourries de QIMAGE inline void GetColor( const QImage& imageData, unsigned int x, unsigned int y, unsigned char* Red, unsigned char* Green, unsigned char* Blue ) { QRgb colors = imageData.pixel((int)x,(int)y); *Red = (unsigned char)qRed(colors); *Green = (unsigned char)qGreen(colors); *Blue = (unsigned char)qBlue(colors); } inline void SetColor( QImage& imageData, unsigned int x, unsigned int y, unsigned char Red, unsigned char Green, unsigned char Blue ) { imageData.setPixel( (int)x, (int)y, qRgb((int)Red ,(int)Green , (int)Blue ) ); } unsigned char Limit( float value ) { if( value>255 ) return 255; else if( value<0 ) return 0; return (unsigned char)value; } inline void SetBrightnessAtPoint( int x, int z, unsigned char brightness ) { lightMap.arrayLightMap[( z*lightMap.sizeLightMap )+x]= brightness; } inline unsigned char GetBrightnessAtPoint( int x, int z ) { return lightMap.arrayLightMap[( z*lightMap.sizeLightMap )+x]; } inline void SetLightColor( float r, float g, float b ) { rLight=r; gLight=g; bLight=b; } //avec ce modele d'ombrage simpliste, on a meme pas besoin de l'hauteur de la source de lumiere... inline void SetLightDirection( int dirX, int dirZ) { directionX= dirX; directionZ= dirZ; } inline void GetLightDirection( int* dirX, int* dirZ) { *dirX=directionX; *dirZ=directionZ; } inline bool UnloadLightMap(void) { if( lightMap.arrayLightMap ) { delete[] lightMap.arrayLightMap; lightMap.sizeLightMap = 0; return true; } return false; } TERRAIN( void ) { repeatDetailMap = 8; //A REVISER SetLightColor(1.0f,1.0f,1.0f); minBrightness = 0.2f; //valeurs qui marchent bien maxBrightness = 0.9f; lightSoftness = 10; paintLighting = true; directionX = -1; directionZ = 0; scaleHeightMap = 0.25f; scaleSize = 1.0f; //8.0f } virtual ~TERRAIN( void ) { } }; #endif //__TERRAIN_H__