/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Mai 2002 */ /* Examen de TD 2000-2001 : Question 3 */ /* Modelisation d'une sphere avec facettes */ /* normales et coordonnees de texturage */ #include #include #include #include #include #include #include "ModuleMenus.h" #include "ModuleReshape.h" #include "ModuleManipulateur.h" #include "ModuleCouleurs.h" typedef float vecteur[3]; typedef float texture[2]; #define LI 64 #define LH 64 static int aff = 0; static int obj = 0; static int disc = 18; static GLubyte image[LI][LH][3]; void makeImage(void) { int i,j,c; for( i = 0 ; i < LI ; i++ ) { for( j = 0 ; j < LH ; j++ ) { c =(((i&0x8)==0)^((j&0x8)==0))*255; image[i][j][0] =(GLubyte) 255; image[i][j][1] =(GLubyte) c; image[i][j][2] =(GLubyte) c; } } } void myinit(void) { makeImage(); glTexImage2D(GL_TEXTURE_2D,0,3,LI,LH,0,GL_RGB,GL_UNSIGNED_BYTE,&image[0][0][0]); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glClearColor(0.5F,0.5F,0.8F,1.0F) ; glEnable(GL_NORMALIZE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); } vecteur **coordonnees(int n,int m) { vecteur **p =(vecteur **) calloc(n,sizeof(vecteur *)); int i; for ( i = 1 ; i <= n ;i++ ) { p[i-1] =(vecteur *) calloc(m,sizeof(vecteur)); 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); } texture **textures(int n,int m) { texture **p =(texture **) calloc(n+2,sizeof(texture *)); int i; for ( i = 0 ; i <= n+1 ; i++ ) { p[i] =(texture *) calloc(m+1,sizeof(texture)); float a =(float) i/(n+1); for ( int j = 0 ; j <= m ;j++ ) { float b =(float) j/m; p[i][j][0] = a; p[i][j][1] = b; } } return(p); } void gouraudFacette3(vecteur p1,vecteur p2,vecteur p3,texture t1,texture t2,texture t3) { glTexCoord2fv(t1); glNormal3fv(p1); glVertex3fv(p1); glTexCoord2fv(t2); glNormal3fv(p2); glVertex3fv(p2); glTexCoord2fv(t3); glNormal3fv(p3); glVertex3fv(p3); } void gouraudFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,texture t1,texture t2,texture t3,texture t4) { glTexCoord2fv(t1); glNormal3fv(p1); glVertex3fv(p1); glTexCoord2fv(t2); glNormal3fv(p2); glVertex3fv(p2); glTexCoord2fv(t3); glNormal3fv(p3); glVertex3fv(p3); glTexCoord2fv(t4); glNormal3fv(p4); glVertex3fv(p4); } void sphere2(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); texture **t = textures(n,m); int i; glBegin(GL_TRIANGLES); for ( i = 0 ; i < m ; i++ ) { gouraudFacette3(p[0][i],p[0][(i+1)%m],inf,t[1][i],t[1][i+1],t[0][i]); } for ( i = 0 ; i < m ; i++ ) { gouraudFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,t[n][i],t[n][i+1],t[n+1][i]); } 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],t[j+1][i],t[j+1][i+1],t[j+2][i+1],t[j+2][i]); } } glEnd(); for ( i = 0 ; i < n ; i++ ) free(p[i]); free(p); for ( i = 0 ; i <= n+1 ; i++ ) free(t[i]); free(t); } void vertex(float csa,float sna,float csb,float snb,float ts,float tt) { float x = csb*csa; float y = snb*csa; float z = sna; glTexCoord2f(ts,tt); glNormal3f(x,y,z); glVertex3f(x,y,z); } void sphere1(int n) { glBegin(GL_QUADS); for ( int i = 0 ; i < n ;i++ ) { float ta1 =(float) i/n; float ta2 =(float) (i+1)/n; float a1 = -3.14159F/2.0F + i*3.14159F/n; float csa1 = cos(a1); float sna1 = sin(a1); float a2 = -3.14159F/2.0F + (i+1)*3.14159F/n; float csa2 = cos(a2); float sna2 = sin(a2); for ( int j = 0 ; j < n ;j++ ) { float tb1 =(float) j/n; float tb2 =(float) (j+1)/n; float b1 = j*3.14159F*2.0F/n; float csb1 = cos(b1); float snb1 = sin(b1); float b2 = (j+1)*3.14159F*2.0F/n; float csb2 = cos(b2); float snb2 = sin(b2); vertex(csa1,sna1,csb1,snb1,ta1,tb1); vertex(csa1,sna1,csb2,snb2,ta1,tb2); vertex(csa2,sna2,csb2,snb2,ta2,tb2); vertex(csa2,sna2,csb1,snb1,ta2,tb1); } } glEnd(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); switch ( aff ) { case 0 : glEnable(GL_TEXTURE_2D); break; case 1 : glDisable(GL_TEXTURE_2D); break; } switch ( obj ) { case 0 : sphere1(disc); break; case 1 : sphere2(disc,disc); break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 43 : disc++ ; glutPostRedisplay() ; break ; case 45 : disc-- ; if ( disc < 3 ) disc = 3; glutPostRedisplay() ; break ; case ' ' : obj = (obj+1)%2 ; glutPostRedisplay() ; break ; case 0x0D : aff = (aff+1)%2 ; 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("Modelisation 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); }