/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Mars 2002 */ /* Une bouteille de Klein */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #define LI 64 #define LH 64 static GLubyte image[LI][LH][3]; static int npv = 20; static int npu = 60; static int aff = 0; static int texture = 1; static int light = 1; static float **au; static float **av; static float **x; static float **y; static float **z; static float **nx; static float **ny; static float **nz; 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 normalize(double *x,double *y,double *z) { double d =sqrt(*x**x+*y**y+*z**z); *x /= d; *y /= d; *z /= d; } void bouteilleDeKlein(void) { int i,j; glPushMatrix(); switch ( aff ) { case 0 : glBegin(GL_POINTS); for ( i = 0 ; i < npu ; i++ ) for ( j = 0 ; j < npv ; j++ ) { glTexCoord2f(au[i][j],av[i][j]); glNormal3f(nx[i][j],ny[i][j],nz[i][j]); glVertex3f(x[i][j],y[i][j],z[i][j]); } glEnd(); break; case 1 : for ( i = 0 ; i < npu ; i++ ) for ( j = 0 ; j < npv ; j++ ) { int i2 = i+1; int j2 = j+1; glBegin(GL_LINE_STRIP); glTexCoord2f(au[i2][j],av[i2][j]); glNormal3f(nx[i2][j],ny[i2][j],nz[i2][j]); glVertex3f(x[i2][j],y[i2][j],z[i2][j]); glTexCoord2f(au[i][j],av[i][j]); glNormal3f(nx[i][j],ny[i][j],nz[i][j]); glVertex3f(x[i][j],y[i][j],z[i][j]); glTexCoord2f(au[i][j2],av[i][j2]); glNormal3f(nx[i][j2],ny[i][j2],nz[i][j2]); glVertex3f(x[i][j2],y[i][j2],z[i][j2]); glEnd(); } break; case 2 : glBegin(GL_QUADS); for ( i = 0 ; i < npu ; i++ ) for ( j = 0 ; j < npv ; j++ ) { int i2 = i+1; int j2 = j+1; glTexCoord2f(au[i][j],av[i][j]); glNormal3f(nx[i][j],ny[i][j],nz[i][j]); glVertex3f(x[i][j],y[i][j],z[i][j]); glTexCoord2f(au[i2][j],av[i2][j]); glNormal3f(nx[i2][j],ny[i2][j],nz[i2][j]); glVertex3f(x[i2][j],y[i2][j],z[i2][j]); glTexCoord2f(au[i2][j2],av[i2][j2]); glNormal3f(nx[i2][j2],ny[i2][j2],nz[i2][j2]); glVertex3f(x[i2][j2],y[i2][j2],z[i2][j2]); glTexCoord2f(au[i][j2],av[i][j2]); glNormal3f(nx[i][j2],ny[i][j2],nz[i][j2]); glVertex3f(x[i][j2],y[i][j2],z[i][j2]); } glEnd(); break; } glPopMatrix(); } void initBouteilleDeKlein(void) { int i,j; au =(float **) calloc(npu+1,sizeof(float *)); av =(float **) calloc(npu+1,sizeof(float *)); x =(float **) calloc(npu+1,sizeof(float *)); y =(float **) calloc(npu+1,sizeof(float *)); z =(float **) calloc(npu+1,sizeof(float *)); nx =(float **) calloc(npu+1,sizeof(float *)); ny =(float **) calloc(npu+1,sizeof(float *)); nz =(float **) calloc(npu+1,sizeof(float *)); for ( i = 0 ; i <= npu ; i++ ) { au[i] =(float *) calloc(npv+1,sizeof(float)); av[i] =(float *) calloc(npv+1,sizeof(float)); x[i] =(float *) calloc(npv+1,sizeof(float)); y[i] =(float *) calloc(npv+1,sizeof(float)); z[i] =(float *) calloc(npv+1,sizeof(float)); nx[i] =(float *) calloc(npv+1,sizeof(float)); ny[i] =(float *) calloc(npv+1,sizeof(float)); nz[i] =(float *) calloc(npv+1,sizeof(float)); } for ( i = 0 ; i <= npu ; i++ ) { for ( j = 0 ; j <= npv ; j++ ) { double angu = i * 2 * 3.14159 / npu; double angv = j * 2 * 3.14159 / npv; au[i][j] = i * 4.75 / npu; av[i][j] = j * 4.75 / npv; double csu = cos(angu); double snu = sin(angu); double csv = cos(angv); double snv = sin(angv); double r = 4.0-csu*2.0; double dxdu; double dydu; double dzdu = 2.0*snv*snu; double dxdv; double dydv; double dzdv = 4.0*csv-2.0*csu*csv; if ( angu <= 3.14159 ) { x[i][j] = 6.0*csu*(1.0+snu)+r*csu*csv; y[i][j] = 16*snu+r*snu*csv; dxdu = -6.0*snu*(1.0+snu)+6.0*csu*csu-4.0*snu*csv+4.0*snu*csu*csv; dxdv = (-4.0+2.0*csu)*csu*snv; dydu = 16*csu+2.0*snu*snu+4.0*csu*(1.0-csu/2); dydv = -(4.0-2.0*csu)*snu*snv; } else { x[i][j] = 6.0*csu*(1.0+snu)-r*csv; y[i][j] = 16*snu; dxdu = -6.0*snu*(1.0+snu)+6.0*csu*csu+2.0*snu*csv; dxdv = 4.0*snv-2.0*csu*snv; dydu = 16*csu; dydv = 0.0; } z[i][j] = r*snv; normalize(&dxdu,&dydu,&dzdu); normalize(&dxdv,&dydv,&dzdv); nx[i][j] = dydu*dzdv-dydv*dzdu; ny[i][j] = dzdu*dxdv-dzdv*dxdu; nz[i][j] = dxdu*dydv-dxdv*dydu; } } } void detruitBouteilleDeKlein(void) { for ( int i = 0 ; i <= npu ; i++ ) { free(au[i]); free(av[i]); free(x[i]); free(y[i]); free(z[i]); free(nx[i]); free(ny[i]); free(nz[i]); } free(au); free(av); free(x); free(y); free(z); free(nx); free(ny); free(nz); } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurBlanc()); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,couleurBlanc()); glColor4fv(couleurBlanc()); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,50.0F); if ( texture ) glEnable(GL_TEXTURE_2D); if ( light ) glEnable(GL_LIGHTING); bouteilleDeKlein(); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glPopMatrix(); glFlush(); glutSwapBuffers(); } void myinit(void) { glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); glEnable(GL_DEPTH_TEST); 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_REPEAT); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glClearColor(0.0,0.0,0.0,1.0); glShadeModel(GL_SMOOTH); glDepthFunc(GL_LESS); GLfloat l_pos[] = { 1.0,1.0,1.0,0.0 }; glLightfv(GL_LIGHT0,GL_POSITION,l_pos); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 'u' : detruitBouteilleDeKlein(); npu++; initBouteilleDeKlein(); glutPostRedisplay(); break; case 'U' : detruitBouteilleDeKlein(); npu--; if ( npu < 6 ) npu = 6; initBouteilleDeKlein(); glutPostRedisplay(); break; case 'v' : detruitBouteilleDeKlein(); npv++; initBouteilleDeKlein(); glutPostRedisplay(); break; case 'V' : detruitBouteilleDeKlein(); npv--; if ( npv < 6 ) npv = 6; initBouteilleDeKlein(); glutPostRedisplay(); break; case ' ' : texture = 1-texture; glutPostRedisplay(); break; case 'l' : light = 1-light; glutPostRedisplay(); break; case 0x0D : aff = (aff+1)%3; glutPostRedisplay(); break; } } int main(int argc,char **argv) { initBouteilleDeKlein(); glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(450,300); glutInitWindowPosition(50,50); glutCreateWindow("Bouteille de Klein"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-16.0,16.0,-16.0,16.0,-50.0,50.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutIdleFunc(idleBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }