/* Une facette 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 obj = 0; static int lum = 0; static float rx = 0.0F; static float ry = 0.0F; static float rz = 0.0F; static int n = 4; static Rotation *rt = new Rotation(); /* 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) { FacetteTriangulaire *fct = new FacetteTriangulaire(p1,p2,p3); Couleur *kd; Couleur *kr; switch ( lum ) { case 0 : kd = new Couleur(1.0,0.2,0.2); kr = new Couleur(0.0,0.8,0.8); break; case 1 : kd = new Couleur(1.0,0.2,0.2); 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; } Position3D *pos = new Position3D(4.2,0.3,0.5); Couleur *jaunatre = new Couleur(1.0,1.0,1.0); LumierePonctuelle *lp = new LumierePonctuelle(pos,10.0,jaunatre); Position3D *obs = new Position3D(0.0,0.0,20.0); Energie *e1 = new Energie(); Energie *e2 = new Energie(); Energie *e3 = new Energie(); { Energie *ed1 = new Energie(); ed1->calculDiffusion(p1,fct,kd,lp); Energie *er1 = new Energie(); er1->calculReflexionSpeculaire(p1,fct,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,fct,kd,lp); Energie *er2 = new Energie(); er2->calculReflexionSpeculaire(p2,fct,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,fct,kd,lp); Energie *er3 = new Energie(); er3->calculReflexionSpeculaire(p3,fct,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(obs); delete(pos); delete(jaunatre); delete(lp); delete(kd); delete(kr); delete(fct); } void facetteSimple(void) { Position3D *p1 = new Position3D(3.0,-1.0,0.0); Position3D *p2 = new Position3D(-1.0,3.0,1.0); Position3D *p3 = new Position3D(-3.0,-3.0,-1.0); p1->transforme(rt); p2->transforme(rt); p3->transforme(rt); facette(p1,p2,p3); delete(p3); delete(p2); delete(p1); } void subdivisionRecursive(Position3D *p1,Position3D *p2,Position3D *p3,int n) { if ( n == 0 ) facette(p1,p2,p3); else { Position3D *p12 = new Position3D((p1->c[0]+p2->c[0])/2.0, (p1->c[1]+p2->c[1])/2.0, (p1->c[2]+p2->c[2])/2.0); Position3D *p23 = new Position3D((p3->c[0]+p2->c[0])/2.0, (p3->c[1]+p2->c[1])/2.0, (p3->c[2]+p2->c[2])/2.0); Position3D *p31 = new Position3D((p3->c[0]+p1->c[0])/2.0, (p3->c[1]+p1->c[1])/2.0, (p3->c[2]+p1->c[2])/2.0); subdivisionRecursive(p1,p12,p31,n-1); subdivisionRecursive(p2,p23,p12,n-1); subdivisionRecursive(p3,p31,p23,n-1); subdivisionRecursive(p23,p31,p12,n-1); delete(p12); delete(p23); delete(p31); } } void facetteSubdivisee(void) { Position3D *p1 = new Position3D(3.0,-1.0,0.0); Position3D *p2 = new Position3D(-1.0,3.0,1.0); Position3D *p3 = new Position3D(-3.0,-3.0,-1.0); p1->transforme(rt); p2->transforme(rt); p3->transforme(rt); subdivisionRecursive(p1,p2,p3,n); delete(p1); delete(p2); delete(p3); } void scene() { Rotation *rtx = new Rotation(35.0*cos(rx),1.0,0.0,0.0); Rotation *rty = new Rotation(35.0*cos(ry),0.0,1.0,0.0); Rotation *rtz = new Rotation(rz,0.0,0.0,1.0); rt->produit(rtx,rty); rt->produit(rt,rtz); glPushMatrix(); switch ( obj ) { case 0 : facetteSimple(); break; case 1 : facetteSubdivisee(); break; } glPopMatrix(); delete(rtx); delete(rty); delete(rtz); } /* 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 == 0 ) n = 1; glutPostRedisplay(); break; case 'f' : { static int face = 1; face = !face; glPolygonMode(GL_FRONT_AND_BACK,( face ) ? GL_FILL : GL_LINE); } glutPostRedisplay(); break; case 0x20 : obj = (obj+1)%2; glutPostRedisplay(); break; case 'l' : 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 facette illuminee"); init(); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutReshapeFunc(reshape); glutIdleFunc(idle); glutDisplayFunc(display); glutMainLoop(); return(0); }