/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Decembre 2001 */ /* Une sphere illuminee */ #include #include #include #include #include #include #include "ModuleMatriceVecteur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #include "ModuleManipulateur.h" #include "ModuleCouleurs.h" static int aff = 0; static int niv = 2; static int disc1 = 10; static int disc2 = 10; static vecteur ldir = { 1.0F,1.0F,1.0F,1.0F }; void myinit(void) { glClearColor(0.5F,0.5F,0.8F,1.0F) ; glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); normalise(ldir); } vecteur **coordonnees(int n,int m) { vecteur **p =(vecteur **) calloc(n,sizeof(vecteur *)); int i; for ( i = 0 ; i < n ; i++ ) p[i] =(vecteur *) calloc(m,sizeof(vecteur)); for ( i = 1 ; i <= n ;i++ ) { float a = -3.14159F/2.0F + i*3.14159/(n+1); float csa = cos(a); float sna = sin(a); for ( int j = 0 ; j < m ;j++ ) { float b = j*3.14159F*2.0F/m; float csb = cos(b); float snb = sin(b); p[i-1][j][0] = csb*csa; p[i-1][j][1] = snb*csa; p[i-1][j][2] = sna; } } return(p); } void colorise(vecteur n,vecteur ldir) { float v = produitScalaire(n,ldir); if ( v < 0.0F ) v = 0.0F; glColor3f(v,v,v); } void flatFacette3(vecteur p1,vecteur p2,vecteur p3,float r) { vecteur n; n[0] = p1[0]+p2[0]+p3[0]; n[1] = p1[1]+p2[1]+p3[1]; n[2] = p1[2]+p2[2]+p3[2]; normalise(n); colorise(n,ldir); glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r); glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r); glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); } void flatFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,float r) { vecteur n; n[0] = p1[0]+p2[0]+p3[0]+p4[0]; n[1] = p1[1]+p2[1]+p3[1]+p4[1]; n[2] = p1[2]+p2[2]+p3[2]+p4[2]; normalise(n); colorise(n,ldir); glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r); glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r); glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r); } void flatSphere(float r,int n,int m) { vecteur sup = { 0.0F,0.0F,1.0F }; vecteur inf = { 0.0F,0.0F,-1.0F }; vecteur **p =coordonnees(n,m); int i; glBegin(GL_TRIANGLES); for ( i = 0 ; i < m ; i++ ) { flatFacette3(p[0][i],p[0][(i+1)%m],inf,r); } for ( i = 0 ; i < m ; i++ ) { flatFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,r); } glEnd(); glBegin(GL_QUADS); for ( int j = 0 ; j < n-1 ; j++ ) { for ( i = 0 ; i < m ; i++ ) { flatFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r); } } glEnd(); for ( i = 0 ; i < n ; i++ ) free(p[i]); free(p); } void gouraudFacette3(vecteur p1,vecteur p2,vecteur p3,float r) { colorise(p1,ldir); glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r); colorise(p2,ldir); glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r); colorise(p3,ldir); glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); } void gouraudFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,float r) { colorise(p1,ldir); glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r); colorise(p2,ldir); glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r); colorise(p3,ldir); glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); colorise(p4,ldir); glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r); } void gouraudSphere(float r,int n,int m) { vecteur sup = { 0.0F,0.0F,1.0F }; vecteur inf = { 0.0F,0.0F,-1.0F }; vecteur **p =coordonnees(n,m); int i; glBegin(GL_TRIANGLES); for ( i = 0 ; i < m ; i++ ) { gouraudFacette3(p[0][i],p[0][(i+1)%m],inf,r); } for ( i = 0 ; i < m ; i++ ) { gouraudFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,r); } glEnd(); glBegin(GL_QUADS); for ( int j = 0 ; j < n-1 ; j++ ) { for ( i = 0 ; i < m ; i++ ) { gouraudFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r); } } glEnd(); for ( i = 0 ; i < n ; i++ ) free(p[i]); free(p); } void normaleIntermediaire(vecteur p1,vecteur p2,vecteur p) { p[0] = p1[0]+p2[0]; p[1] = p1[1]+p2[1]; p[2] = p1[2]+p2[2]; normalise(p); } void positionIntermediaire(vecteur p1,vecteur p2,vecteur p) { p[0] = (p1[0]+p2[0])/2.0F; p[1] = (p1[1]+p2[1])/2.0F; p[2] = (p1[2]+p2[2])/2.0F; } void normaleIntermediaire(vecteur p1,vecteur p2,vecteur p3,vecteur p4,vecteur p) { p[0] = p1[0]+p2[0]+p3[0]+p4[0]; p[1] = p1[1]+p2[1]+p3[1]+p4[1]; p[2] = p1[2]+p2[2]+p3[2]+p4[2]; normalise(p); } void positionIntermediaire(vecteur p1,vecteur p2,vecteur p3,vecteur p4,vecteur p) { p[0] = (p1[0]+p2[0]+p3[0]+p4[0])/4.0F; p[1] = (p1[1]+p2[1]+p3[1]+p4[1])/4.0F; p[2] = (p1[2]+p2[2]+p3[2]+p4[2])/4.0F; } void phongFacette3(vecteur p1,vecteur p2,vecteur p3,vecteur n1,vecteur n2,vecteur n3,float r,int niveau) { if ( niveau == 0 ) { colorise(n1,ldir); glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r); colorise(n2,ldir); glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r); colorise(n3,ldir); glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); } else { vecteur p12; positionIntermediaire(p1,p2,p12); vecteur p13; positionIntermediaire(p1,p3,p13); vecteur p23; positionIntermediaire(p2,p3,p23); vecteur n12; normaleIntermediaire(n1,n2,n12); vecteur n13; normaleIntermediaire(n1,n3,n13); vecteur n23; normaleIntermediaire(n2,n3,n23); phongFacette3(p1,p12,p13,n1,n12,n13,r,niveau-1); phongFacette3(p2,p12,p23,n2,n12,n23,r,niveau-1); phongFacette3(p3,p13,p23,n3,n13,n23,r,niveau-1); phongFacette3(p12,p13,p23,n12,n13,n23,r,niveau-1); } } void phongFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,vecteur n1,vecteur n2,vecteur n3,vecteur n4,float r,int niveau) { if ( niveau == 0 ) { colorise(n1,ldir); glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r); colorise(n2,ldir); glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r); colorise(n3,ldir); glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); colorise(n4,ldir); glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r); } else { vecteur p12; positionIntermediaire(p1,p2,p12); vecteur p23; positionIntermediaire(p2,p3,p23); vecteur p34; positionIntermediaire(p3,p4,p34); vecteur p41; positionIntermediaire(p4,p1,p41); vecteur pi; positionIntermediaire(p1,p2,p3,p4,pi); vecteur n12; normaleIntermediaire(n1,n2,n12); vecteur n23; normaleIntermediaire(n2,n3,n23); vecteur n34; normaleIntermediaire(n3,n4,n34); vecteur n41; normaleIntermediaire(n4,n1,n41); vecteur ni; normaleIntermediaire(n1,n2,n3,n4,ni); phongFacette4(p1,p12,pi,p41,n1,n12,ni,n41,r,niveau-1); phongFacette4(p2,p12,pi,p23,n2,n12,ni,n23,r,niveau-1); phongFacette4(p3,p34,pi,p23,n3,n34,ni,n23,r,niveau-1); phongFacette4(p4,p34,pi,p41,n4,n34,ni,n41,r,niveau-1); } } void phongSphere(float r,int n,int m) { vecteur sup = { 0.0F,0.0F,1.0F }; vecteur inf = { 0.0F,0.0F,-1.0F }; vecteur **p =coordonnees(n,m); int i; glBegin(GL_TRIANGLES); for ( i = 0 ; i < m ; i++ ) { phongFacette3(p[0][i],p[0][(i+1)%m],inf,p[0][i],p[0][(i+1)%m],inf,r,niv); } for ( i = 0 ; i < m ; i++ ) { phongFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,p[n-1][i],p[n-1][(i+1)%m],sup,r,niv); } glEnd(); glBegin(GL_QUADS); for ( int j = 0 ; j < n-1 ; j++ ) { for ( i = 0 ; i < m ; i++ ) { phongFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r,niv); } } glEnd(); for ( i = 0 ; i < n ; i++ ) free(p[i]); free(p); } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); switch ( aff ) { case 0 : flatSphere(1.3F,disc1,disc2); break; case 1 : gouraudSphere(1.3F,disc1,disc2); break; case 2 : phongSphere(1.3F,disc1,disc2); break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 'a' : disc1++ ; glutPostRedisplay() ; break ; case 'A' : disc1-- ; if ( disc1 < 3 ) disc1 = 3; glutPostRedisplay() ; break ; case 'b' : disc2++ ; glutPostRedisplay() ; break ; case 'B' : disc2-- ; if ( disc2 < 2 ) disc2 = 2; glutPostRedisplay() ; break ; case 43 : niv++ ; glutPostRedisplay() ; break ; case 45 : niv-- ; if ( niv < 0 ) niv = 0; glutPostRedisplay() ; break ; case 0x0D : aff = (aff+1)%3 ; glutPostRedisplay() ; break ; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(200,200); glutInitWindowPosition(50,50); glutCreateWindow("Modelise sphere"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-1.5,1.5,-1.5,1.5,-50.0,50.0); setManipulateurDistance(1.0F); setManipulateurSourisAngle(20.0F,30.0F,40.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }