L'exécutable

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);
}

Les modules utilitaires : Modules.zip

RETOUR