Petit jeu en OpenGL

Salut à tous!

Voilà, je suis en train de développer un petit jeu de bataille navale en C, en utilisant l’openGL (la librairie GLUT parce qu’il parait que c’est la plus simple).
Je débute en OpenGL, et j’ai un peu de mal, donc je viens vous demander de l’aide :stuck_out_tongue:

Premièrement, voici le code de mon jeu.
Pour le moment, tout ce qu’il fait c’est afficher la grille de la bataille navale, au moyen d’une fonction appelée tableaugl que j’ai écrite et qui affiche un tableau de jeu, centré sur 0,0,0, perpendiculaire à l’axe Z, et de taille comprise entre -1 et 1 sur x et y. J’ai fait simple pour commencer.

[code]#include <GL/glut.h>
//#include <GL/gl.h>
//#include <GL/glu.h>

void initialise();
void affiche();
void clavier(unsigned char touche,int x,int y);
int tableaugl(int nbln,int nbcol,float angle);

int fenetre;
int font=(int)GLUT_STROKE_ROMAN;

int main(int argc,char** argv)
{
glutInit(&argc,argv);     // on récupère les arguments de la ligne de commande
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);

fenetre = glutCreateWindow("Bataille Navale"); &nbsp; &nbsp; // on affiche la fenêtre OpenGL avec son titre
glutFullScreen(); &nbsp; &nbsp; // on met la fenêtre en plein écran

glutKeyboardFunc(clavier); &nbsp; &nbsp; // on définit la fonction qui nous permet de récupérer les saisies clavier

initialise(); &nbsp; &nbsp; // on appelle la fonction qui va initialiser l'affichage OpenGL
glutDisplayFunc(affiche); &nbsp; &nbsp; // on définit la fonction qui nous permet d'afficher à l'écran
glutMainLoop();

return 0;

}

void initialise()
{
glClearColor (0.5,0.5,1.0,0.0);     // couleur de fond à l’initialisation

// épaisseur du trait
glLineWidth(4.0);

// positionnement de la caméra
glMatrixMode(GL_MODELVIEW);
gluLookAt(0,0,1,0,0,0,0,1,0);

// valeurs de la vue
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

}

void affiche()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f (1.0,1.0,0.0);

// affichage du tableau de jeu
tableaugl(10,10,0);

// affichage d'une lettre
glPushMatrix();
glTranslatef(0, 0, 0);
glutStrokeCharacter(&font, 'a');
glPopMatrix();

glutSwapBuffers();

}

void clavier(unsigned char touche,int x,int y)
{
usleep(100);

// si l'utilisateur presse ECHAP on quitte
if (touche == 27) 
{ 

 glutDestroyWindow(fenetre);     // on ferme la fenêtre OpenGL
 
 exit(0);     // et on quitte le programme
}                  
}

int tableaugl(int nbln,int nbcol,float angle)
{
float i,hln,lcol;
float marge[4];

// marges laissées sur les cotés du tableau
marge[0] = 0.2; &nbsp; &nbsp; // haut
marge[1] = 0.1; &nbsp; &nbsp; // bas
marge[2] = 0.1; &nbsp; &nbsp; // droite
marge[3] = 0.1; &nbsp; &nbsp; // gauche

glColor3f (1.0,1.0,1.0); &nbsp; &nbsp; // réglage de la couleur du tableau

// calcul de la hauteur des lignes et de la largeur des colones
hln = (2.0-marge[0]-marge[1])/(nbln);
lcol = (2.0-marge[2]-marge[3])/nbcol;

// tracé des lignes
for (i=0;i<nbln+1;i++) &nbsp; &nbsp; // tracé des lignes
{

 glBegin(GL_LINES);
 glVertex3f (-1.0+marge[3], ihln-1.0+marge[1], 0.0);
 glVertex3f (1.0-marge[2], i
hln-1.0+marge[1], 0.0);
 glEnd();
 
}

// tracé des colones
for (i=0;i<nbcol+1;i++) &nbsp; &nbsp; // tracé des colones
{

 glBegin(GL_LINES);
 glVertex3f (ilcol-1.0+marge[3], -1.0+marge[1], 0.0);
 glVertex3f (i
lcol-1.0+marge[3], 1.0-marge[0], 0.0);
 glEnd();
}
}[/code]

Je compile ce programmme, tout marche bien comme je veux.

Cependant il y a des trucs que je ne comprend pas trop.

Premièrement
Comme vous le voyez, j’ai utilisé la fonction glulookat de cette manière:
gluLookAt(0,0,1,0,0,0,0,1,0);
Si j’ai bien compris, ma caméra est placée (x,y,z) en 0,0,1, elle regarde en 0,0,0, et le point central haut de la caméra est en 0,1,0. Jusque là tout va bien.
Seulement, si je marque :
gluLookAt(0,0,1,0,1,0,0,2,0);
ben le faut de mon tableau est effacé à partir du moment ou il devient positif sur l’axe Y…

Donc je ne suis pas sûr d’avoir compris comment utiliser cette fonction.

Deuxièmement
Comme vous le voyez aussi :stuck_out_tongue: j’essaie d’afficher le caractère ‹ a › au niveau de l’origine des axes, dans la fonction « affiche ».
Et lorsque j’exécute le programme, je ne vois pas ce fameux caractère a…
Glop m’a aimablement donné un lien vers un code C dans ce topic. Mais je n’arrive pas à réutiliser celà dans mon programme, puisque ce que j’ai fait ne marche pas.

Donc il y a des trucs que je n’ai pas bien compris, si quelqu’un peut m’aider…

Si vous voyez moyen d’améliorer mon code niveau utilisation de l’OpenGL, dites toujours, je débute donc je suis certain qu’il y a moyen d’améliorer.

Pour compiler le code sous Windows, remplacez simplement la déclaration des librairies par :

[quote]#include <gl\glut.h>
#include <gl\gl.h>
#include <gl\glu.h>[/quote]

Voilà, donc si vous pouviez m’expliquer pourquoi ça marche mal, les améliorations possibles, des conseils… ça m’aiderai beaucoup et je vous en serait très reconnaissant :stuck_out_tongue:

J’ai lu quelques cours sur l’OpenGL :
http://www.univ-reims.fr/UFR/Info/Image
http://www.univ-reims.fr/Labos/LERI/membre/bittar/03OpenGL
http://www.essi.fr/~buffa/cours/synthese_image/index.html
J’ai fait quelques TP aussi : http://www.irit.fr/~Loic.Barthe/Enseigneme…O5/TP1/tp1.html

Merci!

Zieute un coup du côté de NeHe, y’a un tuto pour le texte, et y’a aussi pleins d’autres tuto (en anglais) mais très instructif.

Sinon je te refile un fonction bien pratique qu’on m’avait donné,
pour switcher en 2D/3D, ce qui donne l’avantage de pouvoir
utiliser des glvertex2 au lieu des glvertex3, ce qui pourrait être
utile dans ton cas.
Width et Height sont la taille de l’écran

[code]void CCamera::Switch2D()
{
glMatrixMode(GL_PROJECTION);  // Select Projection
glPushMatrix();      // Push The Matrix
glLoadIdentity();      // Reset The Matrix
glOrtho( 0, Width , Height , 0, -1, 1 );// Select Ortho Mode (640x480)
glMatrixMode(GL_MODELVIEW);    // Select Modelview Matrix
glPushMatrix();      // Push The Matrix
glLoadIdentity();      // Reset The Matrix
}

void CCamera::Switch3D()
{
glMatrixMode( GL_PROJECTION ); // Select Projection
glPopMatrix();    // Pop The Matrix
glMatrixMode( GL_MODELVIEW ); // Select Modelview
glPopMatrix();    // Pop The Matrix
}[/code]

pour gluLookAt je croit qu’il faut que le 3éme vecteur passé en parametre soit un vecteur normalisé donc c’est normal que tu ait des problemes avec un vecteur de 0,2,0…

[quote]pour gluLookAt je croit qu’il faut que le 3éme vecteur passé en parametre soit un vecteur normalisé donc c’est normal que tu ait des problemes avec un vecteur de 0,2,0…[/quote]C’est à dire? :stuck_out_tongue:

un vecteur normalisé est un vecteur dont la taille vaut 1.

par exemple: (1,0,0) (0,1,0) (cos(45),sin(45),0), etc…

OK je vois, mais alors je n’ai pas bien compris comment la fonction gluLookAt fonctionne.

Et puis le plus important c’est le texte, quelqu’un ne verrait pas par hazard pourquoi ça ne fonctionne pas ? J’ai dû oublier quelque chose je sais pas…

Je vais écrire ma propre fonction d’affichage de caractères, car les fonctions de glut prévues à cet effet ne me satisfont pas du tout. Je vous filerai le code quand j’aurais fini, si ça vous intéresse… c’est de toutes façons pas bien compliqué à faire hein.

J’aimerai savoir un truc : actuellement j’efface le frame buffer avec une couleur de fond bleue:glClearColor (0.5,0.5,1.0,0.0); glClear(GL_COLOR_BUFFER_BIT);J’aimerai appliquer une texture plutôt, parce que ce bleu c’est moche :stuck_out_tongue:

J’ai vu qu’il y a une fonction intéressante : http://www.games-creators.org/index.php/Op…ion_de_textures
pour charger des textures dans un peu tous les formats d’images.
Mais comment effacer le fond de ma scène 2D avec une texture ? Dois-je définir un gros carré qui couvre le champ de vision de la caméra et auquel j’applique une texture ? C’est un peu brouillon comme méthode, donc si vous avez mieux :stuck_out_tongue: n’hésitez pas!

A mon avis, le seul moyen que tu ais, serait d’appliquer ta texture sur une surface. Et c’est pas brouillon.
Si jamais ca pourait peut etre t’aider : The Red Book

OK ben je vais faire comme ça alors… vu que j’ai modifié le code pour avoir une scène 2D only, je pensais qu’il y avait mieux quoi.

Merci pour le livre rouge!

Connaissez-vous un bon site de textures ? Une texture de mer ou d’eau ce serait super pour mon jeu de bataille navale.

Voilà ma fonction qui permet d’afficher du texte:

[code]void affiche_chaine(int *ptrchaine,float taille,int epaisseur,float x,float y)
{
int i,j;
i=0;

glLineWidth(epaisseur); &nbsp; &nbsp; // épaisseur des lettres

// on définit toutes les lettres
float lettres[27][27] = {
{0}, &nbsp; &nbsp; // espace
{8, 0,0 , 0,5 , 1,6 , 2,6 , 3,5 , 3,0 , 3,3 , 0,3}, &nbsp; &nbsp; // A
{12, 0,0 , 0,6 , 2,6 , 3,5 , 3,4 , 2,3 , 0,3 , 2,3 , 3,2 , 3,1 , 2,0 , 0,0}, &nbsp; &nbsp; // B
{6, 3,0 , 1,0 , 0,1 , 0,5 , 1,6 , 3,6}, &nbsp; &nbsp; // C
{7, 0,0 , 0,6 , 2,6 , 3,5 , 3,1 , 2,0 , 0,0}, &nbsp; &nbsp; // D
{9, 3,0 , 0,0 , 0,3 , 2,3 , 0,3 , 2,3 , 0,3 , 0,6 , 3,6} &nbsp;, // E
{6, 0,0 , 0,3 , 2,3 , 0,3 , 0,6 , 3,6}, &nbsp; &nbsp; // F
{9, 1,3 , 3,3 , 3,1 , 2,0 , 1,0 , 0,1 , 0,5 , 1,6 , 3,6}, &nbsp; &nbsp; // G
{6, 0,0 , 0,6 , 0,3 , 3,3 , 3,6 , 3,0}, &nbsp; &nbsp; // H
{6, 0,0 , 2,0 , 1,0 , 1,6 , 0,6 , 2,6}, &nbsp; &nbsp; // I
{7, 0,3 , 0,1 , 1,0 , 2,1 , 2,6 , 1,6 , 3,6}, &nbsp; &nbsp; // J
{6, 0,0 , 0,6 , 0,3 , 3,6 , 0,3 , 3,0}, &nbsp; &nbsp; // K
{3, 0,6 , 0,0 , 3,0}, &nbsp; &nbsp; // L
{5, 0,0 , 0,6 , 2,3 , 3,6 , 3,0}, &nbsp; &nbsp; // M
{4, 0,0 , 0,6 , 3,0 , 3,6}, &nbsp; &nbsp; // N
{9, 0,1 , 0,5 , 1,6 , 2,6 , 3,5 , 3,1 , 2,0 , 1,0 , 0,1}, &nbsp; &nbsp; // O
{7, 0,0 , 0,6 , 2,6 , 3,5 , 3,4 , 2,3 , 0,3}, &nbsp; &nbsp; // P
{13, 0,1 , 0,5 , 1,6 , 2,6 , 3,5 , 3,1 , 2.5,0.5 , 1,2 , 3,0 , 2.5,0.5 , 2,0 , 1,0 , 0,1}, &nbsp; &nbsp; // Q
{8, 0,0 , 0,6 , 2,6 , 3,5 , 3,4 , 2,3 , 0,3 , 3,0}, &nbsp; &nbsp; // R
{10, 0,0 , 2,0 , 3,1 , 3,2 , 2,3 , 1,3 , 0,4 , 0,5 , 1,6 , 3,6}, &nbsp; &nbsp; // S
{4, 1.5,0 , 1.5,6 , 0,6 , 3,6}, &nbsp; &nbsp; // T
{6, 0,6 , 0,1 , 1,0 , 2,0 , 3,1 , 3,6}, &nbsp; &nbsp; // U
{3, 0,6 , 1.5,0 , 3,6}, &nbsp; &nbsp; // V
{9, 0,6 , 0,2 , 1,0 , 1.5,2 , 1.5,4 , 1.5,2 , 2,0 , 3,2 , 3,6}, &nbsp; &nbsp; // W
{5, 0,0 , 3,6 , 1.5,3 , 0,6 , 3,0}, &nbsp; &nbsp; // X
{4, 0,0 , 3,6 , 1.5,3 , 0,6}, &nbsp; &nbsp; // Y
{5, 0,6 , 3,6 , 0,0 , 3,0 , 3,1} &nbsp; &nbsp; // Z
};

glPushMatrix();
glTranslated(x,y,0);
do
{

 glBegin(GL_LINE_STRIP);
 for (j=1;j<lettres[ptrchaine[i]][0]*2;j=j+2)
 {
   glVertex2f(lettres[ptrchaine[i]][j]*taille,lettres[ptrchaine[i]][j+1]taille);
 }
 glEnd();
 glTranslated(5
taille,0,0);
 i++;
} while (ptrchaine[i] != -1);
glPopMatrix();
}[/code]Je définis tous les caractères un par un, et après je les trace. Pour afficher un texte, il vous suffit d’appeler la fonction avec une variable chaine composée de différents numéros correspondant à chaque lettre.
Par exemple:

int titre[16]={2,1,20,1,9,12,12,5,0,14,1,22,1,12,5,-1}; affiche_chaine(titre,0.1,6,2.5,9.2);Affichera « BATAILLE NAVALE ».
Vous pouvez personnaliser la taille de la police, l’épaisseur du trait, et évidement la position du texte sur la scène, uniquement en 2D.
Je vais peut être ajouter un petit quelque chose qui centre horizontalement le texte, mais j’en ai pas besoin pour le moment donc…

Voilà, bon je sais yen a des centaines dispo sur le net des fonctions qui ressemblent à cette là (mais en mieux) mais je voulais faire la mienne donc voilà :stuck_out_tongue:

Petit problème
Voilà, j’affiche un texte sur la scène, et j’aimerai déplacer ce texte sans déplacer les autres objets de la scène. Imaginons que j’ai tracé quelques lignes avant d’afficher mon texte, je ne veux pas que ces lignes se déplacent, mais juste le texte.

Et enfin, je vais peut être faire une fonction qui affiche du texte à partir de polices graphiques (textures). J’ai pensé pour celà dessiner des rectangles pour chaque lettre, chaque rectangle serait 100% transparent, et sur chacun j’affiche une texture pour chaque lettre. La texture va t-elle être transparente comme le rectangle sur lequel elle est appliquée ? Est-ce une bonne méthode de faire comme ça ?

Après quelques réflexions, j’ai légèrement modifié :

[code]void affiche_chaine(char *chaine, float taille, int epaisseur, float x, float y)
{
int j, k = 0, i = 0;

//On effectue la traduction
while (chaine[i] != 0)
{
 if (chaine[i] < 0x41 || chaine[i] > 0x7A) chaine[i] = 0; // Tout le reste en espace
 if (chaine[i] >= 0x41 && chaine[i] <=0x5A) chaine[i] -= 0x40;  //MAJUSCULE
 if (chaine[i] >= 0x61 && chaine[i] <= 0x7A) chaine[i] -= 0x60; //minuscule
 i++;
}
chaine[i] = -1;

//[TABLE INIT]

i = 0;
glLineWidth(epaisseur);
glPushMatrix();
glTranslated(x,y,0);
while (chaine[i] != -1)
{
k = chaine[i];
glBegin(GL_LINE_STRIP);
for (j = 1; j < lettres[k][0]*2; j+= 2)
{
 glVertex2f(lettres[k][j]*taille,
   lettres[k][j+1]taille);
}
glEnd();
glTranslatef(5
taille,0,0);
i++;
}
glPopMatrix();

//Pour revenir Sans déplacer les objets :
gltranslatef(-x -(5 * taille * i), -y, 0);
}[/code]

En faisant une traduction minimale via les codes ASCII, tu pourra balancer la chaine directement, ce qui pourra être largement plus pratique.

Je te conseille de ne pas utiliser gltranslated si tu lui balances des floats, il va surement convertir en double (à vérifier), ce qui prend du temps et ne rend pas plus précis, un gltranslatef est plus adapté (elle prend pas l’eau [désolé jeu de mot tout çaaaa]).

Autre gros problème : l’initialisation, ok ça marche, mais dis-toi qu’à chaque lancement de la fonction il va recréer ton tableau en mémoire, et vu la taille de ton tableau plein de o (wooooou, de mieux en mieux), ça doit prendre un temps plutôt considérable. Essaye de le placer à un niveau plus haut, afin de ne pas à le re-remplir à chaque fois que tu redessines. Si tu souhaites au contraire garder le tableau dans la fonction (ce qui peut se justifier), il vaudrait mieux grouper la mise à l’échelle, de cette façon tu pourrai changer l’intérieur de la boucle :

... for (j = 1; j < lettres[k][0]*2; j+= 2) {glVertex2fv(&lettres[k][j]);} ...

Pour l’idée d’afficher à partir de la texture, ton rectangle ne sera pas transparent, vu que tu seras en mode texture, c’est la texture qui sera affiché, aucune ligne ne sera présente à l’écran, faudrat juste se démerder pour la transparence des lettres.

Valla valla, le texte quand on débute on fait tjr pleins de trucs dégueux (j’ai continué dans cette voie), par exemple j’avais fait une classe qui stockait les lettres dans un tableau d’int, chaque entier représentait un caractère bitmap et je dessinais tout avec des cubes :P"

[quote]En faisant une traduction minimale via les codes ASCII, tu pourra balancer la chaine directement, ce qui pourra être largement plus pratique.[/quote]Oui j’y ai pensé, et je me suis dit que ça poserai problème si j’ajoute des caractères spéciaux à mon tableau. Pour ce programme je crois que je vais faire comme tu dis.

[quote]Je te conseille de ne pas utiliser gltranslated si tu lui balances des floats, il va surement convertir en double (à vérifier), ce qui prend du temps et ne rend pas plus précis, un gltranslatef est plus adapté (elle prend pas l’eau [désolé jeu de mot tout çaaaa]).[/quote]Merci pour l’info :stuck_out_tongue:

[quote]Autre gros problème : l’initialisation, ok ça marche, mais dis-toi qu’à chaque lancement de la fonction il va recréer ton tableau en mémoire, et vu la taille de ton tableau plein de o (wooooou, de mieux en mieux), ça doit prendre un temps plutôt considérable. Essaye de le placer à un niveau plus haut, afin de ne pas à le re-remplir à chaque fois que tu redessines. Si tu souhaites au contraire garder le tableau dans la fonction (ce qui peut se justifier), il vaudrait mieux grouper la mise à l’échelle, de cette façon tu pourrai changer l’intérieur de la boucle :[/quote]Le tableau de caractères à la limite je peux le déclarer en global non ? Ce qui fait qu’il serait déclaré une seule fois.

Je vais prendre en compte tes modifications.

Aussi j’aimerai plus d’infos sur les textures de lettres.
Premièrement je n’ai pas trouvé d’explication simple pour m’expliquer clairement comment afficher une texture…
Ensuite, en ce qui concerne la transparence dans les textures (pour le O, je veux pas un rond blanc quoi :stuck_out_tongue: ) comment je pourrais faire ?

Oui le tableau pourrait tout à fait ce mettre en global, pour les fonts :
ici

pour les textures : ici
pour la transparence : encore ici

Bon désolé pour la transparence j’ai oublié comment ça marchait, ça fait lontemps que j’ai pas utilisé OpenGL + Textures.

Bonne chance (et bonne lecture) =)

Voilà, je suis arrivé à la bouse particulièrement moche que je souhaitais obtenir!

J’ai fini la partie affichage de mon jeu de bataille navale.
Le moteur du jeu je le ferai après, ça mettre peu de temps, ça a été un peu long pour OpenGL car j’ai appris en m’en servir sur le tas :stuck_out_tongue:

Si quelqu’un veut bien lire mon code pour me signaler des erreurs, etc… comment il aurait fait lui… Je dois encore modifier des trucs dans ma fonction d’affichage de texte, notamment faire en sorte que l’on lui transmette les lettres directement, mais ça c’est pas un problème c’est vite fait.

Voici le code donc:

[code]// TP 9.2
// Bataille Navale

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include « loadppm.c »     // c’est pas moi qui ai écrit loadppm.c !
#include <stdio.h>

void init();     // initialisation
void redimentione(int w,int h);     // redimentionement de la fenêtre
void affiche();     // fonction qui affiche la scène
void affiche_chaine(int *ptrchaine,float taille,int epaisseur,float x,float y);     // fonction qui permet d’afficher des caractères à l’écran (oui, j’aime pas les fonctions de glut prévues à cet effet)
int tableaugl(int nbln,int nbcol,float hln,float lcol,float x,float y);
void clavier(char unsigned touche,int x,int y);     // fonction appelée lors d’une saisie clavier

int fenetre;     // variable qui nous permet d’identifier notre fenêtre OpenGL
int selectx=0,selecty=0;     // position de la sélection

// texture de fond
char nom_texture_fond[] = « eau.ppm »;
PPMImage *image;

// on définit toutes les lettres
float lettres[27][27] = {
{0},     // espace
{8, 0,0 , 0,5 , 1,6 , 2,6 , 3,5 , 3,0 , 3,3 , 0,3},     // A
{12, 0,0 , 0,6 , 2,6 , 3,5 , 3,4 , 2,3 , 0,3 , 2,3 , 3,2 , 3,1 , 2,0 , 0,0},     // B
{6, 3,0 , 1,0 , 0,1 , 0,5 , 1,6 , 3,6},     // C
{7, 0,0 , 0,6 , 2,6 , 3,5 , 3,1 , 2,0 , 0,0},     // D
{9, 3,0 , 0,0 , 0,3 , 2,3 , 0,3 , 2,3 , 0,3 , 0,6 , 3,6}  , // E
{6, 0,0 , 0,3 , 2,3 , 0,3 , 0,6 , 3,6},     // F
{9, 1,3 , 3,3 , 3,1 , 2,0 , 1,0 , 0,1 , 0,5 , 1,6 , 3,6},     // G
{6, 0,0 , 0,6 , 0,3 , 3,3 , 3,6 , 3,0},     // H
{6, 0,0 , 2,0 , 1,0 , 1,6 , 0,6 , 2,6},     // I
{7, 0,3 , 0,1 , 1,0 , 2,1 , 2,6 , 1,6 , 3,6},     // J
{6, 0,0 , 0,6 , 0,3 , 3,6 , 0,3 , 3,0},     // K
{3, 0,6 , 0,0 , 3,0},     // L
{5, 0,0 , 0,6 , 2,3 , 3,6 , 3,0},     // M
{4, 0,0 , 0,6 , 3,0 , 3,6},     // N
{9, 0,1 , 0,5 , 1,6 , 2,6 , 3,5 , 3,1 , 2,0 , 1,0 , 0,1},     // O
{7, 0,0 , 0,6 , 2,6 , 3,5 , 3,4 , 2,3 , 0,3},     // P
{13, 0,1 , 0,5 , 1,6 , 2,6 , 3,5 , 3,1 , 2.5,0.5 , 1,2 , 3,0 , 2.5,0.5 , 2,0 , 1,0 , 0,1},     // Q
{8, 0,0 , 0,6 , 2,6 , 3,5 , 3,4 , 2,3 , 0,3 , 3,0},     // R
{10, 0,0 , 2,0 , 3,1 , 3,2 , 2,3 , 1,3 , 0,4 , 0,5 , 1,6 , 3,6},     // S
{4, 1.5,0 , 1.5,6 , 0,6 , 3,6},     // T
{6, 0,6 , 0,1 , 1,0 , 2,0 , 3,1 , 3,6},     // U
{3, 0,6 , 1.5,0 , 3,6},     // V
{9, 0,6 , 0,2 , 1,0 , 1.5,2 , 1.5,4 , 1.5,2 , 2,0 , 3,2 , 3,6},     // W
{5, 0,0 , 3,6 , 1.5,3 , 0,6 , 3,0},     // X
{4, 0,0 , 3,6 , 1.5,3 , 0,6},     // Y
{5, 0,6 , 3,6 , 0,0 , 3,0 , 3,1}     // Z
};

int main(int argc,char** argv)
{
glutInit(&argc,argv);     // initialisation de glut

glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE); &nbsp; &nbsp; // mode de rendu

 // GLUT_RGBA: couleurs 32bit et GLUT_DOUBLE: double buffer

//glutInitWindowSize(800,600); &nbsp; &nbsp; // taille de la fenêtre
//glutInitWindowPosition(100,100); &nbsp; &nbsp; // position de la fenêtre

fenetre = glutCreateWindow("Bataille navale"); &nbsp; &nbsp; // création de la fenêtre
glutFullScreen(); &nbsp; &nbsp; // mode plein écran

init(); &nbsp; &nbsp; // fonction d'initialisation

// fonctions utilisées
glutDisplayFunc(affiche); &nbsp; &nbsp; // affichage de la scène
glutReshapeFunc(redimentione); &nbsp; &nbsp; // redimentionement de la fenêtre
glutKeyboardFunc(clavier); &nbsp; &nbsp; // attente des saisies clavier

glutMainLoop(); &nbsp; &nbsp; // lancement de glut
return 0;

}

void init(void)
{
// on charge la texture de fond
image = LoadPPM(nom_texture_fond);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image->data);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}

// redimentionement de la fenêtre
void redimentione(int w,int h)     // w et h: dimentions de la fenêtre
{
float L; // longueur entre les 2 plans de coupe verticaux
float H; // hauteur entre les 2 plans de coupe horizontaux

glViewport(0,0,w,h); &nbsp; &nbsp; // transformation de l'affichage, 0,0: coin inférieur gauche

glMatrixMode(GL_PROJECTION); &nbsp; &nbsp; // matrice de projection (pour décrire la caméra)
glLoadIdentity(); &nbsp; &nbsp; // réinitialisation

// pour ne pas avoir de déformation, on prend en compte le cas ou w et h ne sont pas égaux
if (w <= h)
{

 H = (GLfloat) (10h/w);
 L = 10.0;
}
else
{
 H = 10.0;
 L = (GLfloat) (10
w/h);
}
gluOrtho2D(0,L,0,H);     // création d’une projection 2D orthogonale
}

// fonction qui affiche la scène
void affiche()
{
// paramètres du tableau de jeu
float tbx=2.6,tby=1;     // position
int nbln=10,nbcol=10;     // lignes, colones
float hln=0.7,lcol=0.7;     // hauteur lignes, largeur colones

int titre[16]={2,1,20,1,9,12,12,5,0,14,1,22,1,12,5,-1}; &nbsp; &nbsp; // "BATAILLE NAVALE"

//glClearColor (0.6,0.722,0.902,0.0); &nbsp; &nbsp; // couleur d'effacement de la fenêtre
glClear(GL_COLOR_BUFFER_BIT); &nbsp; &nbsp; // on efface la fenêtre

// affichage du fond
glEnable(GL_TEXTURE_2D); &nbsp; &nbsp; // activation de l'utilisation de textures
glBegin(GL_QUADS);

 glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
 glTexCoord2f(1.0, 0.0); glVertex2f(15.0, 0.0);
 glTexCoord2f(1.0, 1.0); glVertex2f(15.0, 10.0);
 glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 10.0);
glEnd();
glDisable(GL_TEXTURE_2D);

glColor3f(1.0, 1.0, 1.0);

affiche_chaine(titre,0.1,6,2.5,9.2); &nbsp; &nbsp; // affichage du titre
glLineWidth(4); &nbsp; &nbsp; // épaisseur des traits

tableaugl(nbln,nbcol,hln,lcol,tbx,tby); &nbsp; &nbsp; // affichage du jeu

// on place la sélection sur la case
if (selectx > nbcol-1) { selectx --; } &nbsp; &nbsp; // on empèche la sélection de sortir du tableau
if (selecty > nbln-1) { selecty --; } &nbsp; &nbsp; // "
if (selectx < 0) { selectx ++; } &nbsp; &nbsp; //
if (selecty < 0) { selecty ++; } &nbsp; &nbsp; //
glColor3f(1.0, 0.439, 0.325); &nbsp; &nbsp; // couleur de la sélection
glLineWidth(8); &nbsp; &nbsp; // épaisseur des traits
glBegin(GL_LINE_STRIP);

 glVertex2f (tbx + selectxlcol, tby + selectyhln + hln/3.0);
 glVertex2f (tbx + selectxlcol, tby + selectyhln);
 glVertex2f (tbx + selectxlcol + lcol/3.0, tby + selectyhln);
glEnd();
glBegin(GL_LINE_STRIP);
 glVertex2f (tbx + selectxlcol + 2.0lcol/3.0, tby + selectyhln);
 glVertex2f (tbx + selectx
lcol + lcol, tby + selectyhln);
 glVertex2f (tbx + selectx
lcol + lcol, tby + selectyhln + hln/3.0);
glEnd();
glBegin(GL_LINE_STRIP);
 glVertex2f (tbx + selectx
lcol + lcol, tby + selectyhln + 2.0hln/3.0);
 glVertex2f (tbx + selectxlcol + lcol, tby + selectyhln+hln);
 glVertex2f (tbx + selectxlcol + 2.0lcol/3.0, tby + selectyhln+hln);
glEnd();
glBegin(GL_LINE_STRIP);
 glVertex2f (tbx + selectx
lcol + lcol/3.0, tby + selectyhln+hln);
 glVertex2f (tbx + selectx
lcol, tby + selectyhln+hln);
 glVertex2f (tbx + selectx
lcol, tby + selectyhln + 2.0hln/3.0);
glEnd();
glLineWidth(4);     // épaisseur des traits

glutSwapBuffers(); &nbsp; &nbsp; // on affiche la scène

}

// fonction qui permet d’afficher des chaines de caractères à l’écran
void affiche_chaine(int *ptrchaine,float taille,int epaisseur,float x,float y)
{
int i,j;
i=0;

glLineWidth(epaisseur); &nbsp; &nbsp; // épaisseur des lettres

glPushMatrix();
glTranslatef(x,y,0);
while (ptrchaine[i] != -1)
{

 glBegin(GL_LINE_STRIP);
 for (j=1;j<lettres[ptrchaine[i]][0]*2;j=j+2)
 {
   glVertex2f(lettres[ptrchaine[i]][j]*taille,lettres[ptrchaine[i]][j+1]taille);
 }
 glEnd();
 glTranslatef(5
taille,0,0);
 i++;
}
glPopMatrix();
}

int tableaugl(int nbln,int nbcol,float hln,float lcol,float x,float y)
{
int i;

// tracé des lignes
for (i=0;i<nbln+1;i++) &nbsp; &nbsp; // tracé des lignes
{

 glBegin(GL_LINES);
 glVertex2f (x, y+ihln);
 glVertex2f (x+lcol
nbcol, y+i*hln);
 glEnd();
 
}

// tracé des colones
for (i=0;i<nbcol+1;i++) &nbsp; &nbsp; // tracé des colones
{

 glBegin(GL_LINES);
 glVertex2f (x+ilcol, y);
 glVertex2f (x+i
lcol, y+hln*nbln);
 glEnd();
}
}

// fonction appelée lors d’une saisie clavier
void clavier(char unsigned touche,int x,int y)
{
usleep(100);     // à enlever lors d’une compilation Windows
switch(touche)
{
 case 27 :     // touche échap (l’utilisateur veut quitter, ça l’a gavé)
 glutDestroyWindow(fenetre);     // on ferme la fenêtre OpenGL
 exit(0);     // et on quitte le programme
 break;
 case 52 :     // déplacement sélection à gauche
 selectx–;
 break;
 case 54 :     // déplacement sélection à droite
 selectx++;
 break;
 case 56 :     // déplacement sélection en haut
 selecty++;
 break;
 case 50 :     // déplacement sélection en bas
 selecty–;
 break;
 case 32 :     // feu!
 break;
}
glutPostRedisplay();  
}[/code]Le programme affiche le titre, un tableau de jeu 10x10, et un viseur de sélection pour dire là où l’on veut tirer, et on le déplace au clavier. Il n’y a donc que la partie affichage pour le moment.

Vous l’aurez remarqué, j’inclus dans mon programme : #include « loadppm.c »
C’est un petit fichier C qui permet de charger facilement une image ppm en texture, c’est pas moi qui l’ai écrit, mais il n’est pas bien compliqué.
Voici donc loadppm.c : http://www.univ-reims.fr/Labos/LERI/membre…/book/loadppm.c

Et voici la texture de fond que j’ai utilisée: http://bluelambda.free.fr/eau.ppm
C’est pas moi qui l’ai faite non plus la texture.

Voilà, placez ces fichiers à coté du code C ci dessus, si vous êtes sous Windows changez les en-têtes des fichiers C comme décrit dans le premier post du topic.

Et donnez moi votre avis! :stuck_out_tongue:

Bon ça tourne, mais sous windows c’est javel la croix et la banière pour compiler (feignant tout ça…), un pti makefile ne ferait pas de mal par exemple :wink: ou encore mieux, des binaires pour se faire une idée.

Aloreuuuuu, la compilation conditionnelle c’est sympa aussi :

#infdef _win32 usleep(100); #endif
usleep(100); ne compilera que sur les systèmes non windows par exemple.
Tips pour le OpenGL sous windows : pour que ça passe facilement avec du VS.net il faut mettre un #include <windows.h> avant les #include <gl*.h>
(je doit être trop fatigué, car je suis pas arrivé à lier avec gcc, l’heure trop tardive sans doute)

Sinon ça va, c’est fonctionnel, ça marche, la texture de fond va bien, mais question conne : La bataille navale que j’ai faite en cour pas plus tard qu’il ya 2 jours, on avait besoin de 2 tableaux, un où on plaçait ses bateaux + attaques adverses et un autre pour noter ces attaques, c’est prévu ou pas?

J’avais entendu dire qu’il fallait virer usleep(100); effectivement. Mais ça m’était sorti de la tête. Je tenterai de vous faire ds binaires Windows.

Sinon, ce que je compte faire, c’est au lancement du jeu on définit son jeu (on place ses bateaux) et ensuite un joue, tour à tour avec le PC, ce dernier dit au joueur quand il touche quelque chose, ou coule quelque chose. Le joueur n’a pas forcément besoin de voir son propre jeu quoi, mais effectuvement je pourrais faire deux tableaux, j’y réfléchirai.

Merci pour tes observations :stuck_out_tongue:

Une petite correction de bug. J’ai remplacé les lignes :

// on place la sélection sur la case if (selectx > nbcol-1) { selectx --; } &nbsp; &nbsp; // on empèche la sélection de sortir du tableau if (selecty > nbln-1) { selecty --; } &nbsp; &nbsp; // " if (selectx < 0) { selectx ++; } &nbsp; &nbsp; // if (selecty < 0) { selecty ++; } &nbsp; &nbsp; //

Par :

// on place la sélection sur la case if (selectx > nbcol-1) { selectx = nbcol-1; } &nbsp; &nbsp; // on empèche la sélection de sortir du tableau if (selecty > nbln-1) { selecty = nbln-1; } &nbsp; &nbsp; // " if (selectx < 0) { selectx = 0; } &nbsp; &nbsp; // if (selecty < 0) { selecty &nbsp;=0; } &nbsp; &nbsp; //

J’ai eu de la chance de m’aperçevoir de ce bug potentiel :stuck_out_tongue:
En effet, j’ai testé l’interface sur mon portable (assez limité niveau graphismes et CPU). Et si je place le sélecteur contre un coté et que je laisse appuyée la touche de déplacement vers ce coté, mon portable empèche le sélecteur de sortir du jeu. Mais au bout d’un moment, le sélecteur commence à sortir peu à peu.
La puissance de mon portable étant limitée, il déplacait le sélecteur, rechargait la scène, et ce rechargement prenait plus de temps que de déplacer à nouveau le sélecteur, le sélecteur était alors déplacé deux fois et ramené en arrière une seule fois.

Avec cette modification là plus de problèmes de ce type, le pointeur est bien bloqué dans le jeu. Je sais pas pourquoi j’avais fait cette erreur, d’habitude je m’arrange pour penser à ce genre de bugs.

Petit problème:
Sur mon portable ça rame pas mal avec la texture. Sans la tecture ça marche impec. La raison est que à chaque fois que je déplace le sélecteur, le programme recharge la scène (et donc la texture), d’où un lag d’environ une seconde.
Comment puis-je faire pour que la texture soit chargé une bonne fois pour toutes, et que lorsque je recharge la scène seule la texture n’est pas effacée et rechargée? C’est vrai d’ailleurs, c’est un peu bête de recharger cette texture à chaque fois, je pense que l’on doit pouvoir faire mieux.

Ensuite, quelqu’un pourrait-il m’expliquer comment compiler le code sous VC++ sous Windows?
Je l’ai fait, mais l’exécutable ne marche que lorsque j’exécute depuis VC++ (Build > exécute : ça marche très bien). Mais ensuite si je vais lancer l’exécutable à la main, il ne se lance pas.

EDIT : j’efface tout ce que j’ai écrit car c’est incompréhensible!

Ce que j’aimerai faire :

J’ai une fonction qui se lance peu importe où dans mon programme.
Imaginons que cette fonction contient une boucle infinie, tant que la boucle tournera (c’est à dire toujours), Glut ne pourra plus rien faire (ni afficher des trucs, ni recevoir des saisies au clavier, rien).

Est-il possible que à chaque tour de la boucle infinie, un appel a une fonction autorise Glut à recevoir des saisies clavier ?
Si je met dans ma boucle infinie : glutPostRedisplay(); l’affichage sera mis à jour à chaque tour de boucle.
Existe t-il autre chose pour que les saisies clavier soient prises en compte à chaque boucle ?

Ou alors existe t-il un moyen d’appeler directement la fonction de saisie clavier de Glut ? Ou une autre fonction de saisie clavier ?
En gros faire en sorte que tant que l’utilisateur ne presse pas une touche, la fonction attend, puis une fois la touche pressée, il la met dans une variable.

Un peu comme lorsque je mets getch(); dans un programme console, mais là c’est en OpenGL…

Car ça m’arrange pas beaucoup de devoir passer par la fonction définie par glutKeyboardFunc à chaque saisie clavier. J’aimerai faire des fonctions qui attendent que l’utilisateur presse une touche avant de poursuivre.

Ben euh, tu fous un flag nan?
tu l’actualise dans la keybord function machin, si une touche est pressé tu met à 1, sinon à 0, et ensuite dans ta routine, tu teste le flag, ou encore mieux : while (!Flag) {…}

C’est ça où j’ai pas bien tout compris le problème en partant du Guatemala?