Bonjour à tous,
Et oui encore moi pour une question, que dis-je, une mission pour une âme charitable.
Je suis en train de faire un labyrinthe en 3D style l'écran de veille de windows, mais j'ai un pb de déplacement de caméra et aussi de collisions.
Je vous lache le code. Si vous voulez y jeter un coup d'oeil, me dire ce qu'il y a à améliorer, je vous remercie franchement. Sinon, c'est pas grave, je retravaille dessus demain, pasque là, je commence à en avoir marre d'opengl...
Enfin, merci d'avance en tout cas.
...Gast...Voici le code :
HEADER.H *********************
/** INCLUDES ***********************************************************************************/
#include<stdio.h>
#include<glut.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
/** DEFINITIONS ********************************************************************************/
#define EXIT {fclose(fichier);return -1;}
#define CTOI(C) (*(int*)&C) //récupère en int un nombre pointé par un char*
/** STRUCTURES *********************************************************************************/
struct StructTex
{
GLint NbCouleurs; //Components
GLsizei Largeur; //Width
GLsizei Hauteur; //Height
GLenum TypeCouleurs; //format
GLenum CodageCouleurs; //codage des couleurs
unsigned char* Data; //Tableau des données
};
/** VARIABLES **********************************************************************************/
char g_tniveau[10][10]={' '};
int X_j;
int Y_j;
GLuint Nom;
double a=0;
struct StructTex UneTexture[5];
GLuint TextureName[3];
/*float ptvueX;
float ptvueY;
float poscamX;
float poscamY;*/
float ptvueX=0;
float ptvueY=0;
float poscamX=-5;
float poscamY=-5;
float angle=90;
bool init=false;
/** FONCTIONS **********************************************************************************/
void Affiche_niveau();
void AfficheSoluce();
void ActiveTexture(int No);
void Chargement_niveau();
void clavier(unsigned char touche, int x, int y);
void clavier_soluce(unsigned char touche, int x, int y);
void Dessine_Labyrinthe();
void Dessine_Labyrinthe_Couleur();
void dessine_murs(int i, int j);
void display();
void display_soluce();
void init_puzzle();
void InitGL();
int LoadBMP(char *File, struct StructTex* UneTexture);
bool RechercheCoord(float coordX, float coordY);
bool RechercheSortie(float coordX, float coordY);
void reshape(int largeur, int hauteur);
void reshape_soluce(int largeur, int hauteur);
MAIN.CPP *************************
#include"header.h"
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
X_j=500;
Y_j=500;
// INIT DE LA FENETRE
glutInitWindowPosition(100,100);
glutInitWindowSize(X_j,Y_j);
glutCreateWindow("Labyrinthe");
// Chargement des éléments externes
InitGL();
Chargement_niveau();
// CALLBACKS
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(clavier);
glutMainLoop();
}
//// CALLBACKS ///////////////////////////////////////////////////////////////////////////////////
/*** DISPLAY ************************************************************************************/
void display()
/************************************************************************************************/
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(RechercheSortie(poscamX,poscamY))
{
gluLookAt(-10,-10,5,5,5,5,0,0,1);
// Affichage du texte du gagnant
char *c;
glColor3ub(255,255,255);
glRasterPos3f(0,0,5);
for(c="BRAVO !";*c!='\0';c++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,*c);
}
else
{
gluLookAt(poscamX,poscamY,-0.5,ptvueX,ptvueY,-0.5,0,0,1);
//gluLookAt(-5,-5,20,ptvueX,ptvueY,0,0,0,1);
glRotated(0,0,1,0);
Dessine_Labyrinthe_Couleur();
}
// Affichage du copyright
char *c;
glColor3ub(255,255,255);
glRasterPos3f(10,70,40);
for(c="Par Gaetan SOPPE - CSII2005";*c!='\0';c++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,*c);
glutSwapBuffers();
}
/*** DISPLAY ************************************************************************************/
void display_soluce()
/************************************************************************************************/
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,10,0,0,-100,0,1,0);
Dessine_Labyrinthe_Couleur();
glutSwapBuffers();
}
/************************************************************************************************/
/*** RESHAPE ************************************************************************************/
void reshape(int largeur, int hauteur)
/************************************************************************************************/
{
glViewport(0,0,largeur,hauteur);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80.0,(double)largeur/hauteur,1.0,100.0);
}
/*** RESHAPE ************************************************************************************/
void reshape_soluce(int largeur, int hauteur)
/************************************************************************************************/
{
glViewport(0,0,largeur,hauteur);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80.0,(double)largeur/hauteur,1.0,100.0);
}
/************************************************************************************************/
/*** CLAVIER ************************************************************************************/
void clavier(unsigned char touche, int x, int y)
/************************************************************************************************/
{
float R=sqrt(pow(poscamX-ptvueX,2)+pow(poscamY-ptvueY,2));
float tempX,tempY;
switch(touche)
{
case 'e':
// On avance
tempX=poscamX-(poscamX-ptvueX)/R;
tempY=poscamY-(poscamY-ptvueY)/R;
// on vérifie qu'on n'est pas dans un mur
if(!RechercheCoord(tempX,tempY))
{
poscamX=tempX;
poscamY=tempY;
}
break;
case 'x':
// On recule
tempX=poscamX+(poscamX-ptvueX)/R;
tempY=poscamY+(poscamY-ptvueY)/R;
// on vérifie qu'on n'est pas dans un mur
if(!RechercheCoord(tempX,tempY))
{
poscamX=tempX;
poscamY=tempY;
}
break;
case 's':
// On tourne vers la gauche
angle=angle+0.1;
ptvueX=poscamX+R*cos(angle);
ptvueY=poscamY+R*sin(angle);
break;
case 'd':
// On tourne vers la droite
angle=angle-0.1;
ptvueX=poscamX+R*cos(angle);
ptvueY=poscamY+R*sin(angle);
break;
case 9:
AfficheSoluce();
break;
case 27:
exit(0);
}
glutPostRedisplay();
}
/************************************************************************************************/
/************************************************************************************************/
void clavier_soluce(unsigned char touche, int x, int y)
/************************************************************************************************/
{
switch(touche)
{
case 9:
glutDestroyWindow(glutGetWindow());
break;
}
}
/************************************************************************************************/
//// FONCTIONS ///////////////////////////////////////////////////////////////////////////////////
/************************************************************************************************/
void Chargement_niveau()
/************************************************************************************************/
{
FILE *fichier;
int cpti=0;
int cptj=0;
char ch;
// Charge le niveau
fichier=fopen("laby.txt","rt");
if(fichier!=NULL)
{
fgets(&ch,2,fichier);
while(!feof(fichier))
{
if(ch!='\n')
{
if(ch=='D')
{
poscamX=cpti-5+0.5;
poscamY=5-cptj-0.5;
ptvueX=poscamX;
ptvueY=poscamY+10;
}
g_tniveau[cpti][cptj]=ch;
cptj++;
if(cptj==10)
{
cpti++;
cptj=0;
}
}
fgets(&ch,2,fichier);
}
}
fclose(fichier);
}
/************************************************************************************************/
/************************************************************************************************/
int LoadBMP(char *File, struct StructTex* UneTexture)
/************************************************************************************************/
{
unsigned char *Data;
FILE *fichier;
unsigned char Header[0x36];
GLuint DataPos,DataSize;
GLint Components;
GLsizei Width,Height;
GLenum Format,Type;
//GLuint Name[1];
//Lit le fichier et son header
fichier = fopen(File,"rb");if (!fichier) return -1;
if (fread(Header,1,0x36,fichier)!=0x36) EXIT;
if (Header[0]!='B' || Header[1]!='M') EXIT;
if (CTOI(Header[0x1E])!=0) EXIT;
if (CTOI(Header[0x1C])!=24) EXIT;
//Récupère les infos du fichier
DataPos = CTOI(Header[0x0A]);
DataSize = CTOI(Header[0x22]);
//Récupère les infos de l'image
Width = CTOI(Header[0x12]);
Height = CTOI(Header[0x16]);
Type = GL_UNSIGNED_BYTE;
Format = GL_RGB;
Components = 3;
//!!!!
if (DataSize==0) DataSize=Width*Height*Components;
if (DataPos==0) DataPos=0x36;
//Charge l'image
fseek(fichier,DataPos,0);
Data = new unsigned char[DataSize];
if (!Data) EXIT;
if (fread(Data,1,DataSize,fichier)!=DataSize)
{
delete Data;
fclose(fichier);
return -1;
}
fclose(fichier);
//Inverse R et B
unsigned char t;
for (int x=0;x<Width*Height;x++)
{
t=Data[x*3];
Data[x*3]=Data[x*3+2];
Data[x*3+2]=t;
}
//Envoie la texture à OpenGL
UneTexture->NbCouleurs = Components;
UneTexture->Largeur = Width;
UneTexture->Hauteur = Height;
UneTexture->TypeCouleurs = Format;
UneTexture->CodageCouleurs = Type;
UneTexture->Data = Data;
return 1;
}
/************************************************************************************************/
/************************************************************************************************/
void InitGL()
/************************************************************************************************/
{
glClearColor(1.0, 1.0, 1.0, 1.0 );
glEnable(GL_TEXTURE_2D);
// on charge l'image "mur" en mémoire
Nom = LoadBMP("ciel.bmp", UneTexture);
// on charge l'image "ciel" en mémoire
Nom = LoadBMP("mur.bmp", UneTexture+1);
// on charge l'image "sol" en mémoire
Nom = LoadBMP("sol.bmp", UneTexture+2);
// on récupère 3 identifiants de textures
glGenTextures(3, TextureName);
// préparation de la texture 1
glBindTexture(GL_TEXTURE_2D, TextureName[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
// préparation de la texture 2
glBindTexture(GL_TEXTURE_2D, TextureName[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
// préparation de la texture 3
glBindTexture(GL_TEXTURE_2D, TextureName[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
/************************************************************************************************/
/************************************************************************************************/
void ActiveTexture(int No)
/************************************************************************************************/
{
glTexImage2D
(
GL_TEXTURE_2D, //target
0, //mipmap level
UneTexture[No].NbCouleurs, //nb couleurs
UneTexture[No].Largeur, //largeur
UneTexture[No].Hauteur, //hauteur
0, //largeur du bord
UneTexture[No].TypeCouleurs, //type des couleurs
UneTexture[No].CodageCouleurs, //codage de chaque composante
UneTexture[No].Data //Image BMP
);
}
/************************************************************************************************/
/************************************************************************************************/
void Dessine_Labyrinthe()
/************************************************************************************************/
{
// Dessin du sol
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureName[2]);
glColor3ub(255,255,255);
ActiveTexture(2);
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3d(-5,-5,-1);
glTexCoord2i(0,1);
glVertex3d(-5,5,-1);
glTexCoord2i(1,1);
glVertex3d(5,5,-1);
glTexCoord2i(1,0);
glVertex3d(5,-5,-1);
glEnd();
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
switch(g_tniveau[j][i])
{
case '1':
glBindTexture(GL_TEXTURE_2D, TextureName[1]);
ActiveTexture(1);
// FACE
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3d(i-5,5-j-1,10);
glTexCoord2i(0,10);
glVertex3d(i-5,5-j,10);
glTexCoord2i(10,10);
glVertex3d(i-5+1,5-j,10);
glTexCoord2i(10,0);
glVertex3d(i-5+1,5-j-1,10);
glEnd();
// DESSOUS
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3d(i-5,5-j-1,-1);
glTexCoord2i(0,10);
glVertex3d(i-5,5-j,-1);
glTexCoord2i(10,10);
glVertex3d(i-5+1,5-j,-1);
glTexCoord2i(10,0);
glVertex3d(i-5+1,5-j-1,-1);
glEnd();
// GAUCHE
glBegin(GL_QUADS);
glTexCoord2i(0,10);
glVertex3d(i-5,5-j-1,10);
glTexCoord2i(0,0);
glVertex3d(i-5,5-j-1,-1);
glTexCoord2i(10,0);
glVertex3d(i-5+1,5-j-1,-1);
glTexCoord2i(10,10);
glVertex3d(i-5+1,5-j-1,10);
glEnd();
// DROITE
glBegin(GL_QUADS);
glTexCoord2i(0,10);
glVertex3d(i-5+1,5-j,10);
glTexCoord2i(0,0);
glVertex3d(i-5+1,5-j,-1);
glTexCoord2i(10,0);
glVertex3d(i-5+1,5-j-1,-1);
glTexCoord2i(10,10);
glVertex3d(i-5+1,5-j-1,10);
glEnd();
// BAS
glBegin(GL_QUADS);
glTexCoord2i(0,10);
glVertex3d(i-5,5-j-1,10);
glTexCoord2i(0,0);
glVertex3d(i-5,5-j-1,-1);
glTexCoord2i(10,0);
glVertex3d(i-5+1,5-j-1,-1);
glTexCoord2i(10,10);
glVertex3d(i-5+1,5-j-1,10);
glEnd();
// HAUT
glBegin(GL_QUADS);
glTexCoord2i(0,10);
glVertex3d(i-5,5-j,10);
glTexCoord2i(0,0);
glVertex3d(i-5,5-j,-1);
glTexCoord2i(10,0);
glVertex3d(i-5+1,5-j,-1);
glTexCoord2i(10,10);
glVertex3d(i-5+1,5-j,10);
glEnd();
break;
}
}
}
// Dessin du ciel
glBindTexture(GL_TEXTURE_2D, TextureName[0]);
ActiveTexture(0);
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3d(-5,-5,10);
glTexCoord2i(0,1);
glVertex3d(-5,5,10);
glTexCoord2i(1,1);
glVertex3d(5,5,10);
glTexCoord2i(1,0);
glVertex3d(5,-5,10);
glEnd();
}
/************************************************************************************************/
/************************************************************************************************/
bool RechercheCoord(float coordX, float coordY)
/************************************************************************************************/
{
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
if(coordX>i-5 && coordX<i-5+1 && coordY<5-j && coordY>5-j-1 && g_tniveau[i][j]!='S')
return false;
return true;
}
/************************************************************************************************/
/************************************************************************************************/
bool RechercheSortie(float coordX, float coordY)
/************************************************************************************************/
{
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
if(coordX>i-5 && coordX<i-5+1 && coordY<5-j && coordY>5-j-1 && g_tniveau[i][j]=='S')
return true;
return false;
}
/************************************************************************************************/
/************************************************************************************************/
void Dessine_Labyrinthe_Couleur()
/************************************************************************************************/
{
// Dessin du sol
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureName[2]);
glColor3ub(255,0,0);
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3d(-5,-5,-1);
glTexCoord2i(0,1);
glVertex3d(-5,5,-1);
glTexCoord2i(1,1);
glVertex3d(5,5,-1);
glTexCoord2i(1,0);
glVertex3d(5,-5,-1);
glEnd();
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
switch(g_tniveau[j][i])
{
case '1':
glColor3ub(0,255,0);
dessine_murs(i,j);
break;
case 'S':
glColor3ub(0,0,255);
dessine_murs(i,j);
break;
case 'D':
glColor3ub(127,127,127);
dessine_murs(i,j);
break;
default:
if(poscamX>i-5 && poscamX<i-5+1 && poscamY<5-j && poscamY>5-j-1)
{
glColor3ub(10,127,10);
dessine_murs(i,j);
}
break;
}
}
}
}
/************************************************************************************************/
/************************************************************************************************/
void AfficheSoluce()
/************************************************************************************************/
{
glutInitWindowSize(X_j,Y_j);
glutInitWindowPosition(400,100);
glutCreateWindow("Solution du labyrinthe");
glutDisplayFunc(display_soluce);
glutReshapeFunc(reshape_soluce);
glutKeyboardFunc(clavier_soluce);
}
/************************************************************************************************/
void dessine_murs(int i, int j)
{
// FACE
glBegin(GL_QUADS);
glVertex3d(i-5,5-j-1,0);
glVertex3d(i-5,5-j,0);
glVertex3d(i-5+1,5-j,0);
glVertex3d(i-5+1,5-j-1,0);
glEnd();
// DESSOUS
glBegin(GL_QUADS);
glVertex3d(i-5,5-j-1,-1);
glVertex3d(i-5,5-j,-1);
glVertex3d(i-5+1,5-j,-1);
glVertex3d(i-5+1,5-j-1,-1);
glEnd();
// GAUCHE
glBegin(GL_QUADS);
glVertex3d(i-5,5-j-1,0);
glVertex3d(i-5,5-j-1,-1);
glVertex3d(i-5+1,5-j-1,-1);
glVertex3d(i-5+1,5-j-1,0);
glEnd();
// DROITE
glBegin(GL_QUADS);
glVertex3d(i-5+1,5-j,0);
glVertex3d(i-5+1,5-j,-1);
glVertex3d(i-5+1,5-j-1,-1);
glVertex3d(i-5+1,5-j-1,0);
glEnd();
// BAS
glBegin(GL_QUADS);
glVertex3d(i-5,5-j-1,0);
glVertex3d(i-5,5-j-1,-1);
glVertex3d(i-5+1,5-j-1,-1);
glVertex3d(i-5+1,5-j-1,0);
glEnd();
// HAUT
glBegin(GL_QUADS);
glVertex3d(i-5,5-j,0);
glVertex3d(i-5,5-j,-1);
glVertex3d(i-5+1,5-j,-1);
glVertex3d(i-5+1,5-j,0);
glEnd();
}