Jeu : GLUT et Visual C++

Bonjour,
Je programme un jeu de course poursuite avec GLUT en utilisant microsoft visual C++. Je tiens à préciser que c’est la première fois que j’utilise du C++ et GLUT, donc je suis une novice… En gros, il y a un missile dirigé par l’utilisateur qui doit détruire un territoire ennemi et un anti-missile qui doit l’intercepter et qui est dirigé par l’ordinateur. Avant le début du jeu, l’utilisateur doit pouvoir choisir la caractéristique de vitesse de son missile et de l’anti-missile (c’est-à-dire dessiner un polygone autour du missile), ainsi que dessiner la forme du territoire à détruire.

Pour l’instant, j’ai programmé une fenêtre où l’on peut dessiner un polygone point par point, il y a un menu (j’aurais préféré des boutons, mais apparemment GLUT ne fait pas ça…) attaché au click droit de la souris et je voudrais que lorsque l’on choisit OK, la fenêtre se ferme, et en ouvre une autre (pour dessiner un autre polygone). Mais j’ai gros bug. Est-ce que j’ai fait une erreur de programmation ??

Est-ce que l’on peut intégrer du GLUT avec du visual C++. Je m’explique : je voudrais faire des interfaces utilisateurs claires (et non pas utiliser un terminal) avec des boites de dialogues,… Mais GLUT n’est pas vraiment fait pour ça. Par exemple je voudrais créer une boite de dialogue en visual C++ avec un bouton OK qui lance une fenêtre GLUT. Est-ce que je rêve ou est-ce possible ?

Encore un autre problème : pour le déplacement du missile, j’ai écrit un petit programme en GLUT qui permet de le diriger via les flèches du clavier (flèche du haut pour aller vers le haut de la fenêtre,…). Seulement ce n’est pas très réaliste car le missile peut faire une rotation de 180° d’un coup et il ne suit d’ailleurs pas le profil de vitesse qui lui est imposé au début du jeu…. Est-ce que vous avez une idée pour programmer un déplacement plus « intelligent » ?

Merci

Olga

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

unsigned int n=0;
int vertices[100];
int windowWidth=200, windowHeight=200;
int a=windowWidth/2,b=windowHeight/2;
int window=0,w=1;
unsigned int i;
enum {OK,CANCEL,CLEAR} string;

void changeSize(int w, int h)
{

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)

 h = 1;

float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
windowWidth=w;
windowHeight=h;

gluOrtho2D(0,windowWidth,windowHeight,0);

// Set the viewport to be the entire window

// Set the correct perspective.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

// Display the first window for drawing the velocity indicatrix of the missile
void displayWindow1(void)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glColor3f(0,0,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

// Display gradually a polygon (the speed profil)
if (n>4)
{
 glBegin(GL_POLYGON);
 for (i=0;i<n;i=i+2)
 glVertex2f(vertices[i],vertices[i+1]);
}

// Display every chosen point of the polygon
for (i=0;i<n;i=i+2)
{
 glColor3f(0,0,0);
 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

 glBegin(GL_POLYGON);
 glVertex2f(-2+vertices[i],-2+vertices[i+1]);
 glVertex2f(2+vertices[i],-2+vertices[i+1]);
 glVertex2f(2+vertices[i],2+vertices[i+1]);
 glVertex2f(-2+vertices[i],2+vertices[i+1]);
 glEnd();
}

glPopMatrix();

glColor3f(1,0,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

// Display a square representing the missile
glBegin(GL_POLYGON);
 glVertex2f(-4+windowWidth/2,-4+windowHeight/2);
 glVertex2f(4+windowWidth/2,-4+windowHeight/2);
 glVertex2f(4+windowWidth/2,4+windowHeight/2);
 glVertex2f(-4+windowWidth/2,4+windowHeight/2);
glEnd();
glFlush();

glutSwapBuffers();

}

// Create the function which allow to add points to the polygon
// when the user click in the window
void processMouse(int button, int state, int x, int y)
{
switch (button)
{
 case GLUT_LEFT_BUTTON:
 if (state == GLUT_DOWN)
 {
   a=x;
   b=y;
   vertices[n]=a;
   vertices[n+1]=b;
   n=n+2;
   glutIdleFunc(displayWindow1);
   break;
 }
 if (state == GLUT_UP)
   glutIdleFunc(NULL);

 default:
 glutIdleFunc(NULL);
 break;
}
}

// Assign a function to each item of the menu
void menu(int choice)
{
switch(choice)
{
 case OK :
 {
 glutDestroyWindow(w);
 w++;
 break;
 }
 case CLEAR:
 {
 n=0;
 break;
 }
 case CANCEL:
 {
 if (n>0)
   n=n-2;
 break;
 }
}
glutPostRedisplay();
}

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);

glutInitWindowPosition(500,300);
glutInitWindowSize(windowWidth,windowHeight);

if (w==1) // The user draws the first polygon
{
glutCreateWindow("Fenêtre 1");
glutSetWindow(w);

int m =glutCreateMenu(menu);
glutSetMenu(m);
glutAddMenuEntry("OK",OK);
glutAddMenuEntry("Cancel",CANCEL);
glutAddMenuEntry("Clear",CLEAR);
glutAttachMenu(GLUT_RIGHT_BUTTON);

   glutMouseFunc(processMouse);

glutDisplayFunc(displayWindow1);
glutIdleFunc(displayWindow1);
}

if (w==2) // The user draws the second polygon
{
glutCreateWindow("Fenêtre 2");
glutSetWindow(w);

int m =glutCreateMenu(menu);
glutSetMenu(m);
glutAddMenuEntry("OK",OK);
glutAddMenuEntry("Cancel",CANCEL);
glutAddMenuEntry("Clear",CLEAR);
glutAttachMenu(GLUT_RIGHT_BUTTON);

   glutMouseFunc(processMouse);

glutDisplayFunc(displayWindow1);
glutIdleFunc(displayWindow1);
}

glutReshapeFunc(changeSize);
glEnable(GL_DEPTH_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_DEPTH_TEST);

glutMainLoop();

}[/code]

Hum a mon souvenir Glut peut faire des UI

Mais je conseillerai GLUI pour le faire c’est trés simple a utilisé.

Sinon oui tu peux utilisé c’est deux lib + GL avec visual

Suffit de bien faire tes includes et de bien link le lib.

Koubiak

[quote]case OK :
{
  glutDestroyWindow(w);
  w++;
  break;
}[/quote]

Je vois que tu détruit ta fenêtre de dessin des polygones ici.
Tu a mis la création de tes fenêtres dans ta procédure MAIN() qui n’est plus exécutée.
En effet au lancement de ton prog, la procédure main est parcourue en entier jusque à
glutMainLoop(); ton prog ne repasse donc plus sur

[quote]if (w==2) // The user draws the second polygon
{
glutCreateWindow(« Fenêtre 2 »);
glutSetWindow(w);

int m =glutCreateMenu(menu);
glutSetMenu(m);
glutAddMenuEntry(« OK »,OK);
glutAddMenuEntry(« Cancel »,CANCEL);
glutAddMenuEntry(« Clear »,CLEAR);
glutAttachMenu(GLUT_RIGHT_BUTTON);

  glutMouseFunc(processMouse);

glutDisplayFunc(displayWindow1);
glutIdleFunc(displayWindow1);
}[/quote]

Donc pour le moment tout ce que tu fais c’est de détruire ta fenêtre et c’est tout. il faut que tu fasse une autre procédure qui fera la création de ta fenêtre. Ainsi tu pourras l’appelé, depuis ton case « OK ».
Comme tu as fait pour le moment il faudrait que tu rappel MAIN() aprés ton W++, mais je trouve pas ça très top niveau coté implémentation (rappel de MAIN = :stuck_out_tongue: ).

bon test A+

Audrix

ou encor mieux vas faire un tour chez

Nehe

tu devrai surement y trouver ton bohneur. il ya des exemples opengl implémenté en C++ et glut.

bonne pioche

Merci pour vos réponses!
J’ai essayé de faire comme Audrix m’a conseillé (si j’ai bien compris!). J’arrive à afficher les 2 premières fenêtres consécutivement, mais à la 3ème, ça bug,… et je ne comprends toujours pas pourquoi.
Autrement, pour faire du code un peu plus clair? Car j’utilise presque les mêmes fonctions (createWindow1, createWindow2,…) et je voudrais les rassembler en une seule, mais quand j’essaie de mettre des paramètres, ça plante…
Merci.
olga

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

unsigned int n=0,m=0,p=0;
int verticesMiss[100], verticesAnti[100],verticesTerr[100];
int windowWidth=200, windowHeight=200;
int a=windowWidth/2,b=windowHeight/2;
int window=0,w=1,e;
unsigned int i;
enum {OK,CANCEL,CLEAR} string;

void changeSize(int w, int h)
{

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)

 h = 1;

float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
windowWidth=w;
windowHeight=h;

gluOrtho2D(0,windowWidth,windowHeight,0);

// Set the viewport to be the entire window

// Set the correct perspective.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

void createWindow2(void);
void createWindow3(void);

// Display the first window for drawing the velocity indicatrix of the anti-missile
void displayWindow1(void)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glColor3f(0,0,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

// Display gradually a polygon (the speed profil)
if (n>4)
{
 glBegin(GL_POLYGON);
 for (i=0;i<n;i=i+2)
 glVertex2f(verticesMiss[i],verticesMiss[i+1]);
}

// Display every chosen point of the polygon
for (i=0;i<n;i=i+2)
{
 glColor3f(0,0,0);
 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

 glBegin(GL_POLYGON);
 glVertex2f(-2+verticesMiss[i],-2+verticesMiss[i+1]);
 glVertex2f(2+verticesMiss[i],-2+verticesMiss[i+1]);
 glVertex2f(2+verticesMiss[i],2+verticesMiss[i+1]);
 glVertex2f(-2+verticesMiss[i],2+verticesMiss[i+1]);
 glEnd();
}

glPopMatrix();

glColor3f(1,0,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

// Display a square representing the missile
glBegin(GL_POLYGON);
 glVertex2f(-4+windowWidth/2,-4+windowHeight/2);
 glVertex2f(4+windowWidth/2,-4+windowHeight/2);
 glVertex2f(4+windowWidth/2,4+windowHeight/2);
 glVertex2f(-4+windowWidth/2,4+windowHeight/2);
glEnd();
glFlush();

glutSwapBuffers();

}

// Display the second window for drawing the velocity indicatrix of the missile
void displayWindow2(void)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glColor3f(0,0,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

// Display gradually a polygon (the speed profil)
if (m>4)
{
 glBegin(GL_POLYGON);
 for (i=0;i<m;i=i+2)
 glVertex2f(verticesAnti[i],verticesAnti[i+1]);
}

// Display every chosen point of the polygon
for (i=0;i<m;i=i+2)
{
 glColor3f(0,0,0);
 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

 glBegin(GL_POLYGON);
 glVertex2f(-2+verticesAnti[i],-2+verticesAnti[i+1]);
 glVertex2f(2+verticesAnti[i],-2+verticesAnti[i+1]);
 glVertex2f(2+verticesAnti[i],2+verticesAnti[i+1]);
 glVertex2f(-2+verticesAnti[i],2+verticesAnti[i+1]);
 glEnd();
}

glPopMatrix();

glColor3f(1,0,0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

// Display a square representing the missile
glBegin(GL_POLYGON);
 glVertex2f(-4+windowWidth/2,-4+windowHeight/2);
 glVertex2f(4+windowWidth/2,-4+windowHeight/2);
 glVertex2f(4+windowWidth/2,4+windowHeight/2);
 glVertex2f(-4+windowWidth/2,4+windowHeight/2);
glEnd();
glFlush();

glutSwapBuffers();

}

void displayWindow3(void)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glColor3f(0,1,0.2);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

// Display gradually a polygon (the speed profil)
if (p>4)
{
 glBegin(GL_POLYGON);
 for (i=0;i<p;i=i+2)
 glVertex2f(verticesTerr[i],verticesTerr[i+1]);
}

// Display every chosen point of the polygon
for (i=0;i<p;i=i+2)
{
 glColor3f(0,0,0);
 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

 glBegin(GL_POLYGON);
 glVertex2f(-2+verticesTerr[i],-2+verticesTerr[i+1]);
 glVertex2f(2+verticesTerr[i],-2+verticesTerr[i+1]);
 glVertex2f(2+verticesTerr[i],2+verticesTerr[i+1]);
 glVertex2f(-2+verticesTerr[i],2+verticesTerr[i+1]);
 glEnd();
}

glPopMatrix();

glutSwapBuffers();

}

// Create the function which allow to add points to the polygon
// when the user click in the window
void processMouse1(int button, int state, int x, int y)
{
switch (button)
{
 case GLUT_LEFT_BUTTON:
 if (state == GLUT_DOWN)
 {
   a=x;
   b=y;
   verticesMiss[n]=a;
   verticesMiss[n+1]=b;
   n=n+2;
   glutIdleFunc(displayWindow1);
   break;
 }
 if (state == GLUT_UP)
   glutIdleFunc(NULL);

 default:
 glutIdleFunc(NULL);
 break;
}
}

void processMouse2(int button, int state, int x, int y)
{
switch (button)
{
 case GLUT_LEFT_BUTTON:
 if (state == GLUT_DOWN)
 {
   a=x;
   b=y;
   verticesAnti[m]=a;
   verticesAnti[m+1]=b;
   m=m+2;
   glutIdleFunc(displayWindow2);
   break;
 }
 if (state == GLUT_UP)
   glutIdleFunc(NULL);

 default:
 glutIdleFunc(NULL);
 break;
}
}

void processMouse3(int button, int state, int x, int y)
{
switch (button)
{
 case GLUT_LEFT_BUTTON:
 if (state == GLUT_DOWN)
 {
   a=x;
   b=y;
   verticesTerr[p]=a;
   verticesTerr[p+1]=b;
   p=p+2;
   glutIdleFunc(displayWindow3);
   break;
 }
 if (state == GLUT_UP)
   glutIdleFunc(NULL);

 default:
 glutIdleFunc(NULL);
 break;
}
}
// Assign a function to each item of the menu
void menu1(int choice)
{
switch(choice)
{
 case OK :
 {
 glutDestroyWindow(w);
 createWindow2();
 w++;
 break;
 }
 case CLEAR:
 {
 n=0;
 break;
 }
 case CANCEL:
 {
 if (n>0)
   n=n-2;
 break;
 }
}
glutPostRedisplay();
}

void menu2(int choice)
{
switch(choice)
{
 case OK :
 {
 glutDestroyWindow(w);
 createWindow3();
 w++;
 break;
 }
 case CLEAR:
 {
 m=0;
 break;
 }
 case CANCEL:
 {
 if (m>0)
   m=m-2;
 break;
 }
}
glutPostRedisplay();
}

void menu3(int choice)
{
switch(choice)
{
 case OK :
 {
 // glutDestroyWindow(w);
 w++;
 break;
 }
 case CLEAR:
 {
 p=0;
 break;
 }
 case CANCEL:
 {
 if (p>0)
   p=p-2;
 break;
 }
}
glutPostRedisplay();
}
void createWindow1(void)
{
 glutInitWindowPosition(500,300);
glutInitWindowSize(windowWidth,windowHeight);

 glutCreateWindow(“Fenêtre 1”);
glutSetWindow(w);

e =glutCreateMenu(menu1);
glutSetMenu(e);
glutAddMenuEntry("OK",OK);
glutAddMenuEntry("Cancel",CANCEL);
glutAddMenuEntry("Clear",CLEAR);
glutAttachMenu(GLUT_RIGHT_BUTTON);

   glutMouseFunc(processMouse1);

glutDisplayFunc(displayWindow1);
glutIdleFunc(displayWindow1);

 glutReshapeFunc(changeSize);

}

void createWindow2(void)
{
glutInitWindowPosition(500,300);
glutInitWindowSize(windowWidth,windowHeight);

glutCreateWindow("Fenêtre 2");
glutSetWindow(w);

e =glutCreateMenu(menu2);
glutSetMenu(e);
glutAddMenuEntry("OK",OK);
glutAddMenuEntry("Cancel",CANCEL);
glutAddMenuEntry("Clear",CLEAR);
glutAttachMenu(GLUT_RIGHT_BUTTON);

   glutMouseFunc(processMouse2);

glutDisplayFunc(displayWindow2);
glutIdleFunc(displayWindow2);
glutReshapeFunc(changeSize);

}

void createWindow3(void)
{
glutInitWindowPosition(500,300);
glutInitWindowSize(windowWidth,windowHeight);

glutInitWindowPosition(450,250);
glutInitWindowSize(300,300);

glutCreateWindow("Fenêtre 3");
glutSetWindow(w);

e =glutCreateMenu(menu3);
glutSetMenu(e);
glutAddMenuEntry("OK",OK);
glutAddMenuEntry("Cancel",CANCEL);
glutAddMenuEntry("Clear",CLEAR);
glutAttachMenu(GLUT_RIGHT_BUTTON);

   glutMouseFunc(processMouse3);

glutDisplayFunc(displayWindow3);
glutIdleFunc(displayWindow3);
glutReshapeFunc(changeSize);

}

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);

if (w==1) // The user draws the first polygon
{

 createWindow1();
}

if (w==2) // The user draws the second polygon
{

 createWindow2();
}

if (w==3) // The user draws the third polygon
{

 createWindow3();
}

glEnable(GL_DEPTH_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_DEPTH_TEST);

glutMainLoop();

}[/code]

j’y pense seulement maintenant, mais pourquoi utilises tu plusieur fenêtres ?

Pour te simplifier tu pourait utiliser seulement une fenêtre et juste changer l’affichage.

Je m’explique :
Fais le choix de ton affichage dans ta procédure displayWindow.
Tu style tu place un « case » dans ta procédure, qui te selectionnera l’affichage que tu
veux.
Enfin moi c’est comme ça que je fait d’habitude.

Pour ton probléme de parametre a passer, je crois que glutIdleFunc n’accepte que du
« void », faudrait que je vérifie si j’ai le temps, mais il me semble que c’est ça.

Et puis glutIdleFunc je l’utilise surtout pour faire de l’animation.

Sinon j’ai pas eu le temps de revoir tout ton nouveau code, mais peut etre que je me pencherais dessus ce week end, enfin pas sure :stuck_out_tongue:

a+