/* CHAINE DE TRANSFORMATION ILLUSTRE LES DIFFERENTS SYSTEMES DE COORDONNEES DANS OpenGL: FENETRE CUBE (-1.,-1.,-1.) -> (1.,1.,1.) CAMERA MONDE OBJET ILLUSTRE DEUX MANIERES D'EFFECTUER LA PROJECTION PERSPECTIVE AVEC glFrustum ET gluPerspective ILLUSTRE LE CHANGEMENT D'ANGLE DE VUE ILLUSTRE L'UTILISATION D'UNE PORTION RESTREINTE DE LA FENETRE AVEC glViewport ILLUSTRE LE POSITIONNEMENT DE LA CAMERA AVEC gluLookAt TOUCHES: 'f': MODIFIE L'ANGLE DE VUE 'p': MODIFIE LE MODE DE PROJECTION, SI C'EST BIEN FAIT ON NE DOIT VOIR AUCUN CHANGEMENT DE L'AFFICHAGE 'v': MODIFIE LE POSITIONNEMENT DE LA CAMERA TESTS/EXERCICES A EFFECTUER: CALCULER LES BONNES COORDONNEES DANS LE DESSIN DU CADRE ESSAYER DE CHANGER LA VARIABLE MaProfondeur DANS LE DESSIN DU CADRE PREVOIR AVANT DE TAPER LA TOUCHE 'v' L'ALLURE DE LA SCENE PREVOIR AVANT DE TAPER LA TOUCHE 'f' L'ALLURE DE LA SCENE */ #include #include #include // VARIABLES RELATIVES A LA FENETRE DE L'ECRAN float LargeurFenetre = 400, HauteurFenetre = 400; float RapportDAspect; // LargeurFenetre / HauteurFenetre // VARIABLES RELATIVES A LA PROJECTION CENTRALE float AngleDeVue = 45.0f; // Angle de vue en degres double ZLePlusProche = 1.0, ZLePlusLoin = 1000.0; // VARIABLES STOCKANT LE CHOIX DE L'UTILISATEUR int ChoixAngleDeVue = 0, ChoixVue = 0, ChoixModeDeProjection = 0; // COULEUR DES LUMIERES GLfloat CouleurDeDiffusion[4] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat CouleurAmbiente[4] = { 0.6, 0.6, 0.6, 1.0 }; // POSITION DANS L'ESPACE MONDE DE LA LUMIERE GLfloat PositionSourceLumineuse[4] = {-500.0, 500.0, 500.0, 1.0}; // POSITION ET VERTICALITE DE LA CAMERA GLfloat PositionCamera[2][3] = {{100.0, 100.0, 100.0},{10.0, 100., 10.0}}; // front, HautMonde GLfloat VerticaleCamera[2][3] = {{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}}; void ConversionDeAngleDeVueVersPyramide( double AngleDeVue, double Z, double RapportDAspect, double *GaucheMonde, double *DroiteMonde, double *BasMonde, double *HautMonde) { float TanMoitieAngleDeVue; // Tangente de la moitie de l'angle de vue TanMoitieAngleDeVue = tan((AngleDeVue*(3.14159257)/180.0)/2.0); // tan( AngleDeVue converti de degres a radian / 2) *GaucheMonde = -Z * RapportDAspect * TanMoitieAngleDeVue, *DroiteMonde = +Z * RapportDAspect * TanMoitieAngleDeVue, *BasMonde = -Z * TanMoitieAngleDeVue, *HautMonde = +Z * TanMoitieAngleDeVue; } // INFORMATION TEXTUELLES void AfficheInformationTextuelle() { double GaucheMonde, DroiteMonde, BasMonde, HautMonde; printf("Touches: 'f', 'p', 'v' modifient l'angle de vue, la projection et le positionnement de la camera\n"); printf(" Angle de Vue %.2f Largeur Fenetre %.2f Hauteur Fenetre %.2f Rapport d'Aspect %.2f\n", AngleDeVue, LargeurFenetre, HauteurFenetre, RapportDAspect); if (ChoixModeDeProjection % 2 == 0) printf(" Projection par gluPerspective(%.2f, %.2f, %.2f, %.2f) \n", AngleDeVue, RapportDAspect, ZLePlusProche, ZLePlusLoin); else printf(" Projection par glFrustum(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f) \n", GaucheMonde, DroiteMonde, BasMonde, HautMonde, ZLePlusProche, ZLePlusLoin); printf(" Position de la camera: (%.0f %.0f %.0f ) \n\n", PositionCamera[ChoixVue][0], PositionCamera[ChoixVue][1], PositionCamera[ChoixVue][2]); } void GestionEvenementClavier(unsigned char CodeTouche, int x, int y) { switch (CodeTouche) { case 27: exit(-1); case 'f' : // Changement de l'angle de vue ChoixAngleDeVue = (ChoixAngleDeVue + 1) % 2; if (ChoixAngleDeVue) AngleDeVue = 60.0f; else AngleDeVue = 45.0f; glutPostRedisplay(); break; case 'p' : // Changement du mode de projection ChoixModeDeProjection = (ChoixModeDeProjection + 1) % 2; glutPostRedisplay(); break; case 'v' : // Changement de la vue (position de la camera) ChoixVue = (ChoixVue + 1) % 2; glutPostRedisplay(); break; } } void DessinDuCadreDeProjectionDansLeRepereCamera() { double GaucheMonde, DroiteMonde, BasMonde, HautMonde; double MaProfondeur; ConversionDeAngleDeVueVersPyramide( AngleDeVue, ZLePlusProche, RapportDAspect, &GaucheMonde, &DroiteMonde, &BasMonde, &HautMonde); glLineWidth(10); glBegin(GL_LINES); glColor3f( 1., 0., 0.); MaProfondeur = ZLePlusProche; glVertex3f( GaucheMonde, BasMonde, -MaProfondeur); glVertex3f( GaucheMonde, HautMonde, -MaProfondeur); glVertex3f( DroiteMonde, BasMonde, -MaProfondeur); glVertex3f( DroiteMonde, HautMonde, -MaProfondeur); glVertex3f( GaucheMonde, BasMonde, -MaProfondeur); glVertex3f( DroiteMonde, BasMonde, -MaProfondeur); glVertex3f( GaucheMonde, HautMonde, -MaProfondeur); glVertex3f( DroiteMonde, HautMonde, -MaProfondeur); glEnd(); } void GestionChangementFenetre(int Largeur, int Hauteur) { LargeurFenetre = Largeur; HauteurFenetre = Hauteur; RapportDAspect = LargeurFenetre/HauteurFenetre; // DETERMINATION DE LA TRANSFORMATION 2D + profondeur -> Fenetre pixelisee glViewport(0, 0, Largeur, Hauteur); // UTILISATION DE TOUTE LA FENETRE // glViewport(Largeur/3., Hauteur/3., 1./3.*Largeur, 1./3.*Hauteur); // UTILISATION DU 1/3 CENTRAL DE LA FENETRE } void DessinDeLaScene() { double GaucheMonde, DroiteMonde, BasMonde, HautMonde; //--------------------------------------------------------------------------- // PRECALCUL POUR DETERMINER L'EQUIVALENCE ENTRE glFrustum ET gluPerspective // ON N'A BESOIN QUE DE ZLePlusProche!!! ConversionDeAngleDeVueVersPyramide( AngleDeVue, ZLePlusProche, RapportDAspect, &GaucheMonde, &DroiteMonde, &BasMonde, &HautMonde); AfficheInformationTextuelle(); //------------------------------------------------------ // EFFACAGE DES TAMPONS DE DESSIN ET DE PROFONDEUR glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); //------------------------------------------------------------------- // ON REINITIALISE TOUTES LES MATRICES DE TRANSFORMATION A IDENTITE glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //------------------------------------------- // A) ON EST ICI DANS LE REPERE 2D+Profondeur (-1.,-1.,-1.) -> (1.,1.,1.) //------------------------------------------- // PASSAGE DU REPERE CAMERA -> 2D+Profondeur glMatrixMode(GL_PROJECTION); if (ChoixModeDeProjection % 2 == 0) { gluPerspective(AngleDeVue, RapportDAspect, ZLePlusProche, ZLePlusLoin); } else { glFrustum(GaucheMonde, DroiteMonde, BasMonde, HautMonde, ZLePlusProche, ZLePlusLoin); } //------------------------------------------- // B) ON EST ICI DANS LE REPERE CAMERA DessinDuCadreDeProjectionDansLeRepereCamera(); // MATRICE DE MODELISATION // REGLAGE DE L'ECLAIRAGE. // POUR QUE LA LUMIERE SOIT CONSTANTE PAR RAPPORT A LA CAMERA, // I.E. QUE LA LUMIERE SUIVE LES MOUVEMENTS DE LA CAMERA, // IL FAUT QUE LA GEOMETRIE DE LA LUMIERE SOIT PRECISEE DANS LE REPERE CAMERA glLightfv(GL_LIGHT0, GL_DIFFUSE, CouleurDeDiffusion); glLightfv(GL_LIGHT0, GL_POSITION, PositionSourceLumineuse); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, CouleurAmbiente); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); //-------------------------------------------- // PASSAGE DU REPERE MONDE -> REPERE CAMERA // POSITIONNEMENT DE LA CAMERA PAR RAPPORT AU REPERE MONDE gluLookAt( PositionCamera[ChoixVue][0], PositionCamera[ChoixVue][1], PositionCamera[ChoixVue][2], // POSITION DE LA CAMERA 0.0, 0.0, 0.0, // POINT VERS LEQUEL ON REGARDE VerticaleCamera[ChoixVue][0], VerticaleCamera[ChoixVue][1], VerticaleCamera[ChoixVue][2]); // VERTICALE DE LA CAMERA //--------------------------------- // C) ON EST ICI DANS LE REPERE MONDE // DESSIN DES TROIS AXES glLineWidth(3); glBegin(GL_LINES); // DESSIN DE L'AXE Ox MONDE EN ROUGE glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-60.0f, 0.0f, 0.0f); glVertex3f( 60.0f, 0.0f, 0.0f); // DESSIN DE L'AXE Oy MONDE EN VERT glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 60.0f, 0.0f); glVertex3f(0.0f,-60.0f, 0.f); // DESSIN DE L'AXE Oz MONDE EN BLEU glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 60.0f); glVertex3f(0.0f, 0.0f,-60.0f); glEnd(); //-------------------------------- // D) // DESSIN DE L'OBJET glColor3f(0.0f, 1.0f, 1.0f); glEnable( GL_LIGHTING); // ACTIVATION DU CALCUL DES LUMIERES glutSolidTeapot(30.0); // glutSolidCube(30.0); glDisable( GL_LIGHTING); // DESACTIVATION DU CALCUL DES LUMIERES glutSwapBuffers(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(LargeurFenetre, HauteurFenetre); glutCreateWindow("CHAINE DE TRANSFORMATION"); glutDisplayFunc(DessinDeLaScene); glutReshapeFunc(GestionChangementFenetre); glutKeyboardFunc(GestionEvenementClavier); glutMainLoop(); return (0); }