/* Implantation mathematique */ /* d'operations utilisees */ /* en lancer de rayons */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2011 */ #include #include #include #include #include #include #include "ModuleAffichageChaineDeCarateres.h" #include "Position3D.h" #include "Direction3D.h" #include "Sphere.h" #include "Rayon.h" /* Variables et constantes globales */ /* pour les angles et les couleurs utilises */ static int f1; static int aff = 1; static float rx = -20.0F; static float ry = 0.0F; static float rz = 0.0F; static float px = -0.1F; static float py = 0.1F; static float pz = 0.2F; static float rp = 1.0F; static void postRedisplay(void) { glutPostWindowRedisplay(f1); } /* Fonction executee lors d'un changement */ /* de la taille de la fenetre (1) */ void reshape(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0F,1.0,(float) -h/w,(float) h/w,-50.0,50.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* Fonction executee lors d'un rafraichissement */ /* de la fenetre de dessin (1) */ static void drawDirection(Direction3D *d) { glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3d(d->c[0],d->c[1],d->c[2]); glEnd(); } void displayReflexionEtTransmission() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(rz,0.0F,0.0F,1.0F); glRotatef(ry,0.0F,1.0F,0.0F); glRotatef(rx,1.0F,0.0F,0.0F); glLineWidth(2.0F); glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); Direction3D *n = new Direction3D(0.3,0.6,sqrt(1.0-0.6*0.6-0.3*0.3)); Direction3D *i = new Direction3D(-0.3,0.7,sqrt(1.0-0.7*0.7-0.3*0.3)); Direction3D *a1 = new Direction3D(); a1->produitVectoriel(n,i); Direction3D *a2 = new Direction3D(); a2->produitVectoriel(n,a1); Direction3D *r = new Direction3D(); bool rr; if ( rr = r->reflechi(i,n) ) { glColor4f(1.0F,0.0F,0.0F,1.0F); drawDirection(r); } Direction3D *t = new Direction3D(); bool rt; if ( rt = t->transmis(i,n,rp) ) { glColor4f(0.0F,1.0F,0.0F,1.0F); drawDirection(t); } glColor4f(1.0F,1.0F,0.0,1.0F); drawDirection(i); glColor4f(1.0F,0.0F,1.0F,1.0F); drawDirection(n); glColor4f(0.5F,0.5F,0.5F,0.5F); glBegin(GL_QUADS); glVertex3f(a1->c[0]*2.0F,a1->c[1]*2.0F,a1->c[2]*2.0F); glVertex3f(a2->c[0]*2.0F,a2->c[1]*2.0F,a2->c[2]*2.0F); glVertex3f(-a1->c[0]*2.0F,-a1->c[1]*2.0F,-a1->c[2]*2.0F); glVertex3f(-a2->c[0]*2.0F,-a2->c[1]*2.0F,-a2->c[2]*2.0F); glEnd(); drawString(10,20,"I : %6.3lf %6.3lf %6.3lf",i->c[0],i->c[1],i->c[2]); drawString(10,40,"N : %6.3lf %6.3lf %6.3lf",n->c[0],n->c[1],n->c[2]); drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-50,"Rapport ni/nt : %7.4lf",rp); if ( rr ) drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-30, "R : %6.3lf %6.3lf %6.3lf",r->c[0],r->c[1],r->c[2]); else drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-30,"R : inexistant"); if ( rt ) drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-10, "T : %6.3lf %6.3lf %6.3lf",t->c[0],t->c[1],t->c[2]); else drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-10,"T : inexistant"); delete(t); delete(r); delete(i); delete(n); delete(a1); delete(a2); glPopMatrix(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur OpenGL: %d\n",error); } void drawPoint(double ix,double iy,double iz) { glDisable(GL_DEPTH_TEST); glPushMatrix(); glPointSize(5.0F); glColor4f(0.0F,1.0F,0.0,1.0F); glBegin(GL_POINTS); glVertex3d(ix,iy,iz); glEnd(); glPopMatrix(); glEnable(GL_DEPTH_TEST); } void drawSphere(Sphere *s) { glPushMatrix(); glTranslated(s->centre->c[0],s->centre->c[1],s->centre->c[2]); glutSolidSphere(s->rayon,72,72); glPopMatrix(); } void drawRayon(Rayon *r) { glLineWidth(2.0F); glPointSize(5.0F); glColor4f(1.0F,0.0F,0.0,1.0F); glPushMatrix(); glTranslated(r->pos->c[0],r->pos->c[1],r->pos->c[2]); glBegin(GL_POINTS); glVertex3d(0.0,0.0,0.0); glEnd(); glBegin(GL_LINES); glVertex3d(0.0,0.0,0.0); glVertex3dv((double *) r->dir); glEnd(); glPopMatrix(); } void displayIntersection() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); const GLfloat light0_position[] = { 1.0,1.0,1.0,0.0 }; const GLfloat light1_position[] = { -1.0,1.0,1.0,0.0 }; glLightfv(GL_LIGHT0,GL_POSITION,light0_position); glLightfv(GL_LIGHT1,GL_POSITION,light1_position); glRotatef(rz,0.0F,0.0F,1.0F); glRotatef(ry,0.0F,1.0F,0.0F); glRotatef(rx,1.0F,0.0F,0.0F); Rayon *r = new Rayon(px,py,pz,0.5,0.6,-sqrt(1.0-0.25-0.36)); drawRayon(r); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); Sphere *s = new Sphere(0.2,0.1,-0.3,0.5); drawSphere(s); glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); drawString(10,20,"Rp = %7.4lf %7.4lf %7.4lf", r->pos->c[0],r->pos->c[1],r->pos->c[2]); drawString(10,40,"Rd = %7.4lf %7.4lf %7.4lf", r->dir->c[0],r->dir->c[1],r->dir->c[2]); drawString(10,65,"Sp = %7.4lf %7.4lf %7.4lf", s->centre->c[0],s->centre->c[1],s->centre->c[2]); drawString(10,85,"Sr = %7.4lf",s->rayon); if ( s->intersection(r) ) { double t; s->intersection(r,&t); double ix = r->pos->c[0] + t*r->dir->c[0]; double iy = r->pos->c[1] + t*r->dir->c[1]; double iz = r->pos->c[2] + t*r->dir->c[2]; drawPoint(ix,iy,iz); drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-50,"Intersection"); drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-30,"t = %lf",t); drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-10, "pos = %7.4lf %7.4lf %7.4lf",ix,iy,iz); } else { drawString(10,glutGet(GLUT_WINDOW_HEIGHT)-10,"Pas d'intersection"); } delete(r); delete(s); glPopMatrix(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur OpenGL: %d\n",error); } void myinit(void) { const GLfloat gris[] = { 0.8F,0.8F,0.8F,1.0F }; const GLfloat blanc[] = { 1.0F,1.0F,1.0F,0.5F }; const GLfloat mat_shininess[] = { 50.0 }; glMaterialfv(GL_FRONT,GL_DIFFUSE,blanc); glMaterialfv(GL_FRONT,GL_SPECULAR,blanc); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glLightfv(GL_LIGHT0,GL_DIFFUSE,gris); glLightfv(GL_LIGHT1,GL_DIFFUSE,gris); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_AUTO_NORMAL); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); } /* Fonction executee lors de la frappe */ /* d'une touche special du clavier: */ /* - touches de curseur */ /* - touches de fonction */ /* - ... */ void special(int code,int x,int y) { switch ( code ) { case GLUT_KEY_UP : rx += 1.0F; postRedisplay(); break; case GLUT_KEY_DOWN : rx -= 1.0F; postRedisplay(); break; case GLUT_KEY_RIGHT : ry += 1.0F; postRedisplay(); break; case GLUT_KEY_LEFT : ry -= 1.0F; postRedisplay(); break; case GLUT_KEY_PAGE_UP : rz += 1.0F; postRedisplay(); break; case GLUT_KEY_PAGE_DOWN : rz -= 1.0F; postRedisplay(); break; } } /* Fonction executee lorsqu'aucun evenement */ /* n'est en file d'attente */ void idle(void) { rx += 0.03355F; ry += 0.06117F; rz += 0.04174F; postRedisplay(); } /* 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 : rp *= 0.99F; postRedisplay(); break; case 45 : rp /= 0.99F; postRedisplay(); break; case 'x' : px -= 0.02F; postRedisplay(); break; case 'X' : px += 0.02F; postRedisplay(); break; case 'y' : py -= 0.02F; postRedisplay(); break; case 'Y' : py += 0.02F; postRedisplay(); break; case 'z' : pz -= 0.02F; postRedisplay(); break; case 'Z' : px += 0.02F; postRedisplay(); break; case 'r' : rx = 0.0F; ry = 0.0F; rz = 0.0F; postRedisplay(); break; case 0x20 : aff = (aff+1)%2; if ( aff ) glutDisplayFunc(displayReflexionEtTransmission); else glutDisplayFunc(displayIntersection); postRedisplay(); break; case 0x0D : { static int anim = 0; anim = !anim; glutIdleFunc(( anim ) ? idle : NULL); } break; case 0x1B : exit(0); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitWindowSize(310,380); glutInitWindowPosition(50,50); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); f1 = glutCreateWindow("Mathematiques pour le ray tracing"); myinit(); glutDisplayFunc(displayReflexionEtTransmission); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutMainLoop(); return(0); }