begin process at 2010 09 09 14:19:19
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > LANDSCAPE GL : GÉNÉRATION DE PAYSAGE EN 3D

LANDSCAPE GL : GÉNÉRATION DE PAYSAGE EN 3D


 Information sur la source

Note :
Aucune note
Catégorie :Graphique Niveau :Débutant Date de création :23/08/2003 Date de mise à jour :23/08/2003 01:31:48 Vu / téléchargé :4 319 / 316

Auteur : Maegis

Ecrire un message privé
Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Cette source est basée sur un article du magazine Login n 107
Elle genere un paysage en 3D et l'affiche grace a openGL en mode fil de fer (voir la catpure).
On peut changer la taille du paysage ainsi qu'un parametre permettant d'avoir un paysage plus ou moins lisse.
Il y a inclus dans le zip une explication de 11 pages du procédé de génération du paysage(en .doc plus facile pour les schemas) .Si avec ça vous ne comprenez pas c'est que je ne sais vraiment pas bien expliquer.

Touches utiles (par defaut prevu pour un QWERTY)
W pour se deplacer en avant
S en arriere
A a gauche
D a droite
Les fleches directionnelles pour modifier la vue (tourner a gauche a droite en haut et en bas)
Et enfin R qui recalcule un nouveau paysage

Pour une taille de paysage de 9 ou plus l'affichage (pas le calcul) est assez saccadé.(taille de 9 = paysage de plus de 130 000 triangles)

Si vous ne voulez pas Dl le zip ou pour la compil codes-sources il y a le code en bas qui est modifié pour ne pas avoir de boite de configuration au demarrage (changement des params direct dans le code)

Je ne sais pas trop dans quelle catégorie le mettre je ne le met pas dans openGl car ici il sert juste a l'affichage et l'important est quand même la génération du terrain.  

Source

  • /*-----------------------------------------------------------------------------------------------*
  • //
  • // LandscapeGL
  • //
  • //Fait par : MaegisInstinct (maegisinstinct@free.fr)
  • //
  • //le : 14/08/2003 à 13:03:45
  • //
  • //Description : Generation d'un paysage
  • //
  • //Note : Lire le fichier readme.doc pour avoir une explication de le methode de
  • // generation du terrain et de l'affichage
  • //
  • /*----------------------------------------------------------------------------------------------*/
  • //Includes
  • #include <windows.h>
  • #include <stdlib.h> //rand
  • #include <gl/gl.h>
  • #include <gl/glu.h>
  • #pragma comment(lib,"opengl32.lib")
  • #pragma comment(lib,"glu32.lib")
  • //Declarations
  • void Draw(HDC,double **,int,int,int,int,int,int); //fonction de dessin
  • void Reshape(int,int);
  • void SetupPixelFormat(HDC);
  • double** CalculLand(int,double); //Generation du terrain
  • double** CreateTableau2d(int); //Cree un tableau a 2 dimensions
  • void DeleteTableau2d(double **,int); //Delete le tableau
  • void SquareStep(double**,int,int,double); //Etape de creation du terrain
  • void DiamondStep(double**,int,int,double,int); //2 etape de creation du terrain
  • LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
  • //Var globales
  • int pow2[15] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384}; //puissances de 2
  • double lisse = 2;
  • int tailletableau = 8;
  • //--------------
  • //Fonction main
  • //--------------
  • int APIENTRY WINAPI WinMain(HINSTANCE hInstance,
  • HINSTANCE hPrevInstance,
  • LPSTR lpCmdLine,
  • int nCmdShow)
  • {
  • MSG msg;
  • WNDCLASS wc;
  • HWND hWnd;
  • wc.cbClsExtra = 0;
  • wc.cbWndExtra = 0;
  • wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
  • wc.hCursor = NULL;
  • wc.hIcon = NULL;
  • wc.hInstance = hInstance;
  • wc.lpfnWndProc = &WinProc;
  • wc.lpszClassName = "Fenetre GL";
  • wc.lpszMenuName = NULL;
  • wc.style = CS_HREDRAW | CS_VREDRAW;
  • RegisterClass(&wc);
  • //on cree la fenetre
  • hWnd = CreateWindow("Fenetre GL",
  • "Landscape",
  • WS_POPUP,
  • 0,0,
  • GetSystemMetrics(SM_CXSCREEN),
  • GetSystemMetrics(SM_CYSCREEN),
  • NULL,
  • NULL,
  • hInstance,
  • NULL);
  • ShowWindow(hWnd,SW_SHOW);
  • UpdateWindow(hWnd);
  • ShowCursor(FALSE); //on cache le curseur
  • while (GetMessage(&msg,NULL,0,0))
  • {
  • TranslateMessage(&msg);
  • DispatchMessage(&msg);
  • }
  • return msg.wParam;
  • }
  • //----------------------------------------------------
  • //Met l'affichage en 32bits et specifie le backbuffer
  • //----------------------------------------------------
  • void SetupPixelFormat(HDC hDC)
  • {
  • int pixelFormat;
  • PIXELFORMATDESCRIPTOR pfd = {
  • sizeof(PIXELFORMATDESCRIPTOR),
  • 1,
  • PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER,
  • PFD_TYPE_RGBA,
  • 32,
  • 0, 0, 0, 0, 0, 0,
  • 0, 0,
  • 0, 0, 0, 0, 0,
  • 32,
  • 0,
  • 0,
  • 0,
  • 0,
  • 0,
  • 0,
  • 0
  • };
  • pixelFormat = ChoosePixelFormat(hDC, &pfd);
  • if (pixelFormat == 0)
  • {
  • MessageBox(NULL,"Mode graphique non supporté","Erreur",MB_OK);
  • exit(1);
  • }
  • if (SetPixelFormat(hDC,pixelFormat,&pfd) != TRUE)
  • {
  • MessageBox(NULL,"Mode graphique non supporté","Erreur",MB_OK);
  • exit(1);
  • }
  • }
  • //---------------------------------
  • //Fonction de gestion des messages
  • //---------------------------------
  • LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  • {
  • HDC hdc;
  • PAINTSTRUCT ps;
  • static HGLRC hrc;
  • static double** tableau = NULL;
  • //Variables pour le deplacement sur le terrain
  • static int anglex = 0;
  • static int angley = 0;
  • static int distance = 25;
  • static int strafe = 0;
  • static int hauteur = 0;
  • switch(msg)
  • {
  • case WM_CREATE:
  • srand(GetTickCount()); //on initialise rand
  • tableau = CalculLand(tailletableau,lisse); //on genere le terrain
  • if (tableau == NULL)
  • {
  • MessageBox(hWnd,"Erreur d'allocution de memoire","Erreur de memoire",MB_OK | MB_ICONEXCLAMATION);
  • PostQuitMessage(0);
  • }
  • hdc=GetDC(hWnd);
  • SetupPixelFormat(hdc); //on set le mode d'affichage
  • hrc = wglCreateContext(hdc); //On cree un rendering context
  • if (!hrc)
  • DestroyWindow(hWnd);
  • wglMakeCurrent(hdc,hrc); //on l'associe au DC
  • break;
  • case WM_DESTROY:
  • wglMakeCurrent(NULL,NULL); //on libere le RC
  • if (hrc)
  • wglDeleteContext(hrc); //on le delete
  • if (tableau != NULL)
  • DeleteTableau2d(tableau,pow2[tailletableau]+1); //on libere la memoire
  • PostQuitMessage(0);
  • break;
  • case WM_SIZE:
  • Reshape(LOWORD(lParam),HIWORD(lParam)); //on met a jour l'affichage
  • break;
  • case WM_KEYDOWN :
  • InvalidateRect(hWnd,NULL,FALSE); //on redessinne
  • switch(wParam)
  • {
  • case VK_ESCAPE :
  • DestroyWindow(hWnd);
  • break;
  • case 'R' :
  • DeleteTableau2d(tableau,tailletableau); //on delete le tableau
  • tableau = CalculLand(tailletableau,lisse); //on recalcule
  • InvalidateRect(hWnd,NULL,FALSE);
  • break;
  • //gestion du deplacement
  • case VK_LEFT :
  • angley++;
  • break;
  • case VK_RIGHT :
  • angley--;
  • break;
  • case VK_UP :
  • anglex++;
  • break;
  • case VK_DOWN :
  • anglex--;
  • break;
  • case 'W' :
  • distance--;
  • break;
  • case 'S' :
  • distance++;
  • break;
  • case 'A' :
  • strafe++;
  • break;
  • case 'D' :
  • strafe--;
  • break;
  • case 'C' :
  • hauteur--;
  • break;
  • case VK_SPACE :
  • hauteur++;
  • break;
  • }
  • break;
  • case WM_PAINT:
  • if (tableau != NULL)
  • {
  • hdc = BeginPaint(hWnd,&ps);
  • Draw(hdc,tableau,pow2[tailletableau],anglex,angley,distance,strafe,hauteur); //on Draw la scene
  • EndPaint(hWnd,&ps);
  • }
  • break;
  • }
  • return DefWindowProc(hWnd,msg,wParam,lParam);
  • }
  • //-------------------
  • //Fonction de dessin
  • //-------------------
  • void Draw(HDC hdc,double **tableau,int indexmax,int anglex,int angley,int distance,int strafe,int hauteur)
  • {
  • int i,j;
  • glClearColor(0,0,0,0);
  • glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //on efface tout
  • glMatrixMode(GL_MODELVIEW);
  • glLoadIdentity();
  • gluLookAt(0,0,25,0,0,0,0,1,0); //on defini le point de vue
  • glPushMatrix();
  • //Gestion du deplacement
  • glTranslated(strafe,-hauteur,-distance);
  • glRotated(anglex,1,0,0);
  • glRotated(-angley,0,1,0);
  • glScaled(50.0/indexmax,50.0/indexmax,50.0/indexmax); //mise a l'echelle
  • //affichage
  • for(i=0;i<indexmax;i++)
  • {
  • for(j=0;j<indexmax;j++)
  • {
  • glBegin(GL_LINE_LOOP);
  • glVertex3i(i+1-indexmax/2 ,(int)tableau[i+1][j] ,j-indexmax/2 );
  • glVertex3i(i-indexmax/2 ,(int)tableau[i][j] ,j-indexmax/2 );
  • glVertex3i(i-indexmax/2 ,(int)tableau[i][j+1] ,j+1-indexmax/2 );
  • glVertex3i(i+1-indexmax/2 ,(int)tableau[i+1][j] ,j-indexmax/2 );
  • glVertex3i(i+1-indexmax/2 ,(int)tableau[i+1][j+1] ,j+1-indexmax/2 );
  • glVertex3i(i-indexmax/2 ,(int)tableau[i][j+1] ,j+1-indexmax/2 );
  • glEnd();
  • }
  • }
  • glPopMatrix();
  • SwapBuffers(hdc);
  • }
  • //---------------------------------------------------------
  • //Cree le landscape (retourne un pointeur vers le tableau)
  • //---------------------------------------------------------
  • double** CalculLand(int taille,double lisse)
  • {
  • //Pour l'explication lire le readme !
  • double** tableau;
  • int indexmax = pow2[taille];
  • int step;
  • int i;
  • double randRange = indexmax/2.0;
  • if (lisse > 10) //lisse compris entre 1.5 (horriblement escarpé)
  • lisse = 10; //et 10 (pas mal lisse)
  • if (lisse <1.5)
  • lisse = 1.5;
  • if (taille < 1 ) //on verifie que la taille ne soit pas trop grande (affichage tres long)
  • taille = 1; //et qu'elle soit au moins de 1
  • if (taille > 11 )
  • taille = 11;
  • tableau = CreateTableau2d(indexmax+1); //Creation du tableau
  • if(tableau == NULL)
  • return tableau;
  • //initialisation des 4 coins du tableau (on peut mettre une autre valeur)
  • tableau[0][0] = 0;
  • tableau[0][indexmax] = 0;
  • tableau[indexmax][indexmax] = 0;
  • tableau[indexmax][0] = 0;
  • step = indexmax;
  • for(i = 0;i<taille;i++) //on genere le terrain
  • {
  • SquareStep(tableau,i,step,randRange);
  • DiamondStep(tableau,i,step,randRange,indexmax);
  • if (randRange > 1)
  • randRange /= lisse;
  • if (randRange < 1) //pour eviter le x%0 qui n'existe pas
  • randRange = 1;
  • step /= 2;
  • }
  • return tableau;
  • }
  • //---------------------------------------
  • //1ere etape de generation (voir readme)
  • //---------------------------------------
  • void SquareStep(double **tableau,int nb_passes,int step,double randRange)
  • {
  • int debI,midI,finI;
  • int debJ,midJ,finJ;
  • int i,j;
  • debI = 0;
  • midI = step/2;
  • finI = step;
  • for(i=0;i<pow2[nb_passes];i++)
  • {
  • debJ = 0; //on revient a 0 pour une autre boucle
  • midJ = step/2;
  • finJ = step;
  • for(j=0;j<pow2[nb_passes];j++)
  • {
  • //On fait la moyenne des cases avoisinantes + un nombre compris en -randRange et +randRange
  • tableau[midI][midJ] = (tableau[debI][debJ] + tableau[debI][finJ] + tableau[finI][finJ] + tableau[finI][debJ] ) /4.0 + (rand()%((int)randRange*2))-randRange;
  • debJ += step; //on incremente
  • midJ += step;
  • finJ += step;
  • }
  • debI += step; //incrementation
  • midI += step;
  • finI += step;
  • }
  • }
  • //-----------
  • //2eme etape
  • //-----------
  • void DiamondStep(double **tableau,int nb_passes,int step,double randRange,int indexmax)
  • {
  • int debI,midI,finI;
  • int debJ,midJ,finJ;
  • int i,j;
  • int halfstep = step/2; //pour eviter les step/2 tout le temps
  • midI = 0;
  • debI = indexmax-halfstep;
  • finI = halfstep;
  • for(i=0;i<pow2[nb_passes+1];i++)
  • {
  • if(i%2)
  • {
  • midJ = 0;
  • debJ = indexmax-halfstep;
  • finJ = halfstep;
  • }
  • else
  • {
  • midJ = halfstep;
  • debJ = 0;
  • finJ = step;
  • }
  • for(j=0;j<pow2[nb_passes];j++)
  • {
  • //Moyenne + nombre entre -randRange et +randRange
  • tableau[midI][midJ] = (tableau[midI][debJ] + tableau[midI][finJ] + tableau[debI][midJ] + tableau[finI][midJ]) /4.0 + (rand()%((int)randRange*2))-randRange;
  • debJ = (debJ+step)%indexmax; //explication dans le readme
  • midJ += step;
  • finJ += step;
  • }
  • debI = (debI+halfstep) % indexmax;
  • midI += halfstep;
  • finI += halfstep;
  • }
  • //Recopiage des extremites
  • midI = halfstep;
  • for(i=0;i<pow2[nb_passes];i++)
  • {
  • tableau[indexmax][midI] = tableau[0][midI];
  • tableau[midI][indexmax] = tableau[midI][0];
  • midI += step;
  • }
  • }
  • //-------------------------------
  • //Cree un tableau a 2 dimensions
  • //-------------------------------
  • double** CreateTableau2d(int taille)
  • {
  • double** tableau;
  • int i;
  • tableau = new double*[taille];
  • if(tableau != NULL)
  • {
  • for(i=0;i<taille;i++)
  • {
  • tableau[i] = new double[taille];
  • if (tableau[i] == NULL) //si erreur on delete
  • {
  • DeleteTableau2d(tableau,taille);
  • return NULL;
  • }
  • }
  • }
  • return tableau;
  • }
  • //---------------------------------
  • //Delete le tableau a 2 dimensions
  • //---------------------------------
  • void DeleteTableau2d(double **tableau,int taille)
  • {
  • int i;
  • for(i=0;i<taille;i++)
  • {
  • if (tableau[i] != NULL) //on verifie que le pointeur ne soit pas null
  • delete[] tableau[i];
  • }
  • delete[] tableau;
  • }
  • //-------------------------------------------------------
  • //Definition de la perspective et de la zone d'affichage
  • //-------------------------------------------------------
  • void Reshape(int width,int height)
  • {
  • glViewport(0,0,width,height); //on defini la taille
  • glMatrixMode(GL_PROJECTION);
  • glLoadIdentity();
  • gluPerspective(45.0,(GLdouble) width/height,0,500);
  • }
/*-----------------------------------------------------------------------------------------------*
//
//                                      LandscapeGL
//
//Fait par         : MaegisInstinct (maegisinstinct@free.fr)
//
//le               : 14/08/2003 à 13:03:45
//
//Description      : Generation d'un paysage
//
//Note			   : Lire le fichier readme.doc pour avoir une explication de le methode de 
//					 generation du terrain et de l'affichage
//
/*----------------------------------------------------------------------------------------------*/


//Includes 
#include <windows.h>
#include <stdlib.h>		//rand
#include <gl/gl.h>
#include <gl/glu.h>

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

//Declarations
void				Draw(HDC,double **,int,int,int,int,int,int);				//fonction de dessin
void				Reshape(int,int);
void				SetupPixelFormat(HDC);
double**			CalculLand(int,double);					//Generation du terrain
double**			CreateTableau2d(int);					//Cree un tableau a 2 dimensions
void				DeleteTableau2d(double **,int);			//Delete le tableau
void				SquareStep(double**,int,int,double);	//Etape de creation du terrain
void				DiamondStep(double**,int,int,double,int);	//2 etape de creation du terrain
LRESULT CALLBACK	WinProc(HWND,UINT,WPARAM,LPARAM);	


//Var globales
int		pow2[15]		= {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384};	//puissances de 2
double	lisse			= 2;
int		tailletableau	= 8;

//--------------
//Fonction main
//--------------
int APIENTRY WINAPI WinMain(HINSTANCE hInstance,  
							HINSTANCE hPrevInstance,   
							LPSTR lpCmdLine,   
							int nCmdShow)
{
	MSG			msg;
	WNDCLASS	wc;
	HWND		hWnd;


	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hbrBackground	= (HBRUSH) GetStockObject(BLACK_BRUSH);
	wc.hCursor			= NULL;
	wc.hIcon			= NULL;
	wc.hInstance		= hInstance;
	wc.lpfnWndProc		= &WinProc;
	wc.lpszClassName	= "Fenetre GL";
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW;

	RegisterClass(&wc); 

	//on cree la fenetre
	hWnd = CreateWindow("Fenetre GL",
                        "Landscape",
                         WS_POPUP,
                         0,0,
                         GetSystemMetrics(SM_CXSCREEN),
                         GetSystemMetrics(SM_CYSCREEN),
                         NULL,
					     NULL,
                         hInstance,
                         NULL);

	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);
	ShowCursor(FALSE);		//on cache le curseur

	 while (GetMessage(&msg,NULL,0,0))
	 {
		 TranslateMessage(&msg);
		 DispatchMessage(&msg);
	 }

	return msg.wParam;
}



//----------------------------------------------------
//Met l'affichage en 32bits et specifie le backbuffer
//----------------------------------------------------
void SetupPixelFormat(HDC hDC)
{
	int pixelFormat;
    PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),
		1,
        PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        32,
        0, 0, 0, 0, 0, 0,
        0, 0,	
        0, 0, 0, 0, 0,
        32,
        0,
        0,
        0,
        0,
        0,
        0,
        0
	};

    pixelFormat = ChoosePixelFormat(hDC, &pfd);
    if (pixelFormat == 0)
	{
        MessageBox(NULL,"Mode graphique non supporté","Erreur",MB_OK);
        exit(1);
    }

    if (SetPixelFormat(hDC,pixelFormat,&pfd) != TRUE)
	{
		MessageBox(NULL,"Mode graphique non supporté","Erreur",MB_OK);
        exit(1);
    }
}


//---------------------------------
//Fonction de gestion des messages
//---------------------------------
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	HDC				hdc;
	PAINTSTRUCT		ps;
	static HGLRC	hrc;
	static double**	tableau			= NULL;
	//Variables pour le deplacement sur le terrain
	static int		anglex			= 0;
	static int		angley			= 0;
	static int		distance		= 25;
	static int		strafe			= 0;
	static int		hauteur			= 0;


	switch(msg)
	{
	case WM_CREATE:

		srand(GetTickCount());						//on initialise rand
		tableau = CalculLand(tailletableau,lisse);	//on genere le terrain

		if (tableau == NULL)
		{
			MessageBox(hWnd,"Erreur d'allocution de memoire","Erreur de memoire",MB_OK | MB_ICONEXCLAMATION);
			PostQuitMessage(0);
		}

		hdc=GetDC(hWnd);
		SetupPixelFormat(hdc); //on set le mode d'affichage
		hrc = wglCreateContext(hdc);		//On cree un rendering context
		if (!hrc)
			DestroyWindow(hWnd);
		wglMakeCurrent(hdc,hrc);		//on l'associe au DC
		break;

	case WM_DESTROY:

		wglMakeCurrent(NULL,NULL);		//on libere le RC
		if (hrc)
			wglDeleteContext(hrc);		//on le delete
		if (tableau != NULL)
			DeleteTableau2d(tableau,pow2[tailletableau]+1);		//on libere la memoire
		PostQuitMessage(0);
		break;

	case WM_SIZE:

		Reshape(LOWORD(lParam),HIWORD(lParam));		//on met a jour l'affichage
		break;

	case WM_KEYDOWN :
		InvalidateRect(hWnd,NULL,FALSE);		//on redessinne
		switch(wParam)
		{

		case VK_ESCAPE :
			DestroyWindow(hWnd);
			break;

		case 'R' :
			DeleteTableau2d(tableau,tailletableau);		//on delete le tableau
			tableau = CalculLand(tailletableau,lisse);			//on recalcule
			InvalidateRect(hWnd,NULL,FALSE);
			break;

//gestion du deplacement
		case VK_LEFT :
			angley++;
			break;
		case VK_RIGHT :
			angley--;
			break;
		case VK_UP :
			anglex++;
			break;
		case VK_DOWN :
			anglex--;
			break;
		case 'W' :
			distance--;
			break;
		case 'S' :
			distance++;
			break;
		case 'A' :
			strafe++;
			break;
		case 'D' :
			strafe--;
			break;
		case 'C' :
			hauteur--;
			break;
		case VK_SPACE :
			hauteur++;
			break;
		}
		break;
	case WM_PAINT:

		if (tableau != NULL)
		{
			hdc = BeginPaint(hWnd,&ps);
			Draw(hdc,tableau,pow2[tailletableau],anglex,angley,distance,strafe,hauteur);  //on Draw la scene
			EndPaint(hWnd,&ps);
		}
		break;
	}

	return DefWindowProc(hWnd,msg,wParam,lParam);
}


//-------------------
//Fonction de dessin
//-------------------
void Draw(HDC hdc,double **tableau,int indexmax,int anglex,int angley,int distance,int strafe,int hauteur)
{
	int i,j;

	glClearColor(0,0,0,0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		//on efface tout
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity(); 
	gluLookAt(0,0,25,0,0,0,0,1,0);				//on defini le point de vue
	glPushMatrix();	

//Gestion du deplacement
	glTranslated(strafe,-hauteur,-distance);
	glRotated(anglex,1,0,0);
	glRotated(-angley,0,1,0);
	


	glScaled(50.0/indexmax,50.0/indexmax,50.0/indexmax); //mise a l'echelle
	

//affichage
		for(i=0;i<indexmax;i++)
		{
			for(j=0;j<indexmax;j++)
			{
				glBegin(GL_LINE_LOOP);
				glVertex3i(i+1-indexmax/2	,(int)tableau[i+1][j]	,j-indexmax/2	);
				glVertex3i(i-indexmax/2		,(int)tableau[i][j]		,j-indexmax/2	);
				glVertex3i(i-indexmax/2		,(int)tableau[i][j+1]	,j+1-indexmax/2	);
				glVertex3i(i+1-indexmax/2	,(int)tableau[i+1][j]	,j-indexmax/2	);
				glVertex3i(i+1-indexmax/2	,(int)tableau[i+1][j+1]	,j+1-indexmax/2	);
				glVertex3i(i-indexmax/2		,(int)tableau[i][j+1]	,j+1-indexmax/2	);
				glEnd();
			}
		}

	glPopMatrix();
	SwapBuffers(hdc);
}


//---------------------------------------------------------
//Cree le landscape (retourne un pointeur vers le tableau)
//---------------------------------------------------------
double** CalculLand(int taille,double lisse)
{
//Pour l'explication lire le readme !

	double**	tableau;
	int			indexmax = pow2[taille];
	int			step;
	int			i;
	double		randRange = indexmax/2.0;


	if (lisse > 10)		//lisse compris entre 1.5 (horriblement escarpé)
		lisse = 10;		//et 10 (pas mal lisse)
	if (lisse <1.5)
		lisse = 1.5;
	
	if (taille < 1 )	//on verifie que la taille ne soit pas trop grande (affichage tres long)
		taille = 1;		//et qu'elle soit au moins de 1
	if (taille > 11 )
		taille = 11;



	tableau = CreateTableau2d(indexmax+1);		//Creation du tableau

	if(tableau == NULL)
		return tableau;

	//initialisation des 4 coins du tableau (on peut mettre une autre valeur)
	tableau[0][0]				= 0;
	tableau[0][indexmax]		= 0;
	tableau[indexmax][indexmax] = 0;
	tableau[indexmax][0]		= 0;

	step = indexmax;

	for(i = 0;i<taille;i++)		//on genere le terrain
	{	
		SquareStep(tableau,i,step,randRange);
		DiamondStep(tableau,i,step,randRange,indexmax);

		if (randRange > 1)
			randRange /= lisse; 
		if (randRange < 1)  //pour eviter le x%0 qui n'existe pas
			randRange = 1;

		step /= 2;
	}

	return tableau;
}


//---------------------------------------
//1ere etape de generation (voir readme)
//---------------------------------------
void SquareStep(double **tableau,int nb_passes,int step,double randRange)
{
	int debI,midI,finI;
	int debJ,midJ,finJ;
	int i,j;

	debI =	0;
	midI = step/2;
	finI = step;

	for(i=0;i<pow2[nb_passes];i++)
	{
		debJ = 0;			//on revient a 0 pour une autre boucle
		midJ = step/2;
		finJ = step;

		for(j=0;j<pow2[nb_passes];j++)
		{
//On fait la moyenne des cases avoisinantes + un nombre compris en -randRange et +randRange
			tableau[midI][midJ] = (tableau[debI][debJ] + tableau[debI][finJ] + tableau[finI][finJ] + tableau[finI][debJ] ) /4.0 + (rand()%((int)randRange*2))-randRange;

			debJ += step;		//on incremente
			midJ += step;
			finJ += step;
		}

		debI += step;		//incrementation
		midI += step;
		finI += step;
	}
}


//-----------
//2eme etape
//-----------
void DiamondStep(double **tableau,int nb_passes,int step,double randRange,int indexmax)
{
	int debI,midI,finI;
	int debJ,midJ,finJ;
	int i,j;
	int halfstep = step/2;		//pour eviter les step/2 tout le temps
	
	midI = 0;
	debI = indexmax-halfstep;
	finI = halfstep;

	for(i=0;i<pow2[nb_passes+1];i++)
	{
		if(i%2)
		{
			midJ = 0;
			debJ = indexmax-halfstep;
			finJ = halfstep;
		}
		else
		{
			midJ = halfstep;
			debJ = 0;
			finJ = step;
		}

		for(j=0;j<pow2[nb_passes];j++)
		{
			//Moyenne + nombre entre -randRange et +randRange
			tableau[midI][midJ] = (tableau[midI][debJ] + tableau[midI][finJ] + tableau[debI][midJ] + tableau[finI][midJ]) /4.0 + (rand()%((int)randRange*2))-randRange;

			debJ = (debJ+step)%indexmax;		//explication dans le readme
			midJ += step;
			finJ += step;
		}

		debI = (debI+halfstep) % indexmax;
		midI += halfstep;
		finI += halfstep;
	}

	//Recopiage des extremites
	midI = halfstep;
	for(i=0;i<pow2[nb_passes];i++)
	{
		tableau[indexmax][midI] = tableau[0][midI];
		tableau[midI][indexmax] = tableau[midI][0];
		midI += step;
	}

}


//-------------------------------
//Cree un tableau a 2 dimensions
//-------------------------------
double** CreateTableau2d(int taille)
{
	double** tableau;
	int i;

	tableau = new double*[taille];
	if(tableau != NULL)
	{
		for(i=0;i<taille;i++)
		{
			tableau[i] = new double[taille];

			if (tableau[i] == NULL)		//si erreur on delete
			{
				DeleteTableau2d(tableau,taille);
				return NULL;				
			}

		}
	}
	return tableau;
}


//---------------------------------
//Delete le tableau a 2 dimensions
//---------------------------------
void DeleteTableau2d(double **tableau,int taille)
{
	int i;

	for(i=0;i<taille;i++)
	{
		if (tableau[i] != NULL)		//on verifie que le pointeur ne soit pas null
			delete[] tableau[i];
	}

	delete[] tableau;
}


//-------------------------------------------------------
//Definition de la perspective et de la zone d'affichage
//-------------------------------------------------------
void Reshape(int width,int height)
{
	glViewport(0,0,width,height);	//on defini la taille
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0,(GLdouble) width/height,0,500);
}
  

 Conclusion

Je trouve que l'algo de génération n'est pas évident du premier coup mais allez vois dans le zip lire le readme et vous devriez comprendre.
Je suis pas super fort pour expliquer alors dites moi si vous trouvez l'explication peu claire

Je ne suis pas tres fort en openGL , surtout gestion des lumieres car je voulais faire une version en affichage par exemple tout en blanc et avec les lumieres ça aurait rendu quelque chose mais sans ...
En fait j'arrive a mettre les lumieres mais elles n'eclairent pas comme je le veux. Si quelqu'un peut m'aider..  

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture DETECTION DE CONTOURS
Source avec Zip Source avec une capture ASCII ART : BMP TO HTM - TRANSFORME UNE IMAGE EN FICHIER HT...
Source avec Zip ETIRER/RÉTRÉCIR UNE IMAGE BMP SANS STRETCHBLT
Source avec Zip Source avec une capture BITMAP24 TO TEXT - TRANSFORME UNE IMAGE EN TEXTE VC++
Source avec Zip RESOLUTION D'EQUATIONS DE DEGRÉ 4 OU INFERIEUR

 Sources de la même categorie

Source avec une capture HALLEY MAP par valchek
Source avec Zip Source avec une capture DIGITALISER UN RUBIK'S CUBE À L'AIDE D'UN SCANNER À PLAT. par AffreuxJojp
WXFREECHART PIEPLOT EXAMPLE par neria
Source avec Zip Source avec une capture [WIN32][CB]CRÉATION DIRECTE DE PDF par omnia
Source avec Zip Source avec une capture ENCODAGE D'ANIMATIONS QT AU FORMAT GIF par opossum_farceur

Commentaires et avis

Commentaire de houmiak le 27/08/2003 13:33:00

salut!
j'aimes bien ton prog, le paysage généré est pas mal :o)
j'ai actuellement un debut d'embryon de moteur de paysage en DirectX qui genere un paysage, mais a partir d'un Heighmap.
le paysage est texturé et l'eclairage est géré.
je vais essayer d'integrer ta génération a mon programmes si tu es d'accord
a bientot

Commentaire de Maegis le 27/08/2003 21:52:36

Ok pas de probleme

Commentaire de houmiak le 03/09/2003 17:11:20

c'est une implementation du "diamond square algorithm", neanmoin, ta facon de coder est quelque peu 'particuliere'. j'ai eu du mal a comprendre tes tableaux 2d, qui se revelent etre peu efficaces et pas optimisées. par contre, une version recursive existe de l'algorithme, qui est nettement plus efficace. je fais des tests et je te tient au courant...

Commentaire de Maegis le 16/09/2003 19:46:46

Si tu a regardé dans le zip (et c'est même inscrit tout en haut) , j'ai fait ce prog suite a un article dans un magazine avec le code en ADA.
Il y avait une explication de la méthode et il était dit qu'une méthode récursive était très longue et moins adaptée pour des tableaux un peu grand.
Si j'aurais eu a faire tout cela de moi même, j'aurais certainement utilisé une méthode recursive.
Par contre pour l'histoire des tableaux 2d, je serait intéresé de savoir comment tu stocke les differentes hauteurs.
Et si tu as un line vers une page contenant cette méthode récursive,....

Commentaire de houmiak le 16/09/2003 20:43:39

bien sur, il y a ca:
http://www.gameprogrammer.com/fractal.html

et un article sur l'excellent site flipcode:
http://www.flipcode.com/tfiles/alexc06.shtml

pour les différent algo, je pense que google trouvera mieu que moi.

quand aux tableau, pour qu'il soient rapides, il vaut mieu grouper les données, donc eviter les doubles pointeur(catastrophique pour les caches).

donc un tableau a deux dimension : int tab2D[dim1][dim2];
ou encore (ce qui est équivalent) int tab2D[dim1*dim2];
pour accéder a la case (x,y):
tab2D[x][y];
ou encore
tab[x + y*dim1];

sinon, pour voir comment je gere mes tableaux, va voir ma source:
http://www.cppfrance.com/article.aspx?Val=2531
voili :o)

Commentaire de Maegis le 16/09/2003 22:34:05

A daccord j'avais pas pensé à ça. Bon faire un seul tableau ça évite les pointeurs sur pointeurs mais tu fais une multiplication à chaque fois... je ne sais pas si l'on s'y retrouve
En tout cas merci

Commentaire de houmiak le 17/09/2003 08:38:55

en groupant tes donnée localement, tu as de grandes chances de retrouver dans ton cache la donnée que tu vas utiliser au prochain step de ton prog (les ram et les caches L2 des CPU transfèrent souvent des bloc, pas une donnée) donc avec un tel tableau (a condition de le parcourir inteligemment), ce que tu perd en multiplication, tu le gagne largement en latence mémoire.
de plus, si tu commence a envisager des calcul vectoriel, une telle organisation est indispensable pour de bonnes performances.
a bientot ;o)

Commentaire de kidpigeyre le 18/11/2003 16:09:35

Bonjour,

J'ai longuement regardé ton programme car je dois réaliser un logiciel de modélisation et statistiques en un ensemble de montagne 3D.

Cependant, lors de l'éxécution de ton programme, je trouve un problème d'affichage. En effet certain point lors d'une rotation par les fleches de mouvements ne sont plus reliés par des filaments, on ne les voit plus, ainsi lorsque j'ai essayé d'y rajouter les textures, j'ai des plaques noires ou il y a rien.

Je n'ai aps bien compris ton système pour dessiner les vecteurs dans la fonction draw.

Tu pourrais me l'expliquer? Jpense que ça vient d'ici mais je ne suis pas sur.

Mci.

Romain

Commentaire de Maegis le 18/11/2003 23:23:35

kidpigeyre je t'ai envoyé la réponse en MP

Commentaire de DedeSurf le 21/05/2004 14:05:45

Salut,
Il faut dire que sa vaut le coup d'oeil
je mettrai 8/10 a 9/10, j'y réfflaichirais !
Thyraël

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Septembre 2010
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
27282930   

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,593 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales