c'est une application qui affiche un terrain en projection orthogonale dimetrique. une projection dimétrique est une projection gardant les projections de 2 axes (une projection isometrique garde les proportions des 3 axes) . cette projection est faite à l'aide d'une matrice de transformation Opengl
la projection permet de changer l'inclinaison du terrain et de le faire tourner mais je n'ai pas implementer de depth sorting et en regardant le terrain de l'arriere on voit les faces avant .
->click gauche sur l'eau : crée des vagues
-> drag click droit : scroll (translate) le terrain
-> drag click milieu : change l'echelle (scale) le terrain
-> drag click gauche+droite : change l'inclinaison et la rotation du terrain
le programme tourne à 75fps sur mon ordinateur (Geforce 2 MX T_T): je pense qu'il n'est limité que par le nombre de polygones à affiché (128*128)
l'executable est trop gros pour le zip
mais vous pouvez le trouver sur
http://matt2000.free.fr/release.rar ainsi que des textures non compressés
Source / Exemple :
void CTerrainNode::Draw() {
GLdouble model[16], proj[4][4];
GLint view[4];
glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]);
glGetIntegerv(GL_VIEWPORT, &view[0]);
double x,y,z;
char tmp[32];
unsigned char white[] = { 255,255,255 },height;
short mx = WindowMaker->mouse.x;
short my = WindowMaker->mouse.y;
/**
Projection setting
glPushMatrix();
float matrix[16]= { sqrt(2)*0.5 , -sqrt(2)*0.5*sin((float)(256-View->camera.ry)/256) , 0 , 0,
-sqrt(2)*0.5 , -sqrt(2)*0.5*sin((float)(256-View->camera.ry)/256) , 0 , 0,
0 , cos((256-View->camera.ry)/256) , 1 , 0,
View->camera.x , View->camera.y , 0 , 1 };
glLoadMatrixf(matrix);
glRotatef((-View->camera.rx+128)/2.8,0,0,1);
glScalef((float)View->camera.zoom/8,(float)View->camera.zoom/8,(float)View->camera.zoom/16);
/**
Terrain rendering
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, tilemap->id );
for(int i=0;i<heightmap->height-1;i++) {
for(int j=0;j<heightmap->width-1;j++) {
glBegin(GL_QUADS);
glTexCoord2f((float)i/heightmap->width,(float)j/heightmap->height);
glVertex3f(i ,j ,heightmap->get(i,j,0));
glTexCoord2f((float)(i+1)/heightmap->width,(float)(j)/heightmap->height);
glVertex3f(i+1 ,j ,heightmap->get(i+1,j,0));
glTexCoord2f((float)(i+1)/heightmap->width,(float)(j+1)/heightmap->height);
glVertex3f(i+1 ,j+1 ,heightmap->get(i+1,j+1,0));
glTexCoord2f((float)(i)/heightmap->width,(float)(j+1)/heightmap->height);
glVertex3f(i ,j+1 ,heightmap->get(i,j+1,0));
glEnd();
}
}
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
/**
retrieve the mouse position on the terrain
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
double right[3];
right[0] = model[0];
right[1] = model[4];
right[2] = model[8];
float w;
glReadPixels(mx,768-my,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&w); //read pixel (GL_FLOAT) return a float not a double
z = w;
gluUnProject( mx,768-my,z,&model[0], &proj[0][0], &view[0], &x, &y,&z);
ix = x+0;
iy = y+0;
if(ix>127) ix = 127; else if(ix<0) ix = 0;
if(iy>127) iy = 127; else if(iy<0) iy = 0;
glColor4ub(255,0,0,128);
glBegin(GL_QUADS);
glVertex3f(ix ,iy ,heightmap->get(ix,iy,0));
glVertex3f(ix+1 ,iy ,heightmap->get(ix+1,iy,0));
glVertex3f(ix+1 ,iy+1 ,heightmap->get(ix+1,iy+1,0));
glVertex3f(ix ,iy+1 ,heightmap->get(ix,iy+1,0));
glEnd();
/**
Object (tree,building) rendering using point sprite extension
glPointSize((float)View->camera.zoom/4);
glTexEnvf (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glEnable (GL_POINT_SPRITE);
glEnable(GL_TEXTURE_2D);
glColor3ub(255,255,255);
for(int i=0;i<heightmap->height-1;i++) {
for(int j=0;j<heightmap->width-1;j++) {
if( objectmap->get(i,j,0) && objectmap->get(i,j,0) <= nofObject ) {
glBindTexture( GL_TEXTURE_2D, object [ objectmap->get(i,j,0) ].id );
glBegin(GL_POINTS);
glVertex3f(i+0.5,j+0.5,heightmap->get(i,j,0));
glEnd();
}
}
}
glPointSize(16);
glDisable (GL_POINT_SPRITE);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glColor4ub(96,192,255,64);
for(int i=0;i<heightmap->height-1;i++) {
for(int j=0;j<heightmap->width-1;j++) {
if(heightmap->get(i,j,0) < 64) {
glBegin(GL_QUADS);
//glTexCoord2f((float)i/heightmap->width,(float)j/heightmap->height);
glVertex3f(i ,j ,64+((float)wavemap[(i+j*128)*2+swap]/32));
//glTexCoord2f((float)(i+1)/heightmap->width,(float)(j)/heightmap->height);
glVertex3f(i-1 ,j ,64+((float)wavemap[(i-1+j*128)*2+swap]/32));
//glTexCoord2f((float)(i+1)/heightmap->width,(float)(j+1)/heightmap->height);
glVertex3f(i-1 ,j-1 ,64+((float)wavemap[(i-1+(j-1)*128)*2+swap]/32));
//glTexCoord2f((float)(i)/heightmap->width,(float)(j+1)/heightmap->height);
glVertex3f(i ,j-1 ,64+((float)wavemap[(i+(j-1)*128)*2+swap]/32));
glEnd();
}
}
}
glDisable(GL_DEPTH_TEST);
sprintf(tmp," x %i y %i z %0.0f",ix,iy,z);
gl.DrawText2D(128,128,white,2.0f,0,tmp);
glPopMatrix();
Conclusion :
Features :
-projection dimétrique d'un terrain heightmappé et texturé
-Loader de texture tga,bmp & jpg
-selection de la case sous la souris
-affichage d'objet(arbres,batiments) (utilise l'extension point_sprite )
-simulation de l'eau ( vague )
Todo :
-lorsque j'aurai un carte graphique correcte, j'utiliserai l'extension frame buffer object pour faire le reflet de l'eau et ne rerendre qu'une partie de l'écran lors des translations
-possibilité de creation de route
-possibilité de creer un batiment -> selection du batiment -> debut d'interface pour créer des bonhommes
-pathfinding
-un vrai jeu ?
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.