/* Une sphere illuminee */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Septembre 2010 */ #include #include #include #include #include #include #include "CoordonneesHomogenes.h" #include "Position3D.h" #include "Direction3D.h" #include "FacetteTriangulaire.h" #include "LumierePonctuelle.h" #include "Energie.h" #include "Couleur.h" #include "Rotation.h" /* Variables et constantes globales */ /* pour les angles et les couleurs utilises */ static int lum = 0; static float rx = 0.0F; static float ry = 0.0F; static float rz = 0.0F; static int n = 36; static LumierePonctuelle *lp; static Position3D *obs; /* Fonction d'initialisation des parametres */ /* OpenGL ne changeant pas au cours de la vie */ /* du programme */ void init(void) { const GLfloat shininess[] = { 50.0 }; glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_AUTO_NORMAL); } /* Scene dessinee */ void facette(Position3D *p1,Position3D *p2,Position3D *p3, Direction3D *n1,Direction3D *n2,Direction3D *n3) { Couleur *kd; Couleur *kr; switch ( lum ) { case 0 : kd = new Couleur(1.0,0.0,0.0); kr = new Couleur(0.0,0.8,0.8); break; case 1 : kd = new Couleur(1.0,0.0,0.0); kr = new Couleur(0.0,0.0,0.0); break; case 2 : kd = new Couleur(0.0,0.0,0.0); kr = new Couleur(0.0,0.8,0.8); break; } Energie *e1 = new Energie(); Energie *e2 = new Energie(); Energie *e3 = new Energie(); { Energie *ed1 = new Energie(); ed1->calculDiffusion(p1,n1,kd,lp); Energie *er1 = new Energie(); er1->calculReflexionSpeculaire(p1,n1,kr,lp,obs); e1->r = ed1->r+er1->r; e1->v = ed1->v+er1->v; e1->b = ed1->b+er1->b; delete(ed1); delete(er1); } { Energie *ed2 = new Energie(); ed2->calculDiffusion(p2,n2,kd,lp); Energie *er2 = new Energie(); er2->calculReflexionSpeculaire(p2,n2,kr,lp,obs); e2->r = ed2->r+er2->r; e2->v = ed2->v+er2->v; e2->b = ed2->b+er2->b; delete(ed2); delete(er2); } { Energie *ed3 = new Energie(); ed3->calculDiffusion(p3,n3,kd,lp); Energie *er3 = new Energie(); er3->calculReflexionSpeculaire(p3,n3,kr,lp,obs); e3->r = ed3->r+er3->r; e3->v = ed3->v+er3->v; e3->b = ed3->b+er3->b; delete(ed3); delete(er3); } glBegin(GL_TRIANGLES); glColor3dv((double *) e1); glVertex3dv((double *) p1); glColor3dv((double *) e2); glVertex3dv((double *) p2); glColor3dv((double *) e3); glVertex3dv((double *) p3); glEnd(); delete(e1); delete(e2); delete(e3); delete(kd); delete(kr); } #ifndef M_PI #define M_PI 3.14159 #endif void sphere(double r,float n,float m) { for ( int i = 0 ; i < n ; i++ ) { float a1 = -M_PI/2.0F + i*M_PI/n ; float a2 = a1 + M_PI/n ; float cs1 = cos(a1); float cs2 = cos(a2); float sn1 = sin(a1); float sn2 = sin(a2); for ( int j = 0 ; j < m ; j++ ) { float a = j*2*M_PI/m; float b = (j+1)*2*M_PI/m; double csa = cos(a); double sna = sin(a); double csb = cos(b); double snb = sin(b); float ax1 = cs1*csa; float ay1 = cs1*sna; float ax2 = cs2*csa; float ay2 = cs2*sna; float bx1 = cs1*csb; float by1 = cs1*snb; float bx2 = cs2*csb; float by2 = cs2*snb; { Position3D p1(r*bx2,r*by2,r*sn2); Position3D p2(r*ax2,r*ay2,r*sn2); Position3D p3(r*ax1,r*ay1,r*sn1); Direction3D n1(bx2,by2,sn2); Direction3D n2(ax2,ay2,sn2); Direction3D n3(ax1,ay1,sn1); facette(&p1,&p2,&p3,&n1,&n2,&n3); } { Position3D p1(r*bx1,r*by1,r*sn1); Position3D p2(r*bx2,r*by2,r*sn2); Position3D p3(r*ax1,r*ay1,r*sn1); Direction3D n1(bx1,by1,sn1); Direction3D n2(bx2,by2,sn2); Direction3D n3(ax1,ay1,sn1); facette(&p1,&p2,&p3,&n1,&n2,&n3); } } } } void scene() { Rotation *rtx = new Rotation(95.0*sin(rx),1.0,0.0,0.0); Rotation *rty = new Rotation(95.0*sin(ry),0.0,1.0,0.0); Rotation *rtz = new Rotation(rz,0.0,0.0,1.0); TransformationGeometrique *tg = new TransformationGeometrique(); tg->produit(rtx,rty); tg->produit(tg,rtz); Position3D *pos = new Position3D(0.0,0.0,10.0); tg->transforme(pos); Couleur *jaunatre = new Couleur(1.0,1.0,1.0); lp = new LumierePonctuelle(pos,70.0,jaunatre); obs = new Position3D(0.0,0.0,20.0); delete(pos); delete(jaunatre); delete(tg); delete(rtx); delete(rty); delete(rtz); glPushMatrix(); sphere(3.0,n,n); glPopMatrix(); delete(obs); delete(lp); } /* Fonction executee lors d'un rafraichissement */ /* de la fenetre de dessin */ void display(void) { glClearColor(0.5F,0.5F,0.5F,1.0F); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); scene(); glPopMatrix(); 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.00311F ; ry += 0.00634F ; rz += 0.17174F ; 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); glMatrixMode(GL_PROJECTION) ; glLoadIdentity() ; gluPerspective(25.0F,(float) x/y,15.0,35.0) ; glMatrixMode(GL_MODELVIEW) ; glLoadIdentity() ; gluLookAt(0.0,0.0,20.0,0.0,0.0,0.0,0.0,1.0,0.0); } /* Fonction executee lors de l'appui */ /* d'une touche alphanumerique du clavier */ void keyboard(unsigned char key,int x,int y) { switch (key) { case 43 : n++; glutPostRedisplay(); break; case 45 : n--; if ( n == 2 ) n = 3; glutPostRedisplay(); break; case 'f' : { static int face = 1; face = !face; glPolygonMode(GL_FRONT_AND_BACK,( face ) ? GL_FILL : GL_LINE); } glutPostRedisplay(); break; case 0x20 : lum = (lum+1)%3; glutPostRedisplay(); break; case 0x0D : { static int anim = 1; 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 principale */ int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(300,300); glutInitWindowPosition(50,50); glutCreateWindow("Une sphere illuminee"); init(); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutReshapeFunc(reshape); glutIdleFunc(idle); glutDisplayFunc(display); glutMainLoop(); return(0); }