/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Janvier 2004 */ /* Un volume cree par revolution */ /* d'un polygone autour de l'axe Oy */ #include #include #include #include #include #include "ModuleManipulateur.h" #include "ModuleCouleurs.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #include "ModuleMatriceVecteur.h" struct Coord2D { float x; float y; }; struct Polygone2D { struct Coord2D *p; int nbp; }; static int f1; static int f2; static int aff = 1; static struct Coord2D pts1[5] = {{1.0F,1.0F}, {0.5F,2.5F}, {1.5F,4.5F}, {3.5F,3.5F}, {4.0F,0.5F}}; static struct Polygone2D p1 = { pts1,5 }; static struct Coord2D pts2[8] = {{0.5F,2.5F}, {1.0F,4.0F}, {2.5F,4.5F}, {4.0F,4.0F}, {4.5F,2.5F}, {4.0F,1.0F}, {2.5F,0.5F}, {1.0F,1.0F}}; static struct Polygone2D p2 = { pts2,8 }; static int n = 36; static int nn = 25; static int np = 0; static int m = 0; void myinit(void) { GLfloat shinines[] = { 50.0 }; GLfloat l_pos[] = { 1.0,1.0,1.0,0.0 }; glClearColor(0.75F,0.75F,1.0F,1.0F) ; glMaterialfv(GL_FRONT,GL_SPECULAR,couleurBlanc()); glMaterialfv(GL_FRONT,GL_SHININESS,shinines); glLightfv(GL_LIGHT0,GL_POSITION,l_pos); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); } void polygone(Polygone2D *p) { glBegin(GL_LINE_LOOP); for ( int i = 0 ; i < p->nbp ; i++ ) glVertex2fv((float *) &p->p[i]); glEnd(); } void display1() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); switch ( np ) { case 0 : polygone(&p1); break; case 1 : polygone(&p2); break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } vecteur **sommetsVolumeRevolution(Polygone2D *p,int n) { vecteur **pts =(vecteur **) calloc(n,sizeof(vecteur *)); int i,j; for ( j = 0 ; j < n ; j++ ) { float a =(float) j/n*360; matrice m; toRotationY(m,a); pts[j] =(vecteur *) calloc(p->nbp,sizeof(vecteur)); for ( i = 0 ; i < p->nbp ; i++ ) { pts[j][i][0] = p->p[i].x; pts[j][i][1] = p->p[i].y; pts[j][i][2] = 0.0F; pts[j][i][3] = 1.0F; produitMatriceVecteur(m,pts[j][i],pts[j][i]); } } return(pts); } void volumeRevolutionFilDeFer(Polygone2D *p,int n) { vecteur **pts = sommetsVolumeRevolution(p,n); glLineWidth(1); int i; int j; glColor4fv(couleurBleu()); for ( i = 0 ; i < p->nbp ; i++ ) { glBegin(GL_LINE_LOOP); for ( j = 0 ; j < n ; j++ ) { glVertex3fv((float *) &pts[j][i]); } glEnd(); } for ( j = 0 ; j < n ; j++ ) { glLineWidth(( j != nn) ? 1 : 3); glColor4fv(( j != nn) ? couleurRouge() : couleurVertFonce()); glBegin(GL_LINE_LOOP); for ( i = 0 ; i < p->nbp ; i++ ) { glVertex3fv((float *) &pts[j][i]); } glEnd(); } for ( j = 0 ; j < n ; j++ ) free(pts[j]); free(pts); } void calculNormale(vecteur p,vecteur p1,vecteur p2,vecteur n) { vecteur v1; vecteur v2; v1[0] = p1[0] - p[0]; v1[1] = p1[1] - p[1]; v1[2] = p1[2] - p[2]; v2[0] = p2[0] - p[0]; v2[1] = p2[1] - p[1]; v2[2] = p2[2] - p[2]; produitVectoriel(v2,v1,n); } void volumeRevolutionSolid(Polygone2D *p,int n) { vecteur **pts = sommetsVolumeRevolution(p,n); int i; int j; if ( m ) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); else glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); for ( i = 0 ; i < p->nbp ; i++ ) { glBegin(GL_QUAD_STRIP); for ( j = 0 ; j <= n ; j++ ) { vecteur nm; calculNormale(pts[j%n][i%p->nbp],pts[(j+1)%n][i%p->nbp],pts[j%n][(i+1)%p->nbp],nm); glNormal3fv((float *) nm); glVertex3fv((float *) &pts[j%n][i%p->nbp]); glVertex3fv((float *) &pts[j%n][(i+1)%p->nbp]); } glEnd(); } for ( j = 0 ; j < n ; j++ ) free(pts[j]); free(pts); } void display2() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0F,1.0F,0.0F); manipulateurSouris(); manipulateurClavier(); glTranslatef(0.0F,-2.5F,0.0F); switch ( np ) { case 0 : if ( aff ) volumeRevolutionFilDeFer(&p1,n); else { glEnable(GL_LIGHTING); volumeRevolutionSolid(&p1,n); glDisable(GL_LIGHTING); } break; case 1 : if ( aff ) volumeRevolutionFilDeFer(&p2,n); else{ glEnable(GL_LIGHTING); volumeRevolutionSolid(&p2,n); glDisable(GL_LIGHTING); } break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostWindowRedisplay(f2); else switch ( key ) { case ' ' : aff = !aff; glutPostWindowRedisplay(f2); break; case 'm' : case 'M' : m = !m; glutPostWindowRedisplay(f2); break; case 'n' : nn = (nn+1)%n; glutPostWindowRedisplay(f2); break; case 'N' : nn = (nn+n-1)%n; glutPostWindowRedisplay(f2); break; case 45 : n--; if ( n < 3 ) n = 3; nn = nn%n; glutPostWindowRedisplay(f2); break; case 43 : n++; glutPostWindowRedisplay(f2); break; case 0x0D : np = (np+1)%2; glutPostWindowRedisplay(f1); glutPostWindowRedisplay(f2); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitWindowSize(170,170); glutInitWindowPosition(50,50); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); f1 = glutCreateWindow("Polygone"); creationMenuBasique(); glutDisplayFunc(display1); setParametresOrthoBasique(0.0,5.0,0.0,5.0,-50.0,50.0); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutInitWindowSize(250,250); glutInitWindowPosition(70,250); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); f2 = glutCreateWindow("Volume de révolution"); myinit(); creationMenuBasique(); glutDisplayFunc(display2); setParametresPerspectiveBasique(65.0F,1.0F,1.0F,20.0F,0.0F,0.0F,-8.5F); setManipulateurClavierAngle(30.0F,0.0F,10.0F); setManipulateurDistance(5.0F); glutReshapeFunc(reshapePerspectiveBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutMainLoop(); return(0); }