Les modifications apportées consistent en la création d'une fonction reshape
regroupant un certain nombre des instructions initialement placées dans la fonction
display + un appel à glViewport (voir plus loin).
Les appels concernés sont ceux réalisant le passage en mode GL_PROJECTION pour la
configuration de la caméra de visualisation ainsi que la restoration du mode GL_MODELVIEW
et la translation de placement de la scène devant la caméra.
Tous les autres appels restent dans la fonction display avec ajout d'un glPushMatrix -
glPopMatrix autour de l'appel à la fonction de dessin de la scène pour isoler une
exécution de la fonction display de l'exécution précédente.
La fonction reshape ayant en paramètres les dimensions de la fenêtre, le ratio du gluPerspective peut être calculé pour correspondre exactement à celui de la fenêtre. Toujours au moyen de ces paramètres, l'appel à glViewport est configuré pour que le viewport d'affichage occupe l'intégralité de la fenêtre d'affichage.
La scène est modifiée (battement des ailes) à chaque nouvel appel de fonction.
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Septembre 2005 */
/* Gestion minimum d'une camera */
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <stdio.h>
static int mode = 0;
void myinit(void) {
GLfloat shinines[] = { 50.0 };
GLfloat blanc[] = { 1.0,1.0,1.0,1.0 };
glClearColor(0.5F,0.5F,1.0F,1.0F) ;
glMaterialfv(GL_FRONT,GL_SPECULAR,blanc);
glMaterialfv(GL_FRONT,GL_SHININESS,shinines);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
void aileDroite(float a1,float a2) {
glPushMatrix();
glTranslatef(0.75F,0.0F,0.0F);
glRotatef(a1,0.0F,0.0F,1.0F);
glTranslatef(1.0F,0.0F,0.0F);
glPushMatrix();
glScalef(2.0F,0.1F,0.5F);
glutSolidSphere(1.0,18,18);
glPopMatrix();
glTranslatef(2.0F,0.0F,0.0F);
glRotatef(a2,0.0F,0.0F,1.0F);
glTranslatef(0.9F,0.0F,0.0F);
glPushMatrix();
glScalef(1.0F,0.1F,0.5F);
glutSolidSphere(1.0,18,18);
glPopMatrix();
glPopMatrix();
}
void aileGauche(float a1,float a2) {
glPushMatrix();
glTranslatef(-0.75F,0.0F,0.0F);
glRotatef(-a1,0.0F,0.0F,1.0F);
glTranslatef(-1.0F,0.0F,0.0F);
glPushMatrix();
glScalef(2.0F,0.1F,0.5F);
glutSolidSphere(1.0,18,18);
glPopMatrix();
glTranslatef(-2.0F,0.0F,0.0F);
glRotatef(-a2,0.0F,0.0F,1.0F);
glTranslatef(-0.9F,0.0F,0.0F);
glPushMatrix();
glScalef(1.0F,0.1F,0.5F);
glutSolidSphere(1.0,18,18);
glPopMatrix();
glPopMatrix();
}
void mouette() {
static int image = 0;
float a1 =(float) 25.0*cos((image*5)/180.0F);
float a2 =(float) -40.0*cos(((image*5)+90)/180.0F);
GLfloat l_pos[] = { 1.0,1.0,1.0,0.0 };
glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
glPushMatrix();
glTranslatef(0.0F,-a1/100.0F,0.0F);
glPushMatrix();
glScalef(0.75F,0.5F,1.5F);
glutSolidSphere(1.0,18,18);
glPopMatrix();
aileDroite(a1,a2);
aileGauche(a1,a2);
glPopMatrix();
image++;
}
void reshape(int w,int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(12.0F,(float) w/h,24.0F,36.0F);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0F,0.0F,-30.0F);
printf("Reshape\n");
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK,(mode) ? GL_LINE : GL_FILL);
glPushMatrix();
mouette();
glPopMatrix();
glFlush();
glutSwapBuffers();
int error = glGetError();
if ( error != GL_NO_ERROR )
printf("Attention, erreur OpenGL %d\n",error);
printf("Display\n");
}
void key(unsigned char key,int x,int y) {
switch ( key ) {
case 0x0D : glutPostRedisplay();
break;
case ' ' : mode = !mode;
glutPostRedisplay();
break; }
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(400,200);
glutInitWindowPosition(50,50);
glutCreateWindow("Gestion caméra minimum");
myinit();
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}