/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Octobre 2008 */ /* Typologie des lumieres */ #include #include #include #include #include #include #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #ifndef M_PI #define M_PI 3.14159 #endif static int disc = 200; static int fill = 1; static int type = 0; static GLfloat l_pos[] = { 0.0,0.0,6.0,1.0 }; static GLfloat l_dir[] = { 0.0,0.0,1.0,0.0 }; static int attenuation = 0; static float ouverture = 30.0F; static float spotDir[] = { 0.0F,0.0F,-1.0F }; static float shininess = 100.0F; static int obj = 0; static int mode = 0; static const GLfloat blanc[] = { 1.0,1.0,1.0,1.0 }; static const GLfloat rouge[] = { 1.0,0.0,0.0,1.0 }; static const GLfloat noir[] = { 0.0,0.0,0.0,1.0 }; static const GLfloat gris[] = { 0.7,0.7,0.7,1.0 }; typedef struct Position { float x ; float y ; float z ; } Position ; void dessineFacette(Position *p1,Position *p2,Position *p4,int disc) { float dx1 = (p2->x-p1->x)/disc; float dy1 = (p2->y-p1->y)/disc; float dz1 = (p2->z-p1->z)/disc; float dx2 = (p4->x-p1->x)/disc; float dy2 = (p4->y-p1->y)/disc; float dz2 = (p4->z-p1->z)/disc; glNormal3f(0.0F,0.0F,1.0F); glBegin(GL_QUADS); for ( int i = 0 ; i < disc ; i++ ) for ( int j = 0 ; j < disc ; j++ ) { Position pp1 = { p1->x+i*dx1+j*dx2, p1->y+i*dy1+j*dy2, p1->z+i*dz1+j*dz2}; Position pp2 = { pp1.x+dx1,pp1.y+dy1,pp1.z+dz1 }; Position pp3 = { pp1.x+dx1+dx2,pp1.y+dy1+dy2,pp1.z+dz1+dz2 }; Position pp4 = { pp1.x+dx2,pp1.y+dy2,pp1.z+dz2 }; glVertex3fv((float *) &pp1); glVertex3fv((float *) &pp2); glVertex3fv((float *) &pp3); glVertex3fv((float *) &pp4); } glEnd(); } void displayLumierePonctuelle(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glPolygonMode(GL_FRONT_AND_BACK,(fill) ? GL_FILL : GL_LINE); manipulateurSouris(); manipulateurClavier(); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess); switch ( mode ) { case 0 : glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); break; case 1 : glLightfv(GL_LIGHT0,GL_SPECULAR,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); break; case 2 : glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_DIFFUSE,noir); break; case 3 : glLightfv(GL_LIGHT0,GL_SPECULAR,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,noir); break; } glRotatef(-50.0F,1.0F,0.0F,0.0F); glLightfv(GL_LIGHT0,GL_POSITION,l_pos); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,180.0F); switch ( attenuation ) { case 0 : glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F); break; case 1 : glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,1.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F); break; case 2 : glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.0F); break; } Position p1 = { -8.0F,-8.0F,0.0F } ; Position p2 = { 8.0F,-8.0F,0.0F } ; Position p3 = { -8.0F, 8.0F,0.0F } ; glEnable(GL_LIGHTING); switch ( obj ) { case 0 : dessineFacette(&p1,&p2,&p3,disc); break; case 1 : glutSolidTorus(2.0F,6.0F,disc,disc); break; } glTranslatef(l_pos[0],l_pos[1],l_pos[2]); glColor4fv(blanc); glDisable(GL_LIGHTING); glutSolidSphere(0.3F,36,36); glPopMatrix(); glFlush(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur : %d\n",error); } void displayLumiereDirectionnelle(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glPolygonMode(GL_FRONT_AND_BACK,(fill) ? GL_FILL : GL_LINE); manipulateurSouris(); manipulateurClavier(); glRotatef(-50.0F,1.0F,0.0F,0.0F); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess); switch ( mode ) { case 0 : glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); break; case 1 : glLightfv(GL_LIGHT0,GL_SPECULAR,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); break; case 2 : glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_DIFFUSE,noir); break; case 3 : glLightfv(GL_LIGHT0,GL_SPECULAR,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,noir); break; } glLightfv(GL_LIGHT0,GL_POSITION,l_dir); Position p1 = { -8.0F,-8.0F,0.0F } ; Position p2 = { 8.0F,-8.0F,0.0F } ; Position p3 = { -8.0F, 8.0F,0.0F } ; glEnable(GL_LIGHTING); switch ( obj ) { case 0 : dessineFacette(&p1,&p2,&p3,disc); break; case 1 : glutSolidTorus(2.0F,6.0F,disc,disc); break; } glTranslatef(0.0F,0.0F,7.0F); glColor4fv(blanc); glDisable(GL_LIGHTING); glutSolidSphere(0.2F,36,36); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(-5.0F*l_dir[0],-5.0F*l_dir[1],-5.0F*l_dir[2]); glEnd(); glPopMatrix(); glFlush(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur : %d\n",error); } static void dessineCone(float *dir,float ouverture,int n) { if ( dir[2] != -1.0F ) { if ( dir[2] == 1.0F ) glRotatef(180.0F,1.0F,0.0F,0.0F); else { float angle =(float) (acos(-dir[2])*180.0/3.14159); glRotatef(-angle,-dir[1],dir[0],0.0F); } } ouverture = ouverture/180.0*M_PI; float dx =(float) (4.0*sin(ouverture)); float dz =(float) (-4.0*cos(ouverture)); for ( int i = 0 ; i < n ; i++ ) { glPushMatrix(); float angle = i*360.0F/n; glRotatef(angle,0.0F,0.0F,1.0F); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(dx,0.0F,dz); glEnd(); glPopMatrix(); } } void displayLumiereSpot(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glPolygonMode(GL_FRONT_AND_BACK,(fill) ? GL_FILL : GL_LINE); manipulateurSouris(); manipulateurClavier(); glRotatef(-50.0F,1.0F,0.0F,0.0F); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess); switch ( mode ) { case 0 : glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); break; case 1 : glLightfv(GL_LIGHT0,GL_SPECULAR,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); break; case 2 : glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_DIFFUSE,noir); break; case 3 : glLightfv(GL_LIGHT0,GL_SPECULAR,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,noir); break; } glLightfv(GL_LIGHT0,GL_POSITION,l_pos); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,ouverture); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spotDir); switch ( attenuation ) { case 0 : glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F); break; case 1 : glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,1.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F); break; case 2 : glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.0F); break; } Position p1 = { -8.0F,-8.0F,0.0F } ; Position p2 = { 8.0F,-8.0F,0.0F } ; Position p3 = { -8.0F, 8.0F,0.0F } ; glEnable(GL_LIGHTING); switch ( obj ) { case 0 : dessineFacette(&p1,&p2,&p3,disc); break; case 1 : glutSolidTorus(2.0F,6.0F,disc,disc); break; } glTranslatef(l_pos[0],l_pos[1],l_pos[2]); glColor4fv(blanc); glDisable(GL_LIGHTING); glutSolidSphere(0.3F,36,36); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(5.0F*spotDir[0],5.0F*spotDir[1],5.0F*spotDir[2]); glEnd(); glColor4fv(gris); dessineCone(spotDir,ouverture,9); glPopMatrix(); glFlush(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur : %d\n",error); } void myinit (void) { glClearColor(0.75,0.75,0.95,1.0) ; glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,rouge); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,blanc); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); } static void rotateX(float *v,float ax) { ax = ax/180.0F*M_PI; float cs =(float) cos(ax); float sn =(float) sin(ax); float m[3][3] = { { 1.0F,0.0F,0.0F }, { 0.0F, cs, -sn }, { 0.0F, sn, cs } }; float nv[3]; for ( int i = 0 ; i < 3 ; i++ ) { nv[i] = 0.0F; for ( int j = 0 ; j < 3 ; j++ ) nv[i] += m[i][j]*v[j]; } for ( int i = 0 ; i < 3 ; i++ ) v[i] = nv[i]; } static void rotateY(float *v,float ay) { ay = ay/180.0F*M_PI; float cs =(float) cos(ay); float sn =(float) sin(ay); float m[3][3] = { { cs,0.0F, sn }, { 0.0F,1.0F,0.0F }, { -sn,0.0F, cs } }; float nv[3]; for ( int i = 0 ; i < 3 ; i++ ) { nv[i] = 0.0F; for ( int j = 0 ; j < 3 ; j++ ) nv[i] += m[i][j]*v[j]; } for ( int i = 0 ; i < 3 ; i++ ) v[i] = nv[i]; } static void rotateZ(float *v,float az) { az = az/180.0F*M_PI; float cs =(float) cos(az); float sn =(float) sin(az); float m[3][3] = { { cs, -sn,0.0F }, { sn, cs,0.0F }, { 0.0F,0.0F,1.0F } }; float nv[3]; for ( int i = 0 ; i < 3 ; i++ ) { nv[i] = 0.0F; for ( int j = 0 ; j < 3 ; j++ ) nv[i] += m[i][j]*v[j]; } for ( int i = 0 ; i < 3 ; i++ ) v[i] = nv[i]; } void key(unsigned char key,int x,int y) { switch ( key ) { case 'm' : case 'M' : mode = (mode+1)%4; glutPostRedisplay(); break; case 'a' : case 'A' : obj = (obj+1)%2; glutPostRedisplay(); break; case 'o' : if ( type == 2 ) { ouverture -= 0.2F; if ( ouverture < 0.0F ) ouverture = 0.0F; else glutPostRedisplay(); } break; case 'O' : if ( type == 2 ) { ouverture += 0.2F; if ( ouverture > 90.0F ) ouverture = 90.0F; else glutPostRedisplay(); } break; case '1' : switch ( type ) { case 1 : rotateX(l_dir,1.0F); glutPostRedisplay(); break; case 2 : rotateX(spotDir,1.0F); glutPostRedisplay(); break; } break; case '4' : switch ( type ) { case 1 : rotateX(l_dir,-1.0F); glutPostRedisplay(); break; case 2 : rotateX(spotDir,-1.0F); glutPostRedisplay(); break; } break; case '2' : switch ( type ) { case 1 : rotateY(l_dir,1.0F); glutPostRedisplay(); break; case 2 : rotateY(spotDir,1.0F); glutPostRedisplay(); break; } break; case '5' : switch ( type ) { case 1 : rotateY(l_dir,-1.0F); glutPostRedisplay(); break; case 2 : rotateY(spotDir,-1.0F); glutPostRedisplay(); break; } case '3' : switch ( type ) { case 1 : rotateZ(l_dir,1.0F); glutPostRedisplay(); break; case 2 : rotateZ(spotDir,1.0F); glutPostRedisplay(); break; } break; case '6' : switch ( type ) { case 1 : rotateZ(l_dir,-1.0F); glutPostRedisplay(); break; case 2 : rotateZ(spotDir,-1.0F); glutPostRedisplay(); break; } break; case 'x' : switch ( type ) { case 0 : case 2 : l_pos[0] -= 0.1F; glutPostRedisplay(); break; } break; case 'X' : switch ( type ) { case 0 : case 2 : l_pos[0] += 0.1F; glutPostRedisplay(); break; } break; case 'y' : switch ( type ) { case 0 : case 2 : l_pos[1] -= 0.1F; glutPostRedisplay(); break; } break; case 'Y' : switch ( type ) { case 0 : case 2 : l_pos[1] += 0.1F; glutPostRedisplay(); break; } break; case 'z' : switch ( type ) { case 0 : case 2 : l_pos[2] -= 0.1F; glutPostRedisplay(); break; } break; case 'Z' : switch ( type ) { case 0 : case 2 : l_pos[2] += 0.1F; glutPostRedisplay(); break; } break; case 0x0D : type =(type+1)%3; switch ( type ) { case 0 : glutDisplayFunc(displayLumierePonctuelle); glutPostRedisplay(); break; case 1 : glutDisplayFunc(displayLumiereDirectionnelle); glutPostRedisplay(); break; case 2 : glutDisplayFunc(displayLumiereSpot); glutPostRedisplay(); break; } break; case ' ' : if ( ( type == 0 ) || ( type == 2 ) ) { attenuation = (attenuation+1)%3; glutPostRedisplay(); } break; case 'F' : case 'f' : fill = !fill; glutPostRedisplay(); break; case 's' : shininess += 1.0F; if ( shininess > 128.0F ) shininess = 128.0F; glutPostRedisplay(); break; case 'S' : shininess -= 1.0F; if ( shininess < 0.0F ) shininess = 0.0F; glutPostRedisplay(); break; case 43 : disc++; glutPostRedisplay(); break; case 45 : disc--; if ( disc < 3 ) disc = 3; glutPostRedisplay(); break; case 0x1B : exit(0); } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(220,200); glutInitWindowPosition(50,50); glutCreateWindow("Typologie des lumières"); myinit(); creationMenuBasique(); setParametresPerspectiveBasique(35.0F,1.5F,1.0F,30.0F,0.0F,0.0F,-20.0F); setManipulateurDistance(20.0F); glutReshapeFunc(reshapePerspectiveBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutIdleFunc(idleBasique); glutDisplayFunc(displayLumierePonctuelle); glutMainLoop(); return(0); }