 
 
Intensité reçue sous lumière ponctuelle
 
 
Intensité reçue sous lumière directionnelle
 
 
 
 
Différents éclairages sur différents objets
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'une infomation  */
/* de couleur                          */
#ifndef RVBA
#define RVBA
#include "Objet.h"
class Rvba : public Objet {
  public :
    float r;
    float v;
    float b;
    float a;
  public :
    Rvba(void);
    Rvba(float r,float v,float b,float a);
    Rvba(Rvba *rvba);
    ~Rvba(void);
    void print(char *format);
 };
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'une infomation  */
/* de couleur                          */
#include "ModuleFont.h"
#include "Rvba.h"
Rvba::Rvba(void) {
  this->r = 0.0F;
  this->v = 0.0F;
  this->b = 0.0F;
  this->a = 1.0F;
}
Rvba::Rvba(float r,float v,float b,float a){
  this->r = r;
  this->v = v;
  this->b = b;
  this->a = a;
}
Rvba::Rvba(Rvba *rvba){
  this->r = rvba->r;
  this->v = rvba->v;
  this->b = rvba->b;
  this->a = rvba->a;
}
Rvba::~Rvba(void){
}
void Rvba::print(char *format) {
  simpleBitmapOutput(1,REGULAR8x13,format,r,v,b,a);
}
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'une infomation  */
/* de couleur                          */
#ifndef ENERGIE
#define ENERGIE
#include "Rvba.h"
class Energie : public Rvba {
   public :
    Energie(void);
    Energie(Energie *c);
    Energie(float r,float v,float b);
    ~Energie(void);
};
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'une infomation  */
/* de couleur                          */
#include "Energie.h"
Energie::Energie(void) : Rvba() {
}
Energie::Energie(float r,float v,float b) : Rvba(r,v,b,1.0F) {
}
Energie::Energie(Energie *c) : Rvba(c->r,c->v,c->b,c->a) {
}
Energie::~Energie(void) {
}
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'une infomation  */
/* de couleur                          */
#ifndef COULEUR
#define COULEUR
#include "Rvba.h"
class Couleur : public Rvba {
  public :
    Couleur(void);
    Couleur(float r,float v,float b);
    Couleur(float r,float v,float b,float a);
    Couleur(Couleur *c);
    ~Couleur(void);
};
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'une infomation  */
/* de couleur                          */
#include "Couleur.h"
Couleur::Couleur(void) : Rvba() {
}
Couleur::Couleur(float r,float v,float b) : Rvba(r,v,b,1.0F) {
}
Couleur::Couleur(float r,float v,float b,float a) : Rvba(r,v,b,a) {
}
Couleur::Couleur(Couleur *c) : Rvba(c->r,c->v,c->b,c->a) {
}
Couleur::~Couleur(void) {
}
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion                   */
/* d'une lumiere generique             */
#ifndef LUMIERE
#define LUMIERE
#include "Objet.h"
#include "Couleur.h"
class Lumiere : public Objet {
  public :
    bool on;
    Couleur *c;
    float e;
    
  public :
    Lumiere(void);
    Lumiere(bool on,Couleur *c,float e);
    Lumiere(Lumiere *l);
    ~Lumiere(void);
};
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion                   */
/* d'une lumiere generique             */
#include "Lumiere.h"
Lumiere::Lumiere(void) {
  this->on = false;
  this->c = new Couleur();
  this->e = 0.0F;
}
Lumiere::Lumiere(bool on,Couleur *c,float e){
  this->on = on;
  this->c = new Couleur(c);
  this->e = e;
}
Lumiere::Lumiere(Lumiere *l){
  this->on = l->on;
  this->c = new Couleur(l->c);
  this->e = l->e;
}
Lumiere::~Lumiere(void){
  delete(c);
}
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion                   */
/* d'une lumiere ponctuelle            */
#ifndef LUMIEREPONCTUELLE
#define LUMIEREPONCTUELLE
#include "Lumiere.h"
#include "Position.h"
#include "Direction.h"
#include "Materiel.h"
#include "Energie.h"
class LumierePonctuelle : public Lumiere {
  public :
    Position *p;
  public :
    LumierePonctuelle(void);
    LumierePonctuelle(bool on,Couleur *c,float e,Position *d);
    LumierePonctuelle(LumierePonctuelle *l);
    ~LumierePonctuelle(void);
    Energie *intensiteRecue(Position *p);
    Energie *energieDiffusee(Position *p,Direction *n,Materiel *m);
};
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion                   */
/* d'une lumiere ponctuelle            */
#include "LumierePonctuelle.h"
#include "Position.h"
#include "Direction.h"
#include "Materiel.h"
#include "Energie.h"
LumierePonctuelle::LumierePonctuelle(void) : Lumiere(false,new Couleur(),0.0F) {
  this->p = new Position();
}
LumierePonctuelle::LumierePonctuelle(bool on,
                                     Couleur *c,
                                     float e,
                                     Position *p) : Lumiere(on,new Couleur(c),e) {
  this->p = new Position(p);
}
LumierePonctuelle::LumierePonctuelle(LumierePonctuelle *l) : Lumiere(l->on,new Couleur(l->c),l->e){
  this->p = new Position(l->p);
}
LumierePonctuelle::~LumierePonctuelle(void){
  delete(c);
  delete(p);
}
Energie *LumierePonctuelle::intensiteRecue(Position *pt) {
  Energie *res = new Energie();
  float l = p->distance(pt);
  if ( l != 0 ) {
    l = e/(l*l);
    res->r = l * c->r;
    res->v = l * c->v;
    res->b = l * c->b; }
  return(res);
}
Energie *LumierePonctuelle::energieDiffusee(Position *pt,
                                            Direction *n,
                                            Materiel *m) {
  Energie *res = new Energie();
  Direction *i = new Direction(pt,p);
  i->normalise();
  float ps = n->produitScalaire(i);
  delete(i);
  if ( ps > 0.0F ) {
    Energie *ip = intensiteRecue(pt);
    res->r = ip->r*m->kd->r*ps;
    res->v = ip->v*m->kd->v*ps;
    res->b = ip->b*m->kd->b*ps;
    delete(ip); }
  return(res);
}
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion                   */
/* d'une lumiere directionnelle        */
#ifndef LUMIEREDIRECTIONNELLE
#define LUMIEREDIRECTIONNELLE
#include "Lumiere.h"
#include "Direction.h"
#include "Position.h"
#include "Materiel.h"
#include "Energie.h"
class LumiereDirectionnelle : public Lumiere {
  public :
    Direction *d;
  public :
    LumiereDirectionnelle(void);
    LumiereDirectionnelle(bool on,Couleur *c,float e,Direction *d);
    LumiereDirectionnelle(LumiereDirectionnelle *l);
    ~LumiereDirectionnelle(void);
    Energie *intensiteRecue(Position *p);
    Energie *energieDiffusee(Position *p,Direction *n,Materiel *m);
};
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion                   */
/* d'une lumiere directionnelle        */
#include "LumiereDirectionnelle.h"
#include "Position.h"
#include "Direction.h"
#include "Materiel.h"
#include "Energie.h"
LumiereDirectionnelle::LumiereDirectionnelle(void) : Lumiere(false,new Couleur(),0.0F) {
  this->d = new Direction();
}
LumiereDirectionnelle::LumiereDirectionnelle(bool on,
                                             Couleur *c,
                                             float e,
                                             Direction *d) : Lumiere(on,new Couleur(c),e) {
  this->d = new Direction(d);
}
LumiereDirectionnelle::LumiereDirectionnelle(LumiereDirectionnelle *l) : Lumiere(l->on,new Couleur(l->c),l->e) {
  this->d = new Direction(l->d);
}
LumiereDirectionnelle::~LumiereDirectionnelle(void) {
  delete(c);
  delete(d);
}
Energie *LumiereDirectionnelle::intensiteRecue(Position *p) {
  Energie *res = new Energie();
  res->r = e * c->r;
  res->v = e * c->v;
  res->b = e * c->b;
  return(res);
}
Energie *LumiereDirectionnelle::energieDiffusee(Position *p,
                                                Direction *n,
                                                Materiel *m) {
  Energie *res = new Energie();
  float ps = -n->produitScalaire(d);
  if ( ps > 0.0F ) {
    Energie *ip = intensiteRecue(p);
    res->r = ip->r*m->kd->r*ps;
    res->v = ip->v*m->kd->v*ps;
    res->b = ip->b*m->kd->b*ps;
    delete(ip); }
  return(res);
}
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'un materiel     */
#ifndef MATERIEL
#define MATERIEL
#include "Objet.h"
#include "Couleur.h"
class Materiel : public Objet {
  public :
    Couleur *kd;
    
  public :
    Materiel(void);
    Materiel(Couleur *kd);
    Materiel(Materiel *l);
    ~Materiel(void);
};
#endif
/* Auteur: Nicolas JANEY               */
/* nicolas.janey@univ-fcomte.fr        */
/* Octobre 2005                        */
/* Classe de gestion d'un materiel     */
#include "Materiel.h"
Materiel::Materiel(void) {
  this->kd = new Couleur();
}
Materiel::Materiel(Couleur *kd){
  this->kd = new Couleur(kd);
}
Materiel::Materiel(Materiel *l){
  this->kd = new Couleur(l->kd);
}
Materiel::~Materiel(void){
  delete(kd);
}
/* 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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#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);
}