Le source : TD-DiffusionLumiereDirectionnelle.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Fevrier 2002 */
/* Evaluation de la luniere diffusee */
/* sur une surface eclairee par une */
/* lumiere directionnelle */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#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);
}