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 |
|