Commentaires

Une variable globale entière f3 a été déclarée pour jouer le jeu de handle pour la 3ème fenêtre.

La fonction postRedisplay() (appelée pour demander le rafraîchissement des fenêtres) a été modifiée pour ajouter un 3ème appel à glutPostWindowRedisplay qui porte sur la fenêtre f3.

Le code de la fonction main a été reformaté pour mettre en évidence les parties qui correspondent aux ouvertures des 3 fenêtres.
Toutes les fenêtres ont les mêmes paramètres (GLUT_RGBA,GLUT_DEPTH,GLUT_DOUBLE) de "base".
Toutes les fenêtres partagent les mêmes fonctions keyboard et special.
La fenêtre 1 dispose de ses propres fonctions display et reshape (reshape 1 et display1).
Les fenêtres 2 et 3 ont des fonctions reshape différentes (reshape 2 et reshape3) mais partagent la même fonction display (display2). On voit ainsi que la fonction display assure pleinement et uniquement le rôle de modélisation de la scène et que les fonctions reshape assurent pleinement et uniquement le rôle de configuration de la position et de l'orientation de la caméra associée à chacune des deux fenêtres. Précision : Pour autoriser le mode de fonctionnement décrit à la phrase précedente, par rapport au code source DeuxFenetres.cpp l'appel à gluLookAt placé dans la fonction display2 a été déplacé vers les fonctions reshape.
La troisième fenêtre a été configurée avec une fonction reshape assurant le placement de la caméra en position (0.0,0.0,0.5) c'est à dire dans le cube.
La fonction idle est la même pour toutes les fenêtres.
glutMainLoop ouvre les 3 fenêtres et lance la boucle principale de gestion des affichages et des événements.

L'exécutable

Fichier source : DeuxFenetresSolution.cpp

/* Gestion de trois fenetres                    */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Mars 2020                                    */

#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

/* Variables et constantes globales             */

static int f1;
static int f2;
static int f3;
static float rx = 0.0F;
static float ry = 0.0F;
static float rz = 0.0F;

/* Fonction de rafraichissement des 2 fenetres  */

static void postRedisplay(void) {
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(f2);
  glutPostWindowRedisplay(f3);
}

/* Fonction executee lors de l'appui            */
/* d'une touche de curseur ou d'une touche      */
/* page up ou page down                         */

static void special(int key,int x,int y) {
  switch(key) {
    case GLUT_KEY_UP :
      rx++;
      postRedisplay();
      break;
    case GLUT_KEY_DOWN :
      rx--;
      postRedisplay();
      break;
    case GLUT_KEY_LEFT :
      ry++;
      postRedisplay();
      break;
    case GLUT_KEY_RIGHT :
      ry--;
      postRedisplay();
      break;
    case GLUT_KEY_PAGE_UP :
      rz++;
      postRedisplay();
      break;
    case GLUT_KEY_PAGE_DOWN :
      rz--;
      postRedisplay();
      break; }
}

/* Fonction d'initialisation des parametres     */
/* OpenGL ne changeant pas au cours de la vie   */
/* du programme                                 */

static void init(void) {
}

/* Scene dessinee                               */

static void scene(void) {
  glPushMatrix();
  glutWireCube(7.0);
  glPopMatrix();
}

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin                      */

static void display1(void) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glRotatef(rx,1.0F,0.0F,0.0F);
  glRotatef(ry,0.0F,1.0F,0.0F);
  glRotatef(rz,0.0F,0.0F,1.0F);
  scene();
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur OpenGL: %d\n",error);
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */
/* -> Ajustement de la camera de visualisation  */

static void reshape1(int x,int y) {
  glViewport(0,0,x,y); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-9.0,9.0,-9.0*(float) y/x,9.0*(float) y/x,-9.0,9.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin                      */

static void display2(void) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glRotatef(rx,1.0F,0.0F,0.0F);
  glRotatef(ry,0.0F,1.0F,0.0F);
  glRotatef(rz,0.0F,0.0F,1.0F);
  scene();
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur OpenGL: %d\n",error);
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */
/* -> Ajustement de la camera de visualisation  */

static void reshape2(int tx,int ty) {
  glViewport(0,0,tx,ty); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  double ratio =(double) tx/ty;
  if ( ratio >= 1.0 )
    gluPerspective(80.0,ratio,0.01,20.0);
    else
    gluPerspective(80.0/ratio,ratio,0.01,20.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(0.0,0.0,10.0,0.0,0.0,0.0,0.0,1.0,0.0);
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */
/* -> Ajustement de la camera de visualisation  */

static void reshape3(int tx,int ty) {
  glViewport(0,0,tx,ty); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  double ratio =(double) tx/ty;
  if ( ratio >= 1.0 )
    gluPerspective(80.0,ratio,0.01,20.0);
    else
    gluPerspective(80.0/ratio,ratio,0.01,20.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(0.0,0.0,0.5,0.0,0.0,0.0,0.0,1.0,0.0);
}

/* Fonction executee en tache de fond           */
/* pour realiser une animation                  */

static void idle(void) {
  rx += 0.1F;
  ry += 0.15F;
  rz += 0.23F;
  postRedisplay();
}

/* Fonction executee lors de la frappe          */
/* d'une touche du clavier                      */

static void keyboard(unsigned char key,int x,int y) {
  switch ( key ) {
    case 0x20 : {
      static int animation = 1;
      animation = !animation;
      glutIdleFunc(( animation ) ? idle : NULL); }
      break;
    case 0x1B :
      exit(0); 
      break; }
}

/* Fonction principale                          */

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  { glutInitWindowSize(480,320); 
    glutInitWindowPosition(50,50); 
    f1 = glutCreateWindow("Fenêtre 1"); 
    init();
    glutKeyboardFunc(keyboard);
    glutSpecialFunc(special);
    glutReshapeFunc(reshape1);
    glutDisplayFunc(display1); }
  { glutInitWindowSize(320,240); 
    glutInitWindowPosition(250,100);
    f2 = glutCreateWindow("Fenêtre 2");
    init();
    glutKeyboardFunc(keyboard);
    glutSpecialFunc(special);
    glutDisplayFunc(display2);
    glutReshapeFunc(reshape2); }
  { glutInitWindowSize(400,160); 
    glutInitWindowPosition(500,150);
    f3 = glutCreateWindow("Fenêtre 3");
    init();
    glutKeyboardFunc(keyboard);
    glutSpecialFunc(special);
    glutDisplayFunc(display2);
    glutReshapeFunc(reshape3); }
  glutIdleFunc(idle);
  glutMainLoop();
  return(0);
}

RETOUR