Correction |
|
Mercredi 5 Avril 2000 - 1h25 | |
Exercice 1: OpenGL Le cube est constitué d'un ensemble de 6 facettes carrées. Pour permettre à OpenGL de gérer les ombrages, il faut définir les normales aux facettes. Pour permettre à OpenGL d'effectuer un placage de texture, il faut définir la position de chaque sommet de chaque facette au sein de la bitmap qui tient lieu de texture. /* -------------------------------------------------- */ /* Dessin d'un cube de cote cote, avec gestion des */ /* ombrages et d'une texture */ /* -------------------------------------------------- */ void myAuxSolidCube(double cote) { // sommets du cube static GLfloat vdata[8][3] = { { 0.5, 0.5,-0.5},{ 0.5,-0.5,-0.5}, {-0.5,-0.5,-0.5},{-0.5, 0.5,-0.5}, { 0.5, 0.5, 0.5},{ 0.5,-0.5, 0.5}, {-0.5,-0.5, 0.5},{-0.5, 0.5, 0.5}} ; // indexes des sommets des facettes static GLint t[6][4] = { {0,1,2,3}, {7,6,5,4}, {5,6,2,1}, {0,3,7,4}, {6,7,3,2}, {4,5,1,0}} ; // normales aux facettes static GLfloat ndata[6][3] = { { 0.0, 0.0,-1.0}, { 0.0, 0.0, 1.0}, { 0.0,-1.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}} ; // empilement de la transformation courante glPushMatrix(); // mise a l'echelle d'un facteur cote glScaled(cote,cote,cote) ; // dessin de chaque facette for ( int i = 0 ; i < 6 ; i++ ) { // facette a quatre sommets glBegin(GL_QUADS) ; // definition de la normale a la facette (ombrage) glNormal3fv(&ndata[i][0]); // definitions successives des quatre sommets et // de leurs positions dans la texture glTexCoord2f(0.0F,0.0F) ; glVertex3fv(&vdata[t[i][0]][0]); glTexCoord2f(1.0F,0.0F) ; glVertex3fv(&vdata[t[i][1]][0]); glTexCoord2f(1.0F,1.0F) ; glVertex3fv(&vdata[t[i][2]][0]); glTexCoord2f(0.0F,1.0F) ; glVertex3fv(&vdata[t[i][3]][0]); glEnd() ; } // depilement de la transformation courante glPopMatrix(); } /* -------------------------------------------------- */ Fichier C++ complet : Exo1.cpp Exercice 2: OpenGL Pas de difficulté particulière. /* ************************************************** */ static int anim = 0 ; static int image = 0 ; /* ************************************************** */ /* -------------------------------------------------- */ /* Fonction d'initialisation. */ /* - Une lumiere blanche */ /* - Matiere diffusante rouge */ /* - Activation de l'elimination des parties cachees */ /* -------------------------------------------------- */ void myinit(void) { GLfloat light_ambient[] = { 0.0F,0.0F,0.0F,1.0F }; GLfloat light_diffuse[] = { 1.0F,1.0F,1.0F,1.0F }; GLfloat light_specular[] = { 1.0F,1.0F,1.0F,1.0F }; GLfloat light_position[] = { 1.0F,1.0F,1.0F,0.0F }; glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse); glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular); glLightfv(GL_LIGHT0,GL_POSITION,light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); GLfloat rouge[] = { 1.0F,0.0F,0.0F,0.0F }; glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,rouge); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); } /* -------------------------------------------------- */ /* Dessin d'une image. */ /* - Effacement de la fenetre. */ /* - Empilement de la transformation courante. */ /* - Translation selon l'axe y de valeur fonction */ /* du numero de l'image. */ /* - Dessin de la sphere. */ /* - Flush de l'image. */ /* - Depilement de la transformation courante. */ /* -------------------------------------------------- */ void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); if ( image < 100 ) glTranslatef(0.0F,10.0F-image*image/1000,0.0F) ; else glTranslatef(0.0F,10.0F-(200-image)*(200-image)/1000,0.0F) ; auxSolidSphere(1.0) ; glPopMatrix(); glFlush(); auxSwapBuffers(); } /* -------------------------------------------------- */ /* Gestion de l'animation. */ /* Si une animation est en cours : */ /* - Le numero de l'image est incremente. */ /* - Si le numero de l'image devient superieur */ /* a 200, il redevient egal a 0 et l'animation */ /* est desactivee. */ /* - Le dessin d'une image est demande. */ /* -------------------------------------------------- */ void CALLBACK idle(void) { if ( anim ) { image++ ; if ( image > 200 ) { image = 0 ; anim = 0 ; } display() ; } } /* -------------------------------------------------- */ /* Activation/Desactivation de l'animation. */ /* -------------------------------------------------- */ void CALLBACK keyA(void) { anim = !anim ; } /* ************************************************** */ Fichier C++ complet : Exo2.cpp Exercice 3: Infographie classique Question a La solution proposée consiste à
dessiner le segment de n pixels d'épaisseur comme n segments adjacents décalés par
rapport au segment défini par les deux sommets. Le décalage est horizontal ou vertical
suivant l'orientation du segment générateur: /* -------------------------------------------------- */ /* Fonction de dessin d'une suite horizontale ou */ /* verticale de n pixels autour d'une position */ /* de reference (x,y) avec la couleur c. */ /* dx et dy definissent les dimensions en x et en y */ /* permettant de choisir entre horizontal (dy>dx) */ /* et vertical (sinon). */ /* -------------------------------------------------- */ void pixelAvecEpaisseur(int x,int y,float *c,int n, int dx,int dy) { if ( dx > dy ) for ( int i = y-n/2 ; i < y-n/2+n ; i++ ) pixel(x,i,c) ; else for ( int i = x-n/2 ; i < x-n/2+n ; i++ ) pixel(i,y,c) ; } /* -------------------------------------------------- */ /* Dessin d'un segment tirete (p1,p2) de couleur c, */ /* n pixels allumes suivis de m pixels non modifies : */ /* Algorithme de Bresenham avec fonction de dessin */ /* d'un pixel modifie de maniere a dessiner plusieurs */ /* pixels autour (horizontalement ou verticalement */ /* en fonction de l'orientation du segment) */ /* de la position de reference */ /* -------------------------------------------------- */ void ligneAvecEpaisseur(float *c,int *p1,int *p2,int n) { int dx,dy,i,xinc,yinc,cumul,x,y ; x = p1[0] ; y = p1[1] ; dx = p2[0] - p1[0] ; dy = p2[1] - p1[1] ; xinc = ( dx > 0 ) ? 1 : -1 ; yinc = ( dy > 0 ) ? 1 : -1 ; dx = abs(dx) ; dy = abs(dy) ; pixelAvecEpaisseur(x,y,c,n,dx,dy) ; if ( dx > dy ) { cumul = dx / 2 ; for ( i = 1 ; i <= dx ; i++ ) { x += xinc ; cumul += dy ; if (cumul >= dx) { cumul -= dx ; y += yinc ; } pixelAvecEpaisseur(x,y,c,n,dx,dy) ; } } else { cumul = dy / 2 ; for ( i = 1 ; i <= dy ; i++ ) { y += yinc ; cumul += dx ; if ( cumul >= dy ) { cumul -= dy ; x += xinc ; } pixelAvecEpaisseur(x,y,c,n,dx,dy) ; } } } /* -------------------------------------------------- */ Question b La solution proposée consiste à tracer un segment normal si ce n'est que m pixels sur n+m pixels seront ignorés (les pixels n, n+1, n+2, ..., n+m-1). Cette discrimination est effectuée au moment où chaque pixel sera tracé. /* -------------------------------------------------- */ /* Fonction de dessin d'un pixel de couleur c */ /* en position (x,y) si le numero p du pixel est tel */ /* que p modulo (n+m) est inferieur strictement a n. */ /* -> n pixels traces consecutivement puis m places */ /* libres et ainsi de suite. */ /* -------------------------------------------------- */ void pixelTirete(int x,int y,float *c,int n,int m,int p) { if ( p%(n+m) < n ) pixel(x,y,c) ; } /* -------------------------------------------------- */ /* Dessin d'un segment tirete (p1,p2) de couleur c, */ /* n pixels allumes suivis de m pixels non modifies : */ /* Algorithme de Bresenham avec fonction de dessin */ /* d'un pixel modifie de maniere a tester le numero */ /* du pixel pour dessiner ou non. */ /* -------------------------------------------------- */ void ligneTirete(float *c,int *p1,int *p2,int n,int m) { int dx,dy,i,xinc,yinc,cumul,x,y ; x = p1[0] ; y = p1[1] ; dx = p2[0] - p1[0] ; dy = p2[1] - p1[1] ; xinc = ( dx > 0 ) ? 1 : -1 ; yinc = ( dy > 0 ) ? 1 : -1 ; dx = abs(dx) ; dy = abs(dy) ; pixelTirete(x,y,c,n,m,0) ; if ( dx > dy ) { cumul = dx / 2 ; for ( i = 1 ; i <= dx ; i++ ) { x += xinc ; cumul += dy ; if (cumul >= dx) { cumul -= dx ; y += yinc ; } pixelTirete(x,y,c,n,m,i) ; } } else { cumul = dy / 2 ; for ( i = 1 ; i <= dy ; i++ ) { y += yinc ; cumul += dx ; if ( cumul >= dy ) { cumul -= dy ; x += xinc ; } pixelTirete(x,y,c,n,m,i) ; } } } /* -------------------------------------------------- */ Fichier C++
complet : Exo3.cpp |
|
Remarques, erreurs |