/* Gestion de materiels et de lumieres */ /* en OpenGL */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Octobre 2009 */ #include #include #include #include #include #include /* Variables et constantes globales */ /* pour les angles et les couleurs utilises */ static int lumiere = 0; static int camera = 0; static int wx; static int wy; static float rx = 0.0F; static float ry = 0.0F; static float rz = 0.0F; /* Scene dessinee */ void cylindre(double h,double r,int n,int m) { glPushMatrix(); glRotatef(90.0F,1.0F,0.0F,0.0F); glTranslatef(0.0F,0.0F,-h/2); GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj,GLU_FILL); gluCylinder(qobj,r,r,h,n,m); gluDeleteQuadric(qobj); glPopMatrix(); } void scene() { GLfloat blanc[4] = { 1.0F,1.0F,1.0F,1.0F }; GLfloat noir[4] = { 0.0F,0.0F,0.0F,1.0F }; GLfloat rouge[4] = { 1.0F,0.0F,0.0F,1.0F }; GLfloat vert[4] = { 0.0F,1.0F,0.0F,1.0F }; GLfloat bleu[4] = { 0.0F,0.0F,1.0F,1.0F }; GLfloat jaune[4] = { 1.0F,1.0F,0.0F,1.0F }; glPushMatrix(); glMaterialfv(GL_FRONT,GL_AMBIENT,noir); glMaterialfv(GL_FRONT,GL_SPECULAR,blanc); glMaterialf(GL_FRONT,GL_SHININESS,50.0F); glPushMatrix(); glTranslatef(2.0F,2.0F,0.0F); glMaterialfv(GL_FRONT,GL_DIFFUSE,rouge); glutSolidCube(2.0); glPopMatrix(); glPushMatrix(); glTranslatef(2.0F,-2.0F,0.0F); glMaterialfv(GL_FRONT,GL_DIFFUSE,vert); glutSolidSphere(1.0,72,72); glPopMatrix(); glPushMatrix(); glTranslatef(-2.0F,2.0F,0.0F); glMaterialfv(GL_FRONT,GL_DIFFUSE,bleu); glRotatef(90.0F,-1.0F,0.0F,0.0F); glTranslatef(0.0F,0.0F,-1.0F); glutSolidCone(1.0,2.0,72,72); glPopMatrix(); glPushMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,jaune); glTranslatef(-2.0F,-2.0F,0.0F); cylindre(2.0,1.0,72,72); glPopMatrix(); glPopMatrix(); } /* Fonction executee lors d'un rafraichissement */ /* de la fenetre de dessin */ void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); double cx; double cy; double cz; switch (camera) { case 0 : cx = 0.0; cy = 0.0; cz = 10.0; break; case 1 : cx = 10.0; cy = 0.0; cz = 10.0; break; case 2 : cx = 10.0; cy = 10.0; cz = 10.0; break; } double d = sqrt(cx*cx+cy*cy+cz*cz); gluPerspective(520.0/d,(float) wx/wy,d-5.0,d+5.0F); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(cx,cy,cz,0.0,0.0,0.0,0.0,1.0,0.0); glRotatef(rx,1.0F,0.0F,0.0F); glRotatef(ry,0.0F,1.0F,0.0F); glRotatef(rz,0.0F,0.0F,1.0F); switch ( lumiere ) { case 0 : { glEnable(GL_LIGHT0); glDisable(GL_LIGHT1); glDisable(GL_LIGHT2); const GLfloat light0_position[] = { 0.0,0.0,0.0,1.0 }; glLightfv(GL_LIGHT0,GL_POSITION,light0_position); } break; case 1 : { glDisable(GL_LIGHT0); glEnable(GL_LIGHT1); glDisable(GL_LIGHT2); const GLfloat light1_position[] = { 1.0,0.0,0.0,0.0 }; glLightfv(GL_LIGHT1,GL_POSITION,light1_position); } break; case 2 : { glDisable(GL_LIGHT0); glDisable(GL_LIGHT1); glEnable(GL_LIGHT2); const GLfloat light2_position[] = { -12.0,0.0,10.0,1.0 }; const GLfloat light2_direction[] = { 1.0,0.0,-1.0,0.0 }; glLightfv(GL_LIGHT2,GL_POSITION,light2_position); glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,light2_direction); } break; case 3 : { glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); const GLfloat light0_position[] = { 0.0,0.0,0.0,1.0 }; glLightfv(GL_LIGHT0,GL_POSITION,light0_position); const GLfloat light1_position[] = { 1.0,0.0,0.0,0.0 }; glLightfv(GL_LIGHT1,GL_POSITION,light1_position); const GLfloat light2_position[] = { -12.0,0.0,10.0,1.0 }; const GLfloat light2_direction[] = { 1.0,0.0,-1.0,0.0 }; glLightfv(GL_LIGHT2,GL_POSITION,light2_position); glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,light2_direction); } break; } scene(); glFlush(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur OpenGL\n",error); } /* Fonction executee lorsqu'aucun evenement */ /* n'est en file d'attente */ void idle(void) { rx += 0.4256F; ry += 0.6117F; rz += 0.4174F; glutPostRedisplay(); } /* Fonction executee lors d'un changement */ /* de la taille de la fenetre OpenGL */ void reshape(int x,int y) { glViewport(0,0,x,y); wx = x; wy = y; } /* Fonction executee lors de l'appui */ /* d'une touche alphanumerique du clavier */ void keyboard(unsigned char key,int x,int y) { switch (key) { case 'c' : camera = (camera+1)%3; glutPostRedisplay(); break; case 'l' : lumiere = (lumiere+1)%4; glutPostRedisplay(); break; case 0x0D : { static int anim = 0; anim = !anim; glutIdleFunc(( anim ) ? idle : NULL); } break; case 0x1B : exit(0); break; } } /* Fonction executee lors de l'appui */ /* d'une touche de curseur ou d'une touche */ /* page up ou page down */ void special(int key,int x,int y) { switch(key) { case GLUT_KEY_UP : rx++; glutPostRedisplay() ; break; case GLUT_KEY_DOWN : rx--; glutPostRedisplay() ; break; case GLUT_KEY_LEFT : ry++; glutPostRedisplay() ; break; case GLUT_KEY_RIGHT : ry--; glutPostRedisplay() ; break; case GLUT_KEY_PAGE_UP : rz++; glutPostRedisplay() ; break; case GLUT_KEY_PAGE_DOWN : rz--; glutPostRedisplay() ; break; } } /* Fonction d'initialisation des parametres */ /* constants d'OpenGL */ static void init(void) { GLfloat blanc[4] = { 1.0F,1.0F,1.0F,1.0F }; GLfloat cyan[4] = { 0.0F,1.0F,1.0F,1.0F }; GLfloat jaune[4] = { 1.0F,1.0F,0.0F,1.0F }; glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT1,GL_DIFFUSE,cyan); glLightfv(GL_LIGHT1,GL_SPECULAR,cyan); glLightf(GL_LIGHT2,GL_SPOT_CUTOFF,8.59F); glLightfv(GL_LIGHT2,GL_DIFFUSE,jaune); glLightfv(GL_LIGHT2,GL_SPECULAR,jaune); } /* Fonction principale */ int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(300,300); glutInitWindowPosition(50,50); glutCreateWindow("Materiels et lumieres OpenGL"); init(); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutReshapeFunc(reshape); //glutIdleFunc(idle); glutDisplayFunc(display); glutMainLoop(); return(0); }