/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Fevrier 2002 */ /* Evaluation de la luniere diffusee */ /* sur une surface eclairee par une */ /* lumiere directionnelle */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleFleche.h" #include "ModuleFont.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #ifndef M_PI #define M_PI 3.14159 #endif typedef struct Position { float x ; float y ; float z ; } Position ; typedef struct Direction { float dx ; float dy ; float dz ; } Direction ; typedef struct Couleur { float r ; float v ; float b ; float a ; } Couleur ; typedef struct Energie { float er ; float ev ; float eb ; } Energie ; typedef struct LumiereDirectionnelle { Direction d; Couleur c; float e; } LumiereDirectionnelle ; typedef struct Materiau { Couleur kd; } Materiau ; static int f1; static int f2; static LumiereDirectionnelle ld = { { 0.4F,-0.6F,0.70710678F }, { 1.0F,1.0F,0.0F,1.0F }, 1.0F } ; static Materiau m = { { 1.0F,0.0F,1.0F,1.0F } } ; static Direction n = { 0.0F,0.0F,1.0F }; static Position p = { 0.0F,0.0F,0.0F }; static Energie e = { 0.0F,0.0F,0.0F }; static Couleur c = { 0.0F,0.0F,0.0F,0.8F }; static int carac = 0; static int cf = 0; static int obj = 1; float produitScalaire(Direction *v1,Direction *v2) { return(v1->dx*v2->dx+v1->dy*v2->dy+v1->dz*v2->dz); } void lumiereDiffusee(Position *p,Direction *n,Materiau *m,LumiereDirectionnelle *ld,Energie *e) { float scal = produitScalaire(&ld->d,n); if ( scal < 0.0F ) scal = 0.0F; e->er = ld->e*ld->c.r*m->kd.r*scal; e->ev = ld->e*ld->c.v*m->kd.v*scal; e->eb = ld->e*ld->c.b*m->kd.b*scal; } void couleurEnergie(Energie *e,Couleur *c) { c->r = e->er; if ( c->r > 1.0F ) c->r = 1.0F; c->v = e->ev; if ( c->v > 1.0F ) c->v = 1.0F; c->b = e->eb; if ( c->b > 1.0F ) c->b = 1.0F; } void myinit(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_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT0,GL_SPECULAR,couleurNoir()); glLightfv(GL_LIGHT0,GL_POSITION,light_position0); glLightfv(GL_LIGHT1,GL_POSITION,light_position1); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); } float longueur(Direction *v) { return(sqrt(v->dx*v->dx+v->dy*v->dy+v->dz*v->dz)); } void normalize(Direction *v) { float d = longueur(v); if ( d != 0 ) { v->dx /= d; v->dy /= d; v->dz /= d; } } void produitVectoriel(Direction *v1,Direction *v2,Direction *v) { v->dx = v1->dy*v2->dz-v2->dy*v1->dz; v->dy = v1->dz*v2->dx-v2->dz*v1->dx; v->dz = v1->dx*v2->dy-v2->dx*v1->dy; } void dessineFacetteOrthogonale(Position *p,Direction *n) { Direction v1 = { -n->dy,n->dx,0.0F }; if ( ( v1.dx == 0.0F ) && ( v1.dy == 0.0F ) ) v1.dx = n->dz; normalize(&v1); Direction v2; produitVectoriel(n,&v1,&v2); glBegin(GL_QUADS); glVertex3f(p->x+v1.dx+v2.dx,p->y+v1.dy+v2.dy,p->z+v1.dz+v2.dz); glVertex3f(p->x-v1.dx+v2.dx,p->y-v1.dy+v2.dy,p->z-v1.dz+v2.dz); glVertex3f(p->x-v1.dx-v2.dx,p->y-v1.dy-v2.dy,p->z-v1.dz-v2.dz); glVertex3f(p->x+v1.dx-v2.dx,p->y+v1.dy-v2.dy,p->z+v1.dz-v2.dz); glEnd(); } void displayFacette(void) { lumiereDiffusee(&p,&n,&m,&ld,&e); couleurEnergie(&e,&c); if ( cf ) glClearColor(0.5F,0.5F,0.5F,1.0F); else glClearColor(0.0F,0.0F,0.0F,0.0F); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix() ; manipulateurSouris(); manipulateurClavier(); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,(float *) &ld.c); glPushMatrix(); glTranslatef(0.0F,0.0F,0.0F); flecheEnVolume(ld.d.dx,ld.d.dy,ld.d.dz,0.035F,0.15F,0.007F); glPopMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,(float *) &m.kd); glPushMatrix(); glTranslatef(0.0F,0.0F,0.0F); flecheEnVolume(n.dx,n.dy,n.dz,0.035F,0.15F,0.007F); glPopMatrix(); glDisable(GL_LIGHTING); glColor4fv((float *) &c); glPushMatrix(); glTranslatef(p.x,p.y,p.z); dessineFacetteOrthogonale(&p,&n); glPopMatrix(); glPopMatrix() ; glFlush(); glutSwapBuffers() ; glutPostWindowRedisplay(f2); } void solidSphere(float r,float nn,float nm) { for ( int i = 0 ; i < nn ; i++ ) { float a1 = -M_PI/2.0F + i*M_PI/nn ; float a2 = a1 + M_PI/nn ; 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 <= nm ; j++ ) { float a = j*2*M_PI/nm; float sn = sin(a); float cs = cos(a); float x1 = cs1*cs; float y1 = cs1*sn; float x2 = cs2*cs; float y2 = cs2*sn; Position p1 = { r*x1,r*y1,r*sn1 }; Direction n1 = { x1,y1,sn1 }; lumiereDiffusee(&p1,&n1,&m,&ld,&e); couleurEnergie(&e,&c); glColor4fv((float *) &c); glVertex3fv((float *) &p1); Position p2 = { r*x2,r*y2,r*sn2 }; Direction n2 = { x2,y2,sn2 }; lumiereDiffusee(&p2,&n2,&m,&ld,&e); couleurEnergie(&e,&c); glColor4fv((float *) &c); glVertex3fv((float *) &p2); } glEnd(); } } void displaySphere(void) { if ( cf ) glClearColor(0.5F,0.5F,0.5F,1.0F); else glClearColor(0.0F,0.0F,0.0F,1.0F); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix() ; manipulateurSouris(); manipulateurClavier(); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,(float *) &ld.c); glPushMatrix(); glTranslatef(0.0F,0.0F,0.0F); flecheEnVolume(ld.d.dx,ld.d.dy,ld.d.dz,0.035F,0.15F,0.007F); glPopMatrix(); glDisable(GL_LIGHTING); solidSphere(0.75,72,36); glPopMatrix() ; glFlush(); glutSwapBuffers() ; glutPostWindowRedisplay(f2); } void postRedisplay(void) { glutPostWindowRedisplay(f1); glutPostWindowRedisplay(f2); } void incrementComposante(float *c) { *c += 0.01F; if ( *c > 1.0F ) *c = 1.0F; } void decrementComposante(float *c) { *c -= 0.01F; if ( *c < 0.0F ) *c = 0.0F; } void special(int key,int x,int y) { if ( specialManipulateur(key,x,y) ) { glutPostWindowRedisplay(f1); } } void reshape2(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 displayFacette2() { if ( cf ) glClearColor(0.5F,0.5F,0.5F,1.0F); else glClearColor(0.0F,0.0F,0.0F,1.0F); glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); float pos = 1.0F; glColor4fv(couleurBlanc()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"Direction lumiere : %6.3f %6.3f %6.3f",ld.d.dx,ld.d.dy,ld.d.dz) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv((float *) &ld.c); simpleBitmapOutput(1,REGULAR8x13,"Couleur lumiere : %6.3f %6.3f %6.3f",ld.c.r,ld.c.v,ld.c.b) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv(couleurBlanc()); simpleBitmapOutput(1,REGULAR8x13,"Intensite lumiere : %6.3f",ld.e) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv((float *) &m.kd); simpleBitmapOutput(1,REGULAR8x13,"Diffusion materiau : %6.3f %6.3f %6.3f",m.kd.r,m.kd.v,m.kd.b) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv(couleurBlanc()); simpleBitmapOutput(1,REGULAR8x13,"Normale : %6.3f %6.3f %6.3f",n.dx,n.dy,n.dz) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"Position : %6.3f %6.3f %6.3f",p.x,p.y,p.z) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"Energie diffusee : %6.3f %6.3f %6.3f",e.er,e.ev,e.eb) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv((float *) &e); simpleBitmapOutput(1,REGULAR8x13,"Couleur obtenue : %6.3f %6.3f %6.3f",c.r,c.v,c.b) ; glPopMatrix(); glutSwapBuffers(); } void displaySphere2() { if ( cf ) glClearColor(0.5F,0.5F,0.5F,1.0F); else glClearColor(0.0F,0.0F,0.0F,1.0F); glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); float pos = 1.0F; glColor4fv(couleurBlanc()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"Direction lumiere : %6.3f %6.3f %6.3f",ld.d.dx,ld.d.dy,ld.d.dz) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv((float *) &ld.c); simpleBitmapOutput(1,REGULAR8x13,"Couleur lumiere : %6.3f %6.3f %6.3f",ld.c.r,ld.c.v,ld.c.b) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv(couleurBlanc()); simpleBitmapOutput(1,REGULAR8x13,"Intensite lumiere : %6.3f",ld.e) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv((float *) &m.kd); simpleBitmapOutput(1,REGULAR8x13,"Diffusion materiau : %6.3f %6.3f %6.3f",m.kd.r,m.kd.v,m.kd.b) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; glColor4fv(couleurBlanc()); simpleBitmapOutput(1,REGULAR8x13,"Normale : %6.3f %6.3f %6.3f",n.dx,n.dy,n.dz) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"Position : %6.3f %6.3f %6.3f",p.x,p.y,p.z) ; glPopMatrix(); glutSwapBuffers(); } void key2(unsigned char key,int x,int y) { switch ( key ) { case 0x0D : obj = !obj; glutSetWindow(f1); glutDisplayFunc((obj) ? displayFacette : displaySphere); glutSetWindow(f2); glutDisplayFunc((obj) ? displayFacette2 : displaySphere2); postRedisplay(); break; case 'c' : case 'C' : cf = !cf ; postRedisplay(); break; case '1' : ld.d.dx -= 0.01; normalize(&ld.d); postRedisplay(); break; case '3' : ld.d.dx += 0.01; normalize(&ld.d); postRedisplay(); break; case '4' : ld.d.dy -= 0.01; normalize(&ld.d); postRedisplay(); break; case '6' : ld.d.dy += 0.01; normalize(&ld.d); postRedisplay(); break; case '7' : ld.d.dz -= 0.01; normalize(&ld.d); postRedisplay(); break; case '9' : ld.d.dz += 0.01; normalize(&ld.d); postRedisplay(); break; case ' ' : carac = !carac; break; case 'r' : incrementComposante((carac) ? &m.kd.r : &ld.c.r); postRedisplay(); break; case 'R' : decrementComposante((carac) ? &m.kd.r : &ld.c.r); postRedisplay(); break; case 'v' : incrementComposante((carac) ? &m.kd.v : &ld.c.v); postRedisplay(); break; case 'V' : decrementComposante((carac) ? &m.kd.v : &ld.c.v); postRedisplay(); break; case 'b' : incrementComposante((carac) ? &m.kd.b : &ld.c.b); postRedisplay(); break; case 'B' : decrementComposante((carac) ? &m.kd.b : &ld.c.b); postRedisplay(); break; case 43 : ld.e *= 1.1F; postRedisplay(); break; case 45 : ld.e /= 1.1F; postRedisplay(); break; case 0x1B : exit(0); break; } } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostWindowRedisplay(f1); else key2(key,x,y); } int main(int argc,char **argv) { lumiereDiffusee(&p,&n,&m,&ld,&e); couleurEnergie(&e,&c); glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowPosition(50,50); glutInitWindowSize(420,240); f1 = glutCreateWindow("Diffusion vis a vis d'une lumiere directionnelle"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-1.0,1.0,-1.0,1.0,-50.0,50.0); setManipulateurDistance(1.0F); setManipulateurClavierAngle(-50.0F,0.0F,-20.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutDisplayFunc(displayFacette); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutInitWindowSize(430,170); glutInitWindowPosition(60,340); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); f2 = glutCreateWindow("Valeurs"); creationMenuBasique(); glutDisplayFunc(displayFacette2); glutReshapeFunc(reshape2); glutKeyboardFunc(key); glutSpecialFunc(special); glutMainLoop(); return(0); }