/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2005 */ /* Calcul de la quantite de lumiere diffusee */ /* par une surface eclairee */ /* par une lumiere direcionnelle */ /* ou une lumiere ponctuelle */ #include #include #include #include #include #include #include "Position.h" #include "Direction.h" #include "Triangle.h" #include "Sphere.h" #include "LumiereDirectionnelle.h" #include "LumierePonctuelle.h" #include "ModuleCouleurs.h" #include "ModuleFleche.h" #include "ModuleFont.h" #include "ModuleMatriceVecteur.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #ifndef M_PI #define M_PI 3.14159F #endif static int f1; static int f2; static int fv; static Position *fp1 = new Position(-1.5F,-1.3F, 0.8F); static Position *fp2 = new Position( 2.1F,-1.5F, 1.3F); static Position *fp3 = new Position( 1.5F, 1.5F, -0.2F); static Triangle *f = new Triangle(fp1,fp2,fp3); static Sphere *s = new Sphere(0.0F,0.0F,0.0F,1.0F); static Position *ldp = new Position(-1.0F,1.0F,0.0F); static Couleur *blanc = new Couleur(1.0F,1.0F,1.0F); static Couleur *brun = new Couleur(0.9F,0.7F,0.5F); static Position *pe1 = new Position( 0.5F,-0.5F, 0.7F); static Position *pe2 = new Position(-1.1F,-0.9F, 1.2F); static int npe = 0; static Position *pe = pe1; static Position *tpe[2] = { pe1,pe2 }; static Direction *ldd1 = new Direction(0.0F,-0.6F ,-0.8F); static Direction *ldd2 = new Direction(0.8F,-0.332F,-0.5F); static LumiereDirectionnelle *ld1 = new LumiereDirectionnelle(true,blanc,1.0F,ldd1); static LumiereDirectionnelle *ld2 = new LumiereDirectionnelle(true,brun,1.0F,ldd1); static LumiereDirectionnelle *ld3 = new LumiereDirectionnelle(true,blanc,1.0F,ldd2); static LumiereDirectionnelle *ld4 = new LumiereDirectionnelle(true,brun,1.0F,ldd2); static int nld = 0; static LumiereDirectionnelle *ld = ld1; static LumiereDirectionnelle *tld[4] = { ld1,ld2,ld3,ld4 }; static Position *lpp1 = new Position( 1.0F, 1.0F,1.0F); static Position *lpp2 = new Position(-1.0F,-0.5F,1.5F); static LumierePonctuelle *lp1 = new LumierePonctuelle(true,blanc,1.0F,lpp1); static LumierePonctuelle *lp2 = new LumierePonctuelle(true,brun,1.0F,lpp1); static LumierePonctuelle *lp3 = new LumierePonctuelle(true,blanc,1.0F,lpp2); static LumierePonctuelle *lp4 = new LumierePonctuelle(true,brun,1.0F,lpp2); static int nlp = 0; static LumierePonctuelle *lp = lp1; static LumierePonctuelle *tlp[4] = { lp1,lp2,lp3,lp4 }; static Materiel *m = new Materiel(blanc); static int tt = 0; static int tl = 0; static int to = 0; static int te = 0; static int n = 36; void sphere(Sphere *s, LumierePonctuelle *lp, Materiel *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); glBegin(GL_QUAD_STRIP); for ( int j = 0; j <= n; j++ ) { float a = j*2*M_PI/n; Direction *n1 = new Direction(cs1*cos(a),cs1*sin(a),sn1); float x1 = s->centre->x+s->rayon*cs1*cos(a); float y1 = s->centre->y+s->rayon*cs1*sin(a); float z1 = s->centre->z+s->rayon*sn1; Position *p1 = new Position(x1,y1,z1); Energie *e1 = lp->energieDiffusee(p1,n1,m); delete(p1); Direction *n2 = new Direction(cs2*cos(a),cs2*sin(a),sn2); float x2 = s->centre->x+s->rayon*cs2*cos(a); float y2 = s->centre->y+s->rayon*cs2*sin(a); float z2 = s->centre->z+s->rayon*sn2; Position *p2 = new Position(x2,y2,z2); Energie *e2 = lp->energieDiffusee(p2,n2,m); delete(p2); glColor3f(e1->r,e1->v,e1->b); glVertex3f(x1,y1,z1); glColor3f(e2->r,e2->v,e2->b); glVertex3f(x2,y2,z2); delete(n1); delete(n2); } glEnd(); } } void sphere(Sphere *s, LumiereDirectionnelle *ld, Materiel *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); glBegin(GL_QUAD_STRIP); for ( int j = 0; j <= n; j++ ) { float a = j*2*M_PI/n; Direction *n1 = new Direction(cs1*cos(a),cs1*sin(a),sn1); float x1 = s->centre->x+s->rayon*cs1*cos(a); float y1 = s->centre->y+s->rayon*cs1*sin(a); float z1 = s->centre->z+s->rayon*sn1; Position *p1 = new Position(x1,y1,z1); Energie *e1 = ld->energieDiffusee(p1,n1,m); delete(p1); Direction *n2 = new Direction(cs2*cos(a),cs2*sin(a),sn2); float x2 = s->centre->x+s->rayon*cs2*cos(a); float y2 = s->centre->y+s->rayon*cs2*sin(a); float z2 = s->centre->z+s->rayon*sn2; Position *p2 = new Position(x2,y2,z2); Energie *e2 = ld->energieDiffusee(p2,n2,m); delete(p2); glColor3f(e1->r,e1->v,e1->b); glVertex3f(x1,y1,z1); glColor3f(e2->r,e2->v,e2->b); glVertex3f(x2,y2,z2); delete(n1); delete(n2); } glEnd(); } } void dessineTriangle(Triangle *f, LumiereDirectionnelle *ld, Materiel *m){ Direction *n = f->normale(); glNormal3f(n->x,n->y,n->z); Energie *e1 = ld->energieDiffusee(f->p1,n,m); Energie *e2 = ld->energieDiffusee(f->p2,n,m); Energie *e3 = ld->energieDiffusee(f->p3,n,m); glBegin(GL_TRIANGLES); glColor3fv((float *) e1); glVertex3fv((float *) f->p1); glColor3fv((float *) e2); glVertex3fv((float *) f->p2); glColor3fv((float *) e3); glVertex3fv((float *) f->p3); glEnd(); delete(e3); delete(e2); delete(e1); delete(n); } void dessineTriangleRecursif(Triangle *f, LumiereDirectionnelle *ld, Materiel *m, int niveau){ if ( niveau == 0 ) { dessineTriangle(f,ld,m); } else { Position *p12 = new Position((f->p1->x+f->p2->x)/2.0F, (f->p1->y+f->p2->y)/2.0F, (f->p1->z+f->p2->z)/2.0F); Position *p13 = new Position((f->p1->x+f->p3->x)/2.0F, (f->p1->y+f->p3->y)/2.0F, (f->p1->z+f->p3->z)/2.0F); Position *p23 = new Position((f->p3->x+f->p2->x)/2.0F, (f->p3->y+f->p2->y)/2.0F, (f->p3->z+f->p2->z)/2.0F); Triangle *f1 = new Triangle(f->p1,p12,p13); Triangle *f2 = new Triangle(f->p2,p23,p12); Triangle *f3 = new Triangle(f->p3,p13,p23); Triangle *fc = new Triangle(p12,p23,p13); dessineTriangleRecursif(f1,ld,m,niveau-1); dessineTriangleRecursif(f2,ld,m,niveau-1); dessineTriangleRecursif(f3,ld,m,niveau-1); dessineTriangleRecursif(fc,ld,m,niveau-1); delete(p12); delete(p13); delete(p23); delete(f1); delete(f2); delete(f3); delete(fc); } } void triangle(Triangle *f, LumiereDirectionnelle *ld, Materiel *m){ if ( tt ) dessineTriangleRecursif(f,ld,m,5); else dessineTriangle(f,ld,m); } void dessineTriangle(Triangle *f, LumierePonctuelle *lp, Materiel *m){ Direction *n = f->normale(); glNormal3f(n->x,n->y,n->z); Energie *e1 = lp->energieDiffusee(f->p1,n,m); Energie *e2 = lp->energieDiffusee(f->p2,n,m); Energie *e3 = lp->energieDiffusee(f->p3,n,m); glBegin(GL_TRIANGLES); glColor3fv((float *) e1); glVertex3fv((float *) f->p1); glColor3fv((float *) e2); glVertex3fv((float *) f->p2); glColor3fv((float *) e3); glVertex3fv((float *) f->p3); glEnd(); delete(e3); delete(e2); delete(e1); delete(n); } void dessineTriangleRecursif(Triangle *f, LumierePonctuelle *lp, Materiel *m, int niveau){ if ( niveau == 0 ) { dessineTriangle(f,lp,m); } else { Position *p12 = new Position((f->p1->x+f->p2->x)/2.0F, (f->p1->y+f->p2->y)/2.0F, (f->p1->z+f->p2->z)/2.0F); Position *p13 = new Position((f->p1->x+f->p3->x)/2.0F, (f->p1->y+f->p3->y)/2.0F, (f->p1->z+f->p3->z)/2.0F); Position *p23 = new Position((f->p3->x+f->p2->x)/2.0F, (f->p3->y+f->p2->y)/2.0F, (f->p3->z+f->p2->z)/2.0F); Triangle *f1 = new Triangle(f->p1,p12,p13); Triangle *f2 = new Triangle(f->p2,p23,p12); Triangle *f3 = new Triangle(f->p3,p13,p23); Triangle *fc = new Triangle(p12,p23,p13); dessineTriangleRecursif(f1,lp,m,niveau-1); dessineTriangleRecursif(f2,lp,m,niveau-1); dessineTriangleRecursif(f3,lp,m,niveau-1); dessineTriangleRecursif(fc,lp,m,niveau-1); delete(p12); delete(p13); delete(p23); delete(f1); delete(f2); delete(f3); delete(fc); } } void triangle(Triangle *f, LumierePonctuelle *lp, Materiel *m){ if ( tt ) dessineTriangleRecursif(f,lp,m,5); else dessineTriangle(f,lp,m); } void dessineTriangleSimple(Triangle *f){ glBegin(GL_TRIANGLES); glVertex3fv((float *) f->p1); glVertex3fv((float *) f->p2); glVertex3fv((float *) f->p3); glEnd(); } void dessineTriangleSimpleRecursif(Triangle *f,int niveau){ if ( niveau == 0 ) { dessineTriangleSimple(f); } else { Position *p12 = new Position((f->p1->x+f->p2->x)/2.0F, (f->p1->y+f->p2->y)/2.0F, (f->p1->z+f->p2->z)/2.0F); Position *p13 = new Position((f->p1->x+f->p3->x)/2.0F, (f->p1->y+f->p3->y)/2.0F, (f->p1->z+f->p3->z)/2.0F); Position *p23 = new Position((f->p3->x+f->p2->x)/2.0F, (f->p3->y+f->p2->y)/2.0F, (f->p3->z+f->p2->z)/2.0F); Triangle *f1 = new Triangle(f->p1,p12,p13); Triangle *f2 = new Triangle(f->p2,p23,p12); Triangle *f3 = new Triangle(f->p3,p13,p23); Triangle *fc = new Triangle(p12,p23,p13); dessineTriangleSimpleRecursif(f1,niveau-1); dessineTriangleSimpleRecursif(f2,niveau-1); dessineTriangleSimpleRecursif(f3,niveau-1); dessineTriangleSimpleRecursif(fc,niveau-1); delete(p12); delete(p13); delete(p23); delete(f1); delete(f2); delete(f3); delete(fc); } } void triangleSimple(Triangle *f){ if ( tt ) dessineTriangleSimpleRecursif(f,5); else dessineTriangleSimple(f); } void dessineLumiereDirectionnelle(LumiereDirectionnelle *ld) { glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(float *) ld->c); glPushMatrix(); glTranslatef(ldp->x,ldp->y,ldp->z); flecheEnVolume(ld->d->x,ld->d->y,ld->d->z,0.1F,0.5F,0.025F); glPopMatrix(); } void dessineLumierePonctuelle(LumierePonctuelle *lp) { glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(float *) lp->c); lp->p->dessine(); } void lumieresInterface(void) { GLfloat light_Position0[] = { 1.0F,0.0F,1.0F,0.0F }; GLfloat light_Position1[] = { -1.0F,0.0F,1.0F,0.0F }; glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT0,GL_POSITION,light_Position0); glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT1,GL_POSITION,light_Position1); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); } void lumiereDirectionnelle(LumiereDirectionnelle *ld) { float d[] = { -ld->d->x, -ld->d->y, -ld->d->z, 0.0F }; float c[] = { ld->c->r*ld->e, ld->c->v*ld->e, ld->c->b*ld->e, 1.0F }; glLightfv(GL_LIGHT0,GL_DIFFUSE,c); glLightfv(GL_LIGHT0,GL_POSITION,d); glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.0F); glEnable(GL_LIGHT0); glDisable(GL_LIGHT1); } void lumierePonctuelle(LumierePonctuelle *lp) { float p[] = { lp->p->x, lp->p->y, lp->p->z, 1.0F }; float c[] = { lp->c->r*ld->e, lp->c->v*ld->e, lp->c->b*ld->e, 1.0F }; glLightfv(GL_LIGHT0,GL_DIFFUSE,c); glLightfv(GL_LIGHT0,GL_POSITION,p); glEnable(GL_LIGHT0); glDisable(GL_LIGHT1); } void myinit1(void) { glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT0,GL_SPECULAR,couleurNoir()); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glClearColor(0.75F,0.75F,0.75F,1.0F); } void display1(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glPushMatrix(); lumieresInterface(); glEnable(GL_LIGHTING); if ( tl ) dessineLumierePonctuelle(lp); else dessineLumiereDirectionnelle(ld); glDisable(GL_LIGHTING); if ( te ) if ( to ) if ( tl ) sphere(s,lp,m); else sphere(s,ld,m); else if ( tl ) triangle(f,lp,m); else triangle(f,ld,m); else { glEnable(GL_LIGHTING); pe->dessine(); glDisable(GL_LIGHTING); } glPopMatrix(); glPopMatrix(); glFlush(); glutSwapBuffers(); glutPostWindowRedisplay(fv); } void myinit2(void) { glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT0,GL_SPECULAR,couleurNoir()); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glClearColor(0.75F,0.75F,0.75F,1.0F); } void display2(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glPushMatrix(); if ( te ) { lumieresInterface(); if ( tl ) dessineLumierePonctuelle(lp); else dessineLumiereDirectionnelle(ld); if ( tl ) lumierePonctuelle(lp); else lumiereDirectionnelle(ld); Direction *n = f->normale(); glNormal3f(n->x,n->y,n->z); delete(n); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurBlanc()); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,couleurNoir()); if ( to ) s->dessine(); else triangleSimple(f); } glPopMatrix(); glPopMatrix(); glFlush(); glutSwapBuffers(); glutPostWindowRedisplay(fv); } void postRedisplays(void) { glutPostWindowRedisplay(f1); glutPostWindowRedisplay(f2); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) { postRedisplays(); } else switch ( key ) { case 'e' : case 'E' : te = !te; postRedisplays(); break; case ' ' : to = !to; postRedisplays(); break; case 0x0D : tl = !tl; postRedisplays(); break; case 't' : case 'T' : tt = !tt; postRedisplays(); break; case 's' : case 'S' : npe = (npe+1)%2; pe = tpe[npe]; postRedisplays(); break; case 'd' : case 'D' : nld = (nld+1)%4; ld = tld[nld]; postRedisplays(); break; case 'p' : case 'P' : nlp = (nlp+1)%4; lp = tlp[nlp]; postRedisplays(); break; } ; } void special(int key,int x,int y) { if ( specialManipulateur(key,x,y) ) { postRedisplays(); } } void reshapeV(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,w,-h,0,-1.0,1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void displayV() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glClearColor(0.0F,0.0F,0.0F,1.0F); glPushMatrix(); float pos = 1.0F; glColor4fv(couleurBlanc()); placeFontCursor(5.0F,-pos*20.0F,0.0F); if ( tl ) { simpleBitmapOutput(1,REGULAR8x13,"LUMIERE PONCTUELLE"); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); lp->p->print("POSITION : %7.3f %7.3f %7.3f"); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); simpleBitmapOutput(1,REGULAR8x13,"ENERGIE : %7.3f",lp->e); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); lp->c->print("COULEUR : %7.3f %7.3f %7.3f"); } else { simpleBitmapOutput(1,REGULAR8x13,"LUMIERE DIRECTIONNELLE"); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); ld->d->print("DIRECTION : %7.3f %7.3f %7.3f"); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); simpleBitmapOutput(1,REGULAR8x13,"ENERGIE : %7.3f",ld->e); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); ld->c->print("COULEUR : %7.3f %7.3f %7.3f"); } pos += 2.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); if ( te ) { if ( !to ) { Direction *n = f->normale(); f->p1->print("P1 : %7.3f %7.3f %7.3f"); pos += 1.0F; Energie *e1 = (tl) ? lp->energieDiffusee(f->p1,n,m) : ld->energieDiffusee(f->p1,n,m); placeFontCursor(5.0F,-pos*20.0F,0.0F); e1->print("ENERGIE P1 : %7.3f %7.3f %7.3f"); delete(e1); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); f->p2->print("P2 : %7.3f %7.3f %7.3f"); pos += 1.0F; Energie *e2 = (tl) ? lp->energieDiffusee(f->p2,n,m) : ld->energieDiffusee(f->p2,n,m); placeFontCursor(5.0F,-pos*20.0F,0.0F); e2->print("ENERGIE P2 : %7.3f %7.3f %7.3f"); delete(e2); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F); f->p3->print("P3 : %7.3f %7.3f %7.3f"); pos += 1.0F; Energie *e3 = (tl) ? lp->energieDiffusee(f->p3,n,m) : ld->energieDiffusee(f->p3,n,m); placeFontCursor(5.0F,-pos*20.0F,0.0F); e3->print("ENERGIE P3 : %7.3f %7.3f %7.3f"); delete(e1); delete(n); } } else { pe->print("P : %7.3f %7.3f %7.3f"); pos += 1.0F; if ( tl ) { float dist = pe->distance(lp->p); placeFontCursor(5.0F,-pos*20.0F,0.0F); simpleBitmapOutput(1,REGULAR8x13,"DISTANCE : %7.3f",dist); pos += 1.0F; } Energie *e = (tl) ? lp->intensiteRecue(pe) : ld->intensiteRecue(pe); placeFontCursor(5.0F,-pos*20.0F,0.0F); e->print("IP : %7.3f %7.3f %7.3f"); delete(e); } glPopMatrix(); glutSwapBuffers(); } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); { glutInitWindowPosition(50,50); glutInitWindowSize(240,240); f1 = glutCreateWindow("Lumiere diffusée"); myinit1(); creationMenuBasique(); setParametresOrthoBasique(-2.5,2.5,-2.5,2.5,-50.0,50.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(special); glutDisplayFunc(display1); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); } { glutInitWindowPosition(300,50); glutInitWindowSize(240,240); f2 = glutCreateWindow("Equivalent OpenGL"); myinit2(); creationMenuBasique(); setParametresOrthoBasique(-2.5,2.5,-2.5,2.5,-50.0,50.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(special); glutDisplayFunc(display2); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); } { glutInitWindowSize(380,230); glutInitWindowPosition(60,320); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); fv = glutCreateWindow("Valeurs"); creationMenuBasique(); glutDisplayFunc(displayV); glutReshapeFunc(reshapeV); glutKeyboardFunc(key); glutSpecialFunc(special); } glutMainLoop(); return(0); }