/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2006 */ /* Dessin de divers objets avec texture */ #include #include #include #include #include #include #ifndef M_PI #define M_PI 3.14159 #endif #include "ModuleCouleurs.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" static float anglex = 0.0F; static float angley = 0.0F; static float anglez = 0.0F; static int anim = 1; static int obj = 0; static int n1 = 36; static int n2 = 36; GLubyte *textureDamier(void) { GLubyte *tab =(GLubyte *) malloc(8*8*3*sizeof(GLubyte)); GLubyte *t = tab; for ( int i = 0 ; i < 8 ; i++ ) for ( int j = 0 ; j < 8 ; j++ ) { t[0] = t[1] = t[2] = ( (i+j)%2 ) ? 0x00 : 0xFF; t += 3; } return(tab); } void cube(float c){ c /= 2.0F; glPushMatrix(); glBegin(GL_QUADS); glNormal3f(0.0F,0.0F,-1.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(c,c,-c); glTexCoord2f(0.0F,1.0F); glVertex3f(c,-c,-c); glTexCoord2f(1.0F,1.0F); glVertex3f(-c,-c,-c); glTexCoord2f(1.0F,0.0F); glVertex3f(-c,c,-c); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0F,0.0F,1.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(c,c,c); glTexCoord2f(0.0F,1.0F); glVertex3f(-c,c,c); glTexCoord2f(1.0F,1.0F); glVertex3f(-c,-c,c); glTexCoord2f(1.0F,0.0F); glVertex3f(c,-c,c); glEnd(); glBegin(GL_QUADS); glNormal3f(-1.0F,0.0F,0.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(-c,c,-c); glTexCoord2f(0.0F,1.0F); glVertex3f(-c,-c,-c); glTexCoord2f(1.0F,1.0F); glVertex3f(-c,-c,c); glTexCoord2f(1.0F,0.0F); glVertex3f(-c,c,c); glEnd(); glBegin(GL_QUADS); glNormal3f(1.0F,0.0F,0.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(c,c,c); glTexCoord2f(0.0F,1.0F); glVertex3f(c,-c,c); glTexCoord2f(1.0F,1.0F); glVertex3f(c,-c,-c); glTexCoord2f(1.0F,0.0F); glVertex3f(c,c,-c); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0F,-1.0F,0.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(-c,-c,c); glTexCoord2f(0.0F,1.0F); glVertex3f(-c,-c,-c); glTexCoord2f(1.0F,1.0F); glVertex3f(c,-c,-c); glTexCoord2f(1.0F,0.0F); glVertex3f(c,-c,c); glEnd(); glBegin(GL_QUADS); glNormal3f(0.0F,1.0F,0.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(c,c,c); glTexCoord2f(0.0F,1.0F); glVertex3f(c,c,-c); glTexCoord2f(1.0F,1.0F); glVertex3f(-c,c,-c); glTexCoord2f(1.0F,0.0F); glVertex3f(-c,c,c); glEnd(); glPopMatrix(); } void cylindre1(float r,float h,int n){ float *cs =(float *) calloc(n,sizeof(float)); float *sn =(float *) calloc(n,sizeof(float)); int i; for( i = 0 ; i < n ; i++ ){ float a = (2*M_PI*i)/n; sn[i] = sin(a); cs[i] = cos(a); } glPushMatrix(); glBegin(GL_QUAD_STRIP); for( i = 0 ; i <= n ; i++ ){ float x = r*cs[i%n]; float z = -r*sn[i%n]; glNormal3f(cs[i%n],0.0F,-sn[i%n]); float s =(float) i/n; glTexCoord2f(s,0.0F); glVertex3f(x,h/2,z); glTexCoord2f(s,1.0F); glVertex3f(x,-h/2,z); } glEnd(); glBegin(GL_POLYGON); glNormal3f(0.0F,1.0F,0.0F); for( i = 0 ; i < n ; i++ ){ float si = -r*sn[i]; float ci = r*cs[i]; glTexCoord2f(cs[i]/r,sn[i]/r); glVertex3f(ci,h/2,si); } glEnd(); glBegin(GL_POLYGON); glNormal3f(0.0F,-1.0F,0.0F); for( i = 0 ; i < n ; i++ ){ float si = r*sn[i]; float ci = r*cs[i]; glTexCoord2f(cs[i]/r,sn[i]/r); glVertex3f(ci,-h/2,si); } glEnd(); free(cs); free(sn); glPopMatrix(); } void cylindre2(float r,float h,int n){ float *cs =(float *) calloc(n,sizeof(float)); float *sn =(float *) calloc(n,sizeof(float)); int i; for( i = 0 ; i < n ; i++ ){ float a = (2*M_PI*i)/n; sn[i] = sin(a); cs[i] = cos(a); } glPushMatrix(); glBegin(GL_QUAD_STRIP); for( i = 0 ; i <= n ; i++ ){ float x = r*cs[i%n]; float z = -r*sn[i%n]; glNormal3f(cs[i%n],0.0F,-sn[i%n]); float s =(float) i/n; glTexCoord2f(s,0.0F); glVertex3f(x,h/2,z); glTexCoord2f(s,1.0F); glVertex3f(x,-h/2,z); } glEnd(); glBegin(GL_QUAD_STRIP); glNormal3f(0.0F,1.0F,0.0F); for( i = 0 ; i <= n ; i++ ){ float x = r*cs[i%n]; float z = -r*sn[i%n]; float s =(float) i/n; glTexCoord2f(s,1.0F); glVertex3f(0.0,h/2,0.0); glTexCoord2f(s,0.0F); glVertex3f(x,h/2,z); } glEnd(); glBegin(GL_QUAD_STRIP); glNormal3f(0.0F,-1.0F,0.0F); for( i = 0 ; i <= n ; i++ ){ float x = r*cs[i%n]; float z = -r*sn[i%n]; float s =(float) i/n; glTexCoord2f(s,0.0F); glVertex3f(0.0,-h/2,0.0); glTexCoord2f(s,1.0F); glVertex3f(x,-h/2,z); } glEnd(); free(cs); free(sn); glPopMatrix(); } struct coord3D { float x; float y; float z; }; struct coord2D { float s; float t; }; void sphere1(double r,int lat,int lon) { int npt = 2 + (lat-1)*lon; int ntx = (lat+1)*(lon+1); coord3D *pts =(coord3D *) calloc(npt,sizeof(coord3D)); coord3D *nms =(coord3D *) calloc(npt,sizeof(coord3D)); coord2D *tex =(coord2D *) calloc(ntx,sizeof(coord2D)); pts[0].x = 0.0f; pts[0].y = 0.0f; pts[0].z = r; pts[1].x = 0.0f; pts[1].y = 0.0f; pts[1].z = -r; nms[0].x = 0.0f; nms[0].y = 0.0f; nms[0].z = 1.0F; nms[1].x = 0.0f; nms[1].y = 0.0f; nms[1].z = -1.0F; int n = 0 ; int i,j ; for ( j = 0 ; j < lat+1 ; j++ ) { for ( i = 0 ; i < lon+1 ; i++ ) { tex[n].s =(float) i/lon; tex[n].t =(float) j/lat; n++; } } n = 2 ; for ( j = 0 ; j < (lat-1) ; j++ ) { double aa = M_PI/2.0-(j+1)*M_PI/lat; double c = cos(aa); double s = sin(aa); double rc = r*c; double rs = r*s; for ( i = 0 ; i < lon ; i++ ) { double a = i*M_PI*2.0/lon; double ca = cos(a); double sa = sin(a); pts[n].x = rc*ca; pts[n].y = rc*sa; pts[n].z = rs; nms[n].x = c*ca; nms[n].y = c*sa; nms[n].z = s; n++; } } glBegin(GL_QUAD_STRIP); for ( i = 0 ; i <= lon ; i++ ) { glTexCoord2fv((float *) &tex[i]); glNormal3fv((float *) &nms[0]); glVertex3fv((float *) &pts[0]); glTexCoord2fv((float *) &tex[i+lon+1]); glNormal3fv((float *) &nms[2+i%lon]); glVertex3fv((float *) &pts[2+i%lon]); } glEnd(); for ( j = 0 ; j < lat-2 ; j++ ) { glBegin(GL_QUAD_STRIP); for ( i = 0 ; i <= lon ; i++ ) { glTexCoord2fv((float *) &tex[i+(j+1)*(lon+1)]); glNormal3fv((float *) &nms[2+i%lon+j*lon]); glVertex3fv((float *) &pts[2+i%lon+j*lon]); glTexCoord2fv((float *) &tex[i+(j+2)*(lon+1)]); glNormal3fv((float *) &nms[2+i%lon+j*lon+lon]); glVertex3fv((float *) &pts[2+i%lon+j*lon+lon]); } glEnd(); } glBegin(GL_QUAD_STRIP); for ( i = 0 ; i <= lon ; i++ ) { glTexCoord2fv((float *) &tex[i+lat*(lon+1)]); glNormal3fv((float *) &nms[1]); glVertex3fv((float *) &pts[1]); glTexCoord2fv((float *) &tex[i+(lat-1)*(lon+1)]); glNormal3fv((float *) &nms[2+(lat-2)*lon+i%lon]); glVertex3fv((float *) &pts[2+(lat-2)*lon+i%lon]); } glEnd(); free(tex); free(nms); free(pts); } void calculPositionNormaleCoordTexture(int lt,int lg,int lat,int lon,float r,struct coord3D *p,struct coord3D *n,struct coord2D *t) { t->s =(float) lg/lon; t->t =(float) lt/lat; double aa = M_PI/2.0-t->t*M_PI; double c = cos(aa); double s = sin(aa); double rc = r*c; double rs = r*s; double a = t->s*M_PI*2.0; double ca = cos(a); double sa = sin(a); p->x = rc*ca; p->y = rc*sa; p->z = rs; n->x = c*ca; n->y = c*sa; n->z = s; } void sphere2(double r,int lat,int lon) { struct coord3D p; struct coord3D n; struct coord2D t; for ( int j = 0 ; j < lat ; j++ ) { glBegin(GL_QUAD_STRIP); for ( int i = 0 ; i <= lon ; i++ ) { calculPositionNormaleCoordTexture(j,i,lat,lon,r,&p,&n,&t); glTexCoord2fv((float *) &t); glNormal3fv((float *) &n); glVertex3fv((float *) &p); calculPositionNormaleCoordTexture(j+1,i,lat,lon,r,&p,&n,&t); glTexCoord2fv((float *) &t); glNormal3fv((float *) &n); glVertex3fv((float *) &p); } glEnd(); } } void tore(double ri,double re,int nbi,int nbe) { for ( int i = 0 ; i < nbi ; i++ ) { float alphai = 2*M_PI*i/nbi; float alphaj = alphai+2*M_PI/nbi; float cosalphai = cos(alphai); float sinalphai = sin(alphai); float cosalphaj = cos(alphaj); float sinalphaj = sin(alphaj); glBegin(GL_QUAD_STRIP); for ( int j = 0 ; j <= nbe ; j++ ) { float beta = 2*M_PI*j/nbe; float cosbeta = cos(beta); float sinbeta = sin(beta); float x1 = (ri+re*cosbeta)*cosalphai; float y1 = (ri+re*cosbeta)*sinalphai; float z1 = re*sinbeta; glTexCoord2f((double) i/nbi,(double) j/nbe); glNormal3f(cosbeta*cosalphai,cosbeta*sinalphai,sinbeta); glVertex3f(x1,y1,z1); float x2 = (ri+re*cosbeta)*cosalphaj; float y2 = (ri+re*cosbeta)*sinalphaj; float z2 = re*sinbeta; glTexCoord2f((double) (i+1)/nbi,(double) j/nbe); glNormal3f(cosbeta*cosalphaj,cosbeta*sinalphaj,sinbeta); glVertex3f(x2,y2,z2); } glEnd(); } } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glRotatef(anglex,1.0F,0.0F,0.0F); glRotatef(angley,0.0F,1.0F,0.0F); glRotatef(anglez,0.0F,0.0F,1.0F); switch (obj) { case 0 : cube(3.8F) ; break; case 1 : cylindre1(1.9F,3.8F,n1); break; case 2 : cylindre2(1.9F,3.8F,n1); break; case 3 : sphere1(3.0F,n1,n2); break; case 4 : sphere2(3.0F,n1,n2); break; case 5 : tore(2.3F,1.1F,n1,n2); break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } void myinit (void) { glClearColor(0.5F,0.5F,0.5F,0.0F); glShadeModel(GL_SMOOTH); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); float dir0[4] = { 1.0F,1.0F,1.0F,0.0F }; glLightfv(GL_LIGHT0,GL_POSITION,dir0) ; glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurVert()) ; float dir1[4] = { -1.0F,1.0F,1.0F,0.0F }; glLightfv(GL_LIGHT1,GL_POSITION,dir1) ; glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurBleu()) ; float dir2[4] = { 0.0F,-1.0F,1.0F,0.0F }; glLightfv(GL_LIGHT2,GL_POSITION,dir2) ; glLightfv(GL_LIGHT2,GL_DIFFUSE,couleurRouge()) ; glPixelStorei(GL_UNPACK_ALIGNMENT,1); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D,0,3,8,8,0,GL_RGB,GL_UNSIGNED_BYTE,textureDamier()); glEnable(GL_TEXTURE_2D); } void idle(void) { anglex += 0.31F; angley += 0.37F; anglez += 0.41F; glutPostRedisplay(); } void key(unsigned char key,int x,int y) { static int aff = 1; if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 43 : n1++; glutPostRedisplay(); break; case 45 : n1--; if ( n1 < 3 ) n1 = 3; glutPostRedisplay(); break; case 'N' : n2++; glutPostRedisplay(); break; case 'n' : n2--; if ( n2 < 3 ) n2 = 3; glutPostRedisplay(); break; case ' ' : anim = !anim; glutIdleFunc((anim) ? idle : NULL); break; case 0x0D : obj = (obj+1)%6; glutPostRedisplay(); break; case 'a' : case 'A' : aff = !aff; glPolygonMode(GL_FRONT_AND_BACK,(aff) ? GL_FILL : GL_LINE); glutPostRedisplay(); } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(250,250); glutInitWindowPosition(50,50); glutCreateWindow("Objets avec texture"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-3.5F,3.5F,-3.5F,3.5F,-50.0,50.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutIdleFunc(idle); glutDisplayFunc(display); glutMainLoop(); return(0); }