/* Changement interactif de point de vue sur une scene (trackball) */ #include #include #include /* Placement de la scene par rapport a la camera */ GLfloat tb_translation[3] = { 0,0,-8 }, tb_rotation[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; /* Taille du frustum */ GLfloat cF = 1.0; /* demi-cote minimal de la face avant */ GLfloat pF = 3.0; /* demi-profondeur */ /* Affichage de la scene */ void display() { /* Tout effacer */ glClear( GL_COLOR_BUFFER_BIT ); /* Initialiser les transformations geometriques */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); /* Repere de la camera ici */ /* Placer la scene par rapport a la camera */ glTranslatef( tb_translation[0], tb_translation[1], tb_translation[2] ); glMultMatrixf( tb_rotation ); /* Repere de la scene ici */ glBegin( GL_LINES ); glColor3f( 1,0,0 ); glVertex3f( 0,0,0 ); glVertex3f( 1,0,0 ); glColor3f( 0,1,0 ); glVertex3f( 0,0,0 ); glVertex3f( 0,1,0 ); glColor3f( 0,0,1 ); glVertex3f( 0,0,0 ); glVertex3f( 0,0,1 ); glEnd(); /* Placer un objet */ glTranslatef( 0, 0, 0 ); glRotatef( 0, 0,1,0 ); glScalef( 1, 0.5, 0.25 ); /* Repere de l'objet ici */ /* Boite centree sur son repere local */ glColor3f( 1,1,1 ); glBegin( GL_LINE_LOOP ); /* face avant */ glVertex3f( -1.0, -1.0, 1.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glEnd(); glBegin( GL_LINE_LOOP ); /* face arriere */ glVertex3f( -1.0, -1.0, -1.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glVertex3f( 1.0, 1.0, -1.0 ); glVertex3f( -1.0, 1.0, -1.0 ); glEnd(); glBegin( GL_LINES ); /* autres aretes */ glVertex3f( -1.0, -1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 ); glEnd(); /* Afficher le buffer */ glutSwapBuffers(); } /* Transformation perspective camera -> fenetre */ static void reshape( GLsizei w, GLsizei h ) { /* aspect de la fenetre */ double ratio = (double)w/h; /* place de l'image dans la fenetre */ glViewport( 0, 0, w, h ); /* transformation perspective */ glMatrixMode( GL_PROJECTION ); glLoadIdentity(); if( ratio>1 ){ /* etirer le frustum horizontalement */ glFrustum( -cF*ratio, cF*ratio, -cF, cF, -tb_translation[2]-pF, -tb_translation[2]+pF ); } else { /* etirer le frustum verticalement */ glFrustum( -cF, cF, -cF/ratio, cF/ratio, -tb_translation[2]-pF, -tb_translation[2]+pF ); } } /* Prise en compte des touches frappees */ static void key( unsigned char key, int x, int y ) { if( key == 27 ){ /* touche ESCAPE */ exit(0); } else if( key == 'h' ){ printf("\nBouton gauche pour tourner selon XY,\n"); printf("Bouton droit pour translater selon XY,\n"); printf("Bouton du milieu pour tourner et avancer selon Z.\n"); } } /* Gestion de la souris */ int ancienx, ancieny, tournerXY=0, translaterXY=0, bougerZ=0; /* Boutons de la souris */ void mouse( int button, int state, int x, int y ) { /* enfoncer gauche */ if( button==GLUT_LEFT_BUTTON && state==GLUT_DOWN ){ tournerXY = 1; ancienx = x; ancieny = y; } /* relacher gauche */ else if( button==GLUT_LEFT_BUTTON && state==GLUT_UP ){ tournerXY = 0; } /* enfoncer milieu */ if( button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN ){ bougerZ = 1; ancienx = x; ancieny = y; } /* relacher milieu */ else if( button==GLUT_MIDDLE_BUTTON && state==GLUT_UP ){ bougerZ = 0; } /* enfoncer droit */ else if( button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN ){ translaterXY = 1; ancienx = x; ancieny = y; } /* relacher droit */ else if( button==GLUT_RIGHT_BUTTON && state==GLUT_UP ){ translaterXY = 0; } } /* Changement de position de la souris */ void mouseMotion( int x, int y ) { double dx,dy,nrm; if( tournerXY || translaterXY || bougerZ ) { /* deplacement */ dx = x - ancienx; dy = ancieny - y; /* axe vertical dans l'autre sens */ if( tournerXY ){ nrm = sqrt( dx*dx+dy*dy+dx*dx+dy*dy ); glLoadIdentity(); glRotatef( nrm, -dy, dx, 0 );/*axe perpendiculaire au deplacement*/ glMultMatrixf( tb_rotation ); glGetFloatv( GL_MODELVIEW_MATRIX, tb_rotation ); } else if( translaterXY ){ tb_translation[0] += dx/100.0; tb_translation[1] += dy/100.0; } else { tb_translation[2] += dy/100.0; glLoadIdentity(); glRotatef( dx, 0,0,-1 );/*axe perpendiculaire a l'ecran*/ glMultMatrixf( tb_rotation ); glGetFloatv( GL_MODELVIEW_MATRIX, tb_rotation ); } ancienx = x; ancieny = y; display(); } } /* programme principal */ int main( int argc, char* argv[] ) { /* Initialisations */ glutInit( &argc, argv ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB ); /* double buffer */ glutInitWindowSize( 400, 400 ); glutCreateWindow("Cube"); glClearColor( 0.4, 0.4, 0.6, 0.0 ); printf("Tapez h pour obtenir de l'aide\n"); printf("Tapez ESCAPE pour quitter l'application\n"); /* Fonctions pouvant etre appelees dans la boucle principale */ glutReshapeFunc( reshape ); /* redimensionnement fenetre */ glutDisplayFunc( display ); /* affichage */ glutKeyboardFunc( key ); /* touches du clavier */ glutMouseFunc( mouse ); /* boutons de la souris */ glutMotionFunc( mouseMotion );/* deplacement de la souris */ /* Lancement de la boucle principale */ glutMainLoop(); /* Cette instruction n'est jamais executee */ return 0; }