Accueil > > > LANDSCAPE GL : GÉNÉRATION DE PAYSAGE EN 3D
LANDSCAPE GL : GÉNÉRATION DE PAYSAGE EN 3D
Information sur la source
Description
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..
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
ARTICLE DANS PROGRAMMEZ SUR LES PRINCIPES SOLIDARTICLE DANS PROGRAMMEZ SUR LES PRINCIPES SOLID par fathi
Hello tout le monde! J'ai pas pu blogger ces derniers temps car j'ai eu un (heureux) petit chamboulement dans ma vie perso (un "bug" de 3.8 kg et de 52 cm) J'en profite juste pour vous annoncer la parution d'un article sur les principes SOLID ...
Cliquez pour lire la suite de l'article par fathi PARUTION DE MON LIVRE SUR WPF 4PARUTION DE MON LIVRE SUR WPF 4 par odewit
La 2e édition de mon livre sur WPF sort aujourd'hui en version numérique et lundi en version papier :-)
L'ouvrage présente de façon approfondie les fonctionnalités de WPF 4 : graphisme 2D et 3D, animation, multimédia, interfaces utilisateur, databind...
Cliquez pour lire la suite de l'article par odewit EDM : COMMENT UTILISER L'HORIZONTAL ENTITY SPLITTINGEDM : COMMENT UTILISER L'HORIZONTAL ENTITY SPLITTING par Matthieu MEZIL
Une des raisons pour lesquelles j'adore l'Entity Framework est la puissance de son mapping. Beaucoup de développeurs pour ne pas dire la plus part n'en n'ont pas conscience. Pour rappel, j'ai réalisé des videos (en anglais) sur le mapping . Certains scena...
Cliquez pour lire la suite de l'article par Matthieu MEZIL [WP7DEV][REACTIVE] RENDRE LES REACTIVE EXTENSIONS PLUS STABLES[WP7DEV][REACTIVE] RENDRE LES REACTIVE EXTENSIONS PLUS STABLES par jay
Lorsque l'on développe des applications .NET, les exceptions non gérées dans des threads ont le désagréable effet de terminer le processus courant.
Dans l'exemple suivant.......(read more) ...
Cliquez pour lire la suite de l'article par jay
Forum
DE L'AIIIDE!!DE L'AIIIDE!! par eliramomo
Cliquez pour lire la suite par eliramomo
Logiciels
Microsoft Office (2010)MICROSOFT OFFICE (2010)Microsoft Office 2010 offre de nouveaux moyens flexibles et puissants pour optimiser votre travai... Cliquez pour télécharger Microsoft Office SeaMonkey (2.0.7)SEAMONKEY (2.0.7)Le projet SeaMonkey est issu d'un effort communautaire pour developper une application tout en un... Cliquez pour télécharger SeaMonkey Safari (5.0.2)SAFARI (5.0.2)Le navigateur d'Apple a lui aussi été mis à jour, aussi bien dans sa mouture Windows que celle po... Cliquez pour télécharger Safari Mozilla FireFox (4.0 béta 5)MOZILLA FIREFOX (4.0 BéTA 5)Firefox 4.0 béta 5
L'une des nouveautés visibles les plus attendues réside sans doute dans l'a... Cliquez pour télécharger Mozilla FireFox Mozilla Firefox (3.6.9)MOZILLA FIREFOX (3.6.9)Firefox 3.6.9 corrige les problèmes suivants :
* Introduced support for the X-FRAME-OPTION... Cliquez pour télécharger Mozilla Firefox
|