L'exécutable

Le source: LancerDeRayonsFonctions.h

/* Auteur: Nicolas JANEY                   */
/* nicolas.janey@univ-fcomte.fr            */
/* Avril 2004                              */
/* Fonction de calcul de lancer de rayons  */

#ifndef LANCERDERAYONSFONCTIONS
#define LANCERDERAYONSFONCTIONS

#include "ModuleMatriceVecteurDouble.h"

enum {
  cube,
  sphere };

struct couleur {
  float r;
  float v;
  float b;
  float a; };

struct materiel {
  struct couleur *diffuse ;
  struct couleur *ambient ;
  int r;
  struct couleur *specular ;
  struct couleur *emission ;
  int t;
  struct couleur *transparence ;
  float shininess ;
  double indice ;
  int damier ;
  float carreau ; };

struct rayon {
  vecteur o ;
  vecteur d ; };

struct objet {
  int type ;
  double tx,ty,tz ;
  double a,ax,ay,az ;
  double rx,ry,rz ;
  struct materiel *m ;
  matrice mp ;
  matrice mpp ;
  matrice mpi ;
  vecteur ori ;
  vecteur dir ;
  vecteur p ;
  vecteur norm ;
  rayon rt ;
  int vrt ;
  rayon rr ; };

struct lumiere {
  vecteur pos ;
  float e;
  struct couleur *coul ; };
  
struct scene {
  int nobj ;
  struct objet *obj ;
  int nlum ;
  struct lumiere *lum ;
  double vang ;
  double cmin ;
  double cmax ;
  int tx ;
  int ty ; };

extern double sensibilite;
extern float fact;

unsigned char *initialisationsCalculImageLancerDeRayon(scene *sc,int width2,int height2);
void initialisationsCalculLancerDeRayon(scene *sc);
void calculImageLancerDeRayon(scene *sc,int j,int w,int h,unsigned char *im);

#endif

Le source: LancerDeRayonsFonctions.cpp

/* Auteur: Nicolas JANEY                   */
/* nicolas.janey@univ-fcomte.fr            */
/* Avril 2004                              */
/* Fonction de calcul de lancer de rayons  */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "LancerDeRayonsFonctions.h"

#define DMIN 100000.0
#define EPSILON 0.0001

double sensibilite = 15.0;
float fact = 2.0F;
static int prof = 15;

void matricePlacement(objet *o,matrice m) {
  toScale(m,o->rx,o->ry,o->rz);
  matrice r;
  toRotation(r,o->a,o->ax,o->ay,o->az);
  matrice t;
  toTranslation(t,o->tx,o->ty,o->tz);
  produitMatriceMatrice(r,m,m);
  produitMatriceMatrice(t,m,m);
}

void matricePlacementInterm(objet *o,matrice m) {
  toRotation(m,o->a,o->ax,o->ay,o->az);
  matrice t;
  toTranslation(t,o->tx,o->ty,o->tz);
  produitMatriceMatrice(t,m,m);
}

void inverseMatricePlacement(objet *o,matrice m) {
  matrice s;
  toScale(s,1.0/o->rx,1.0/o->ry,1.0/o->rz);
  matrice r;
  toRotation(r,-o->a,o->ax,o->ay,o->az);
  toTranslation(m,-o->tx,-o->ty,-o->tz);
  produitMatriceMatrice(r,m,m);
  produitMatriceMatrice(s,m,m);
}

double intersectionCube(scene *s,objet *o,rayon *r) {
  o->ori[0] = r->o[0];
  o->ori[1] = r->o[1];
  o->ori[2] = r->o[2];
  o->ori[3] = 1.0;
  produitMatriceVecteur(o->mpi,o->ori,o->ori);
  o->dir[0] = r->d[0];
  o->dir[1] = r->d[1];
  o->dir[2] = r->d[2];
  o->dir[3] = 0.0;
  produitMatriceVecteur(o->mpi,o->dir,o->dir);
  int inter = 0;
  int cpt = 0;
  double dis = DMIN;
  { double d = (0.5-o->ori[2])/o->dir[2];
    double x = o->ori[0] + d*o->dir[0];
    double y = o->ori[1] + d*o->dir[1];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( y >= -0.5 ) && ( y <= 0.5 ) ) {
      inter += 1;
      if ( d > EPSILON ) {
        o->norm[0] = o->norm[1] = o->norm[3] = 0.0;
        o->norm[2] = 1.0;
        dis = d;
        cpt++; } } }
  { double d = (-0.5-o->ori[2])/o->dir[2];
    double x = o->ori[0] + d*o->dir[0];
    double y = o->ori[1] + d*o->dir[1];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( y >= -0.5 ) && ( y <= 0.5 ) ) {
      inter += 1;
      if ( ( d > EPSILON ) && ( d < dis ) ) {
        o->norm[0] = o->norm[1] = o->norm[3] = 0.0;
        o->norm[2] = -1.0;
        dis = d;
        cpt++; } } }
  if ( inter == 2 ) {
    if ( cpt == 0 )
      return(DMIN);
      else
      return(dis); }
  { double d = (-0.5-o->ori[1])/o->dir[1];
    double x = o->ori[0] + d*o->dir[0];
    double z = o->ori[2] + d*o->dir[2];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) ) {
      inter += 1;
      if ( ( d > EPSILON ) && ( d < dis ) ) {
        o->norm[0] = o->norm[2] = o->norm[3] = 0.0;
        o->norm[1] = -1.0;
        dis = d;
        cpt++; } } }
  if ( inter == 2 ) {
    if ( cpt == 0 )
      return(DMIN);
      else
      return(dis); }
  { double d = (0.5-o->ori[1])/o->dir[1];
    double x = o->ori[0] + d*o->dir[0];
    double z = o->ori[2] + d*o->dir[2];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) ) {
      inter += 1;
      if ( ( d > EPSILON ) && ( d < dis ) ) {
        o->norm[0] = o->norm[2] = o->norm[3] = 0.0;
        o->norm[1] = 1.0;
        dis = d;
        cpt++; } } }
  if ( inter == 2 ) {
    if ( cpt == 0 )
      return(DMIN);
      else
      return(dis); }
  { double d = (-0.5-o->ori[0])/o->dir[0];
    double y = o->ori[1] + d*o->dir[1];
    double z = o->ori[2] + d*o->dir[2];
    if ( ( y >= -0.5 ) && ( y <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) ) {
      inter += 1;
      if ( ( d > EPSILON ) && ( d < dis ) ) {
        o->norm[1] = o->norm[2] = o->norm[3] = 0.0;
        o->norm[0] = -1.0;
        dis = d;
        cpt++; } } }
  if ( inter == 2 ) {
    if ( cpt == 0 )
      return(DMIN);
      else
      return(dis); }
  { double d = (0.5-o->ori[0])/o->dir[0];
    double y = o->ori[1] + d*o->dir[1];
    double z = o->ori[2] + d*o->dir[2];
    if ( ( y >= -0.5 ) && ( y <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) ) {
      inter += 1;
      if ( ( d > EPSILON ) && ( d < dis ) ) {
        o->norm[1] = o->norm[2] = o->norm[3] = 0.0;
        o->norm[0] = 1.0;
        dis = d;
        cpt++; } } }
  if ( inter == 2 )
    if ( cpt == 0 )
      return(DMIN);
      else
      return(dis);
  return(DMIN);
}

double intersectionSphere(scene *s,objet *o,rayon *r) {
  o->ori[0] = r->o[0];
  o->ori[1] = r->o[1];
  o->ori[2] = r->o[2];
  o->ori[3] = 1.0;
  produitMatriceVecteur(o->mpi,o->ori,o->ori);
  o->dir[0] = r->d[0];
  o->dir[1] = r->d[1];
  o->dir[2] = r->d[2];
  o->dir[3] = 0.0;
  produitMatriceVecteur(o->mpi,o->dir,o->dir);
  double a = o->dir[0]*o->dir[0]+o->dir[1]*o->dir[1]+o->dir[2]*o->dir[2];
  double b = 2*(o->dir[0]*o->ori[0]+o->dir[1]*o->ori[1]+o->dir[2]*o->ori[2]);
  double c = o->ori[0]*o->ori[0]+o->ori[1]*o->ori[1]+o->ori[2]*o->ori[2] - 1.0;
  double delta = b*b - 4*a*c;
  if ( delta == 0.0 ) {
    double d = -b/2/a;
    if ( d > EPSILON ) {
      o->norm[0] = (o->dir[0]*d + o->ori[0])*o->ry*o->rz;
      o->norm[1] = (o->dir[1]*d + o->ori[1])*o->rx*o->rz;
      o->norm[2] = (o->dir[2]*d + o->ori[2])*o->rx*o->ry;
      o->norm[3] = 0.0;
      return(d); }
    else
    return(DMIN); }
  if ( delta > 0.0 ) {
    double d1 = (-b-sqrt(delta))/2/a;
    if ( d1 > EPSILON ) {
      o->norm[0] = (o->dir[0]*d1 + o->ori[0])*o->ry*o->rz;
      o->norm[1] = (o->dir[1]*d1 + o->ori[1])*o->rx*o->rz;
      o->norm[2] = (o->dir[2]*d1 + o->ori[2])*o->rx*o->ry;
      o->norm[3] = 0.0;
      return(d1); }
      else {
      double d2 = (-b+sqrt(delta))/2/a;
      if ( d2 > EPSILON ) {
        o->norm[0] = (o->dir[0]*d2 + o->ori[0])*o->ry*o->rz;
        o->norm[1] = (o->dir[1]*d2 + o->ori[1])*o->rx*o->rz;
        o->norm[2] = (o->dir[2]*d2 + o->ori[2])*o->rx*o->ry;
        o->norm[3] = 0.0;
        return(d2); } } }
  return(DMIN);
}

int testIntersectionCube(scene *s,objet *o,rayon *r) {
  vecteur ori;
  vecteur dir;
  ori[0] = r->o[0];
  ori[1] = r->o[1];
  ori[2] = r->o[2];
  ori[3] = 1.0;
  produitMatriceVecteur(o->mpi,ori,ori);
  dir[0] = r->d[0];
  dir[1] = r->d[1];
  dir[2] = r->d[2];
  dir[3] = 0.0;
  produitMatriceVecteur(o->mpi,dir,dir);
  { double d = (0.5-ori[2])/dir[2];
    double x = ori[0] + d*dir[0];
    double y = ori[1] + d*dir[1];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( y >= -0.5 ) && ( y <= 0.5 ) && ( d > EPSILON ) ) {
      return(1); } }
  { double d = (-0.5-ori[2])/dir[2];
    double x = ori[0] + d*dir[0];
    double y = ori[1] + d*dir[1];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( y >= -0.5 ) && ( y <= 0.5 ) && ( d > EPSILON ) ) {
      return(1); } }
  { double d = (-0.5-ori[1])/dir[1];
    double x = ori[0] + d*dir[0];
    double z = ori[2] + d*dir[2];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) && ( d > EPSILON ) ) {
      return(1); } }
  { double d = (0.5-ori[1])/dir[1];
    double x = ori[0] + d*dir[0];
    double z = ori[2] + d*dir[2];
    if ( ( x >= -0.5 ) && ( x <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) && ( d > EPSILON ) ) {
      return(1); } }
  { double d = (-0.5-ori[0])/dir[0];
    double y = ori[1] + d*dir[1];
    double z = ori[2] + d*dir[2];
    if ( ( y >= -0.5 ) && ( y <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) && ( d > EPSILON ) ) {
      return(1); } }
  { double d = (0.5-ori[0])/dir[0];
    double y = ori[1] + d*dir[1];
    double z = ori[2] + d*dir[2];
    if ( ( y >= -0.5 ) && ( y <= 0.5 ) && ( z >= -0.5 ) && ( z <= 0.5 ) && ( d > EPSILON ) ) {
      return(1); } }
  return(0);
}

int testIntersectionSphere(scene *s,objet *o,rayon *r) {
  vecteur ori;
  vecteur dir;
  ori[0] = r->o[0];
  ori[1] = r->o[1];
  ori[2] = r->o[2];
  ori[3] = 1.0;
  produitMatriceVecteur(o->mpi,ori,ori);
  dir[0] = r->d[0];
  dir[1] = r->d[1];
  dir[2] = r->d[2];
  dir[3] = 0.0;
  produitMatriceVecteur(o->mpi,dir,dir);
  double a = dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2];
  double b = 2*(dir[0]*ori[0]+dir[1]*ori[1]+dir[2]*ori[2]);
  double c = ori[0]*ori[0]+ori[1]*ori[1]+ori[2]*ori[2] - 1.0;
  double delta = b*b - 4*a*c;
  if ( delta == 0.0 ) {
    double d = -b/2/a;
    if ( d > EPSILON ) {
      return(1); } }
  if ( delta > 0.0 ) {
    double d1 = (-b-sqrt(delta))/2/a;
    if ( d1 > EPSILON ) {
      return(1); }
      else {
      double d2 = (-b+sqrt(delta))/2/a;
      if ( d2 > EPSILON ) {
        return(1); } } }
  return(0);
}

int rayonTransmis(objet *obj,rayon *r,int interieur) {
  double indice = ( interieur ) ? obj->m->indice : 1.0/obj->m->indice;
  vecteur i = { -r->d[0],-r->d[1],-r->d[2],0.0 } ;
  vecteur norm = { obj->norm[0],obj->norm[1],obj->norm[2],0.0 } ;
  if ( interieur ) {
    norm[0] = -norm[0];
    norm[1] = -norm[1];
    norm[2] = -norm[2]; }
  double scal = produitScalaire(norm,i);
  double n2 = indice*indice;
  double val = 1.0F-n2*(1.0F-scal*scal);
  if ( val < 0.0F )
    return(0);
    else {
    val = indice*scal-sqrt(val);
    obj->rt.d[0] = val*norm[0]-indice*i[0];
    obj->rt.d[1] = val*norm[1]-indice*i[1];
    obj->rt.d[2] = val*norm[2]-indice*i[2];
    obj->rt.d[3] = 0.0;
    obj->rt.o[0] = obj->p[0];
    obj->rt.o[1] = obj->p[1];
    obj->rt.o[2] = obj->p[2];
    obj->rt.o[3] = 1.0;
    return(1); }
}

void rayonReflechi(objet *obj,rayon *r) {
  vecteur i = { -r->d[0],-r->d[1],-r->d[2],0.0 } ;
  double scal = produitScalaire(i,obj->norm);
  obj->rr.d[0] = 2*obj->norm[0]*scal-i[0];
  obj->rr.d[1] = 2*obj->norm[1]*scal-i[1];
  obj->rr.d[2] = 2*obj->norm[2]*scal-i[2];
  obj->rr.d[3] = 0.0;
  obj->rr.o[0] = obj->p[0];
  obj->rr.o[1] = obj->p[1];
  obj->rr.o[2] = obj->p[2];
  obj->rr.o[3] = 1.0;
}

void calculCaracteristiquesIntersection(objet *obj,double dmin,struct rayon *r,int interieur) {
  obj->p[0] = obj->ori[0] + dmin*obj->dir[0];
  obj->p[1] = obj->ori[1] + dmin*obj->dir[1];
  obj->p[2] = obj->ori[2] + dmin*obj->dir[2];
  obj->p[3] = 1.0;
  produitMatriceVecteur(obj->mp,obj->p,obj->p);
  produitMatriceVecteur(obj->mpp,obj->norm,obj->norm);
  normalise(obj->norm);
  if ( ( obj->m->r ) && ( !interieur ) )
    rayonReflechi(obj,r);
  if ( obj->m->t ) {
    obj->vrt = rayonTransmis(obj,r,interieur); }
    else
    obj->vrt = 0;
}

void diffusion(objet *obj,lumiere *lum,couleur *cd) {
  double dist = distance(lum->pos,obj->p);
  vecteur i;
  calculVecteurNorme(obj->p,lum->pos,i) ;
  double fact = produitScalaire(i,obj->norm);
  if ( fact > 0 ) {
    fact = fact/dist/dist*sensibilite;
    cd->r =(float) (fact*lum->coul->r*lum->e);
    cd->v =(float) (fact*lum->coul->v*lum->e);
    cd->b =(float) (fact*lum->coul->b*lum->e); }
    else {
    cd->r = cd->v = cd->b = 0.0F; }
}

int testRayonOmbre(scene *sc,objet *obj,lumiere *lum) {
  rayon r;
  calculVecteur(obj->p,lum->pos,r.d) ;
  r.o[0] = obj->p[0];
  r.o[1] = obj->p[1];
  r.o[2] = obj->p[2];
  r.o[3] = 1.0;
  r.d[3] = 0.0;
  for ( int i = 0 ; i < sc->nobj ; i++ ) {
    switch ( sc->obj[i].type ) {
      case cube      : if ( testIntersectionCube(sc,&sc->obj[i],&r) ) {
                         return(1); }
                       break;
      case sphere    : if ( testIntersectionSphere(sc,&sc->obj[i],&r) ) {
                         return(1); }
                       break; } }
  return(0);
}

void lancerDeRayons(scene *sc,rayon *r,couleur *c,int prof,int interieur) {
  double dmin = DMIN;
  int obj = -1;
  c->r = c->v = c->b = 0.0F;
  for ( int i = 0 ; i < sc->nobj ; i++ ) {
    double d;
    switch ( sc->obj[i].type ) {
      case cube      : d = intersectionCube(sc,&sc->obj[i],r);
                       break;
      case sphere    : d = intersectionSphere(sc,&sc->obj[i],r);
                       break; }
    if ( ( d > EPSILON ) && ( d < dmin ) ) {
      dmin = d;
      obj = i; } }
   if ( obj != -1 ) {
     calculCaracteristiquesIntersection(&sc->obj[obj],dmin,r,interieur);
     objet aux = sc->obj[obj];
     for ( int l = 0 ; l < sc->nlum ; l++ ) {
       if ( !testRayonOmbre(sc,&sc->obj[obj],&sc->lum[l]) ) {
         couleur cd;
         diffusion(&sc->obj[obj],&sc->lum[l],&cd);
         c->r += cd.r*sc->obj[obj].m->diffuse->r;
         c->v += cd.v*sc->obj[obj].m->diffuse->v;
         c->b += cd.b*sc->obj[obj].m->diffuse->b;
         sc->obj[obj] = aux; } }
     if ( prof > 0 ) {
       if ( sc->obj[obj].vrt ) {
         couleur ct;
         lancerDeRayons(sc,&sc->obj[obj].rt,&ct,prof-1,!interieur);
         c->r += ct.r*sc->obj[obj].m->transparence->r;
         c->v += ct.v*sc->obj[obj].m->transparence->v;
         c->b += ct.b*sc->obj[obj].m->transparence->b;
         sc->obj[obj] = aux; }
       if ( ( sc->obj[obj].m->r ) && ( !interieur ) ) {
         couleur cr;
         lancerDeRayons(sc,&sc->obj[obj].rr,&cr,prof-1,0);
         if ( sc->obj[obj].vrt ) {
           c->r += cr.r*sc->obj[obj].m->specular->r;
           c->v += cr.v*sc->obj[obj].m->specular->v;
           c->b += cr.b*sc->obj[obj].m->specular->b; }
           else {
           c->r += cr.r*(sc->obj[obj].m->specular->r+sc->obj[obj].m->transparence->r);
           c->v += cr.v*(sc->obj[obj].m->specular->v+sc->obj[obj].m->transparence->v);
           c->b += cr.b*(sc->obj[obj].m->specular->b+sc->obj[obj].m->transparence->b); } } } }
}

void initialisationsCalculLancerDeRayon(scene *sc) {
  for ( int o = 0 ; o < sc->nobj ; o++ ) {
    inverseMatricePlacement(&sc->obj[o],sc->obj[o].mpi);
    matricePlacementInterm(&sc->obj[o],sc->obj[o].mpp);
    matricePlacement(&sc->obj[o],sc->obj[o].mp); }
}

unsigned char *initialisationsCalculImageLancerDeRayon(scene *sc,int width2,int height2) {
  initialisationsCalculLancerDeRayon(sc);
  int w = width2;
  int h = height2;
  int t = w*h*3 ;
  return((unsigned char *) calloc(t,sizeof(unsigned char)));
}

void calculImageLancerDeRayon(scene *sc,int j,int w,int h,unsigned char *im) {
  double d = tan(sc->vang/360.0F*3.14159F)*sc->cmin/h*2.0F;
  for ( int i = 0 ; i < w ; i++ ) {
    int p = i*3;
    rayon r;
    r.o[0] = 0.0F;
    r.o[1] = 0.0F;
    r.o[2] = 0.0F;
    r.o[3] = 1.0F;
    r.d[0] = (i-w/2)*d+d/2.0F;
    r.d[1] = (j-h/2)*d+d/2.0F;
    r.d[2] = -sc->cmin;
    r.d[3] = 1.0F;
    normalise(r.d);
    couleur c;
    lancerDeRayons(sc,&r,&c,prof,0);
    if ( c.r > 1.0F )
      c.r = 1.0F;
    if ( c.v > 1.0F )
      c.v = 1.0F;
    if ( c.b > 1.0F )
      c.b = 1.0F;
    im[p] =(unsigned char) (c.r*255.0F);
    im[p+1] =(unsigned char) (c.v*255.0F);
    im[p+2] =(unsigned char) (c.b*255.0F); }
}

Le source: LancerDeRayons.cpp

/* Auteur: Nicolas JANEY                    */
/* nicolas.janey@univ-fcomte.fr             */
/* Avril 2004                               */
/* Comparaison Z-Buffer - Lancer de rayons  */

#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 "ModuleMenus.h"
#include "ModuleFont.h"
#include "ModuleMatriceVecteurDouble.h"
#include "ModuleManipulateur.h"

#include "LancerDeRayonsFonctions.h"

static int width ;
static int height ;
static int width2 ;
static int height2 ;
static int f1;
static int f2;
static float indice = 1.0F;
materiel c0 = { (couleur *) couleurRouge(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurGrisMoyen(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurBlanc(),
                3.0F,1.5F,
                0,0.0F };
materiel c1 = { (couleur *) couleurVert(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurGrisMoyen(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurBlanc(),
                3.0F,1.333F,
                0,0.0F };
materiel c2 = { (couleur *) couleurBlanc(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurGrisMoyen(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurGrisMoyen(),
                3.0F,1.33F,
                0,0.0F };
materiel c3 = { (couleur *) couleurBleu(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurGrisMoyen(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurGrisMoyen(),
                3.0F,1.5F,
                0,0.0F };
materiel c41 = { (couleur *) couleurBlanc(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.0F,
                 0,0.0F };
materiel c42 = { (couleur *) couleurRouge(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.0F,
                 0,0.0F };
materiel c43 = { (couleur *) couleurVert(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.0F,
                 0,0.0F };
materiel c44 = { (couleur *) couleurBleu(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.0F,
                 0,0.0F };
materiel c45 = { (couleur *) couleurMagenta(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.0F,
                 0,0.0F };
materiel c5 = { (couleur *) newCouleur(couleurGris(0.15F,0.5F)),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 (couleur *) couleurNoir(),
                 1,(couleur *) couleurBlanc(),
                 3.0F,indice,
                 0,0.0F };
materiel c6 = { (couleur *) newCouleur(couleurGris(0.15F,0.5F)),
                (couleur *) couleurNoir(),
                0,(couleur *) couleurNoir(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurBlanc(),
                3.0F,1.5F,
                0,0.0F };
materiel c7 = { (couleur *) couleurNoir(),
                (couleur *) couleurNoir(),
                1,(couleur *) couleurBlanc(),
                (couleur *) couleurNoir(),
                0,(couleur *) couleurNoir(),
                3.0F,1.5F,
                0,0.0F };
materiel c8 = { (couleur *) couleurJaune(),
                (couleur *) couleurNoir(),
                0,(couleur *) couleurGrisClair(),
                (couleur *) couleurNoir(),
                0,(couleur *) couleurNoir(),
                3.0F,1.5F,
                0,0.0F };
materiel c9 = { (couleur *) couleurCyan(),
                (couleur *) couleurNoir(),
                0,(couleur *) couleurGrisClair(),
                (couleur *) couleurNoir(),
                0,(couleur *) couleurNoir(),
                3.0F,1.5F,
                0,0.0F };
materiel c10 = { (couleur *) couleurRouge(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurGrisClair(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.5F,
                 0,0.0F };
materiel c11 = { (couleur *) couleurVert(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurGrisClair(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.5F,
                 0,0.0F };
materiel c12 = { (couleur *) couleurBlanc(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurGrisClair(),
                 (couleur *) couleurNoir(),
                 0,(couleur *) couleurNoir(),
                 3.0F,1.5F,
                 0,0.0F };

lumiere lums1[2] = { { { 0.0F,2.0F,-10.0F,1.0F },1.0F,(couleur *) couleurBlanc() },
                    { { 0.0F,-2.0F,-12.0F,1.0F },1.0F,(couleur *) couleurBlanc() } };
lumiere lums2[2] = { { { 6.0F,0.0F,-5.0F,1.0F },1.0F,(couleur *) couleurBlanc() },
                     { { -3.0F,0.0F,-8.0F,1.0F },1.0F,(couleur *) couleurBlanc() } };
lumiere lums3[2] = { { { 6.0F,0.0F,-7.5F,1.0F },2.0F,(couleur *) couleurJaune() },
                     { { -6.0F,0.0F,-7.5F,1.0F },2.0F,(couleur *) couleurBlanc() } };
lumiere lums6[2] = { { { 2.0F,1.0F,-6.0F,1.0F },2.5F,(couleur *) couleurBlanc() },
                     { { -2.0F,-1.0F,-6.0F,1.0F },2.5F,(couleur *) couleurBlanc() } };
objet objs1[4] = { { cube,2.0F,2.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.6F,1.2F,0.9F,&c0 },
                   { cube,-2.0F,2.0F,-15.0F,60.0F,1.0F,1.0F,0.0F,2.4F,1.8F,1.2F,&c1 },
                   { sphere,-2.0F,-2.0F,-15.0F,25.0F,-1.0F,1.0F,1.0F,0.9F,1.2F,1.4F,&c2 },
                   { sphere,2.0F,-2.0F,-15.0F,60.0F,-1.0F,-1.0F,1.0F,0.6F,2.1F,1.9F,&c3 } };
objet objs2[2] = { { sphere,0.0F,0.0F,-15.0F,0.0F,0.0F,0.0F,1.0F,2.0F,3.0F,4.0F,&c2 },
                   { sphere,1.0F,0.0F,-10.0F,0.0F,0.0F,0.0F,1.0F,0.4F,0.4F,0.4F,&c3 } };
objet objs3[26] = { { cube,3.0F,3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,3.0F,1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,3.0F,0.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,3.0F,-1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,3.0F,-3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,1.5F,3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,1.5F,1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,1.5F,0.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,1.5F,-1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,1.5F,-3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,0.0F,3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,0.0F,1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,0.0F,0.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,0.0F,-1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,0.0F,-3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,-1.5F,3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,-1.5F,1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,-1.5F,0.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,-1.5F,-1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,-1.5F,-3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,-3.0F,3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,-3.0F,1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,-3.0F,0.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,-3.0F,-1.5F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,-3.0F,-3.0F,-15.0F,35.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { sphere,0.0F,0.0F,-9.0F,0.0F,0.0F,0.0F,1.0F,2.0F,2.0F,2.0F,&c5 } };
objet objs4[26] = { { cube,3.0F,3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,3.0F,1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,3.0F,0.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,3.0F,-1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,3.0F,-3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,1.5F,3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,1.5F,1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,1.5F,0.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,1.5F,-1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,1.5F,-3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,0.0F,3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,0.0F,1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,0.0F,0.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,0.0F,-1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,0.0F,-3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,-1.5F,3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,-1.5F,1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,-1.5F,0.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,-1.5F,-1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,-1.5F,-3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,-3.0F,3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c41 },
                    { cube,-3.0F,1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c42 },
                    { cube,-3.0F,0.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c43 },
                    { cube,-3.0F,-1.5F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c44 },
                    { cube,-3.0F,-3.0F,-15.0F,45.0F,1.0F,1.0F,1.0F,1.0F,0.8F,0.6F,&c45 },
                    { cube,0.0F,0.0F,-8.0F,40.0F,0.1F,1.0F,0.1F,3.0F,3.0F,0.7F,&c6 } };
objet objs5[6] = { { cube,0.0F,0.0F,-14.5F,0.0F,1.0F,1.0F,1.0F,4.5F,4.5F,0.2F,&c12 },
                   { cube,0.0F,2.5F,-12.0F,0.0F,1.0F,1.0F,1.0F,4.5F,0.2F,4.5F,&c11 },
                   { cube,0.0F,-2.5F,-12.0F,0.0F,1.0F,1.0F,1.0F,4.5F,0.2F,4.5F,&c10 },
                   { cube,2.5F,0.0F,-12.0F,0.0F,1.0F,1.0F,1.0F,0.2F,4.5F,4.5F,&c9 },
                   { cube,-2.5F,0.0F,-12.0F,0.0F,1.0F,1.0F,1.0F,0.2F,4.5F,4.5F,&c8 },
                   { sphere,0.0F,0.0F,-12.0F,0.0F,0.0F,0.0F,1.0F,1.75F,1.75F,1.75F,&c7 } };
scene sc1 = { 4,objs1,2,lums1,30.0F,5.0F,40.0F,160,160 };
scene sc2 = { 2,objs2,2,lums2,30.0F,5.0F,40.0F,160,160 };
scene sc3 = { 26,objs3,2,lums3,30.0F,5.0F,40.0F,210,210 };
scene sc4 = { 26,objs4,2,lums3,30.0F,5.0F,40.0F,240,240 };
scene sc5 = { 6,objs5,2,lums6,35.0F,5.0F,40.0F,210,210 };
scene *scenes[6] = { &sc1,&sc2,&sc3,&sc4,&sc5,&sc5 };
static int sce = 2;
static int nsce = 6;
static GLubyte *im = NULL ;

void displayZBuffer(scene *sc) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(sc->vang,(double) width/height,sc->cmin,sc->cmax);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glPushMatrix();
  glEnable(GL_LIGHTING);
  glEnable(GL_CULL_FACE);
  int i;
  for ( i = 0 ; i < sc->nlum ; i++ ) {
    int l = GL_LIGHT0+i;
    glEnable(l);
    float p[4] = { (float) sc->lum[i].pos[0],(float) sc->lum[i].pos[1],(float) sc->lum[i].pos[2],(float) sc->lum[i].pos[3] };
    glLightfv(l,GL_POSITION,p);
    float d[4] = { (float) sc->lum[i].coul->r*sensibilite*fact,(float) sc->lum[i].coul->v*sensibilite*fact,(float) sc->lum[i].coul->b*sensibilite*fact,(float) sc->lum[i].coul->a };
    glLightfv(l,GL_DIFFUSE,d);
    glLightfv(l,GL_SPECULAR,d);
    glLightfv(l,GL_AMBIENT,couleurNoir());
    glLightf(l,GL_CONSTANT_ATTENUATION,0.0F);
    glLightf(l,GL_QUADRATIC_ATTENUATION,1.0F); }   
  for ( ; i < 8 ; i++ ) {
    int l = GL_LIGHT0+i;
    glEnable(l); }
  for ( i = 0 ; i < sc->nobj ; i++ ) {
    glPushMatrix();
    glTranslated(sc->obj[i].tx,sc->obj[i].ty,sc->obj[i].tz);
    manipulateurSouris();
    manipulateurClavier();
    glRotated(sc->obj[i].a,sc->obj[i].ax,sc->obj[i].ay,sc->obj[i].az);
    glScaled(sc->obj[i].rx,sc->obj[i].ry,sc->obj[i].rz);
    glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(float *) sc->obj[i].m->diffuse);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,(float *) sc->obj[i].m->ambient);
    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,(float *) sc->obj[i].m->specular);
    glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,(float *) sc->obj[i].m->emission);
    glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,(float *) &sc->obj[i].m->shininess);
    switch(sc->obj[i].type) {
      case cube     : glutSolidCube(1.0);
                      break;
      case sphere   : glutSolidSphere(1.0,180,180);
                      break; }
    glPopMatrix(); }
  glDisable(GL_LIGHTING);
  glDisable(GL_CULL_FACE);
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void display(void) {
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(scenes[sce]->vang,(double) width/height,scenes[sce]->cmin,scenes[sce]->cmax);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  displayZBuffer(scenes[sce]);
  glFlush();
  glutSwapBuffers();
  glutSwapBuffers();
}

void myinit (void) {
  glClearColor(0.0F,0.0F,0.0F,0.0F);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_ALPHA_TEST);
  glEnable(GL_BLEND);
  glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
}

void reshape(int w, int h) {
  glViewport(0,0,w,h);
  width = w;
  height = h;
}

void ajustementTailleFenetre() {
  if ( ( scenes[sce]->tx != width ) || ( scenes[sce]->ty != height ) )
    glutReshapeWindow(scenes[sce]->tx,scenes[sce]->ty);
    else
    glutPostRedisplay();
}

static int j = 0;
static int anim = 0;

void reAnime(void) {
  j = 0;
  anim = 0; }

void idle(void) {
  int w = width2;
  int h = height2;
  glutSetWindow(f1);
  ajustementTailleFenetre();
  glutSetWindow(f2);
  ajustementTailleFenetre();
  if ( j == 0 )
    im = initialisationsCalculImageLancerDeRayon(scenes[sce],width2,height2);
  calculImageLancerDeRayon(scenes[sce],j,w,h,&im[(j*w)*3]);
  j++;
  if ( j == h ) {
    glutIdleFunc(NULL);
    anim = 0;
    j = 0; }
    else
    glutPostRedisplay();
}

void key2(unsigned char key,int x,int y) {
  switch (key) {
    case 0x0D : anim = 1;
                glutIdleFunc(idle);
                break;
    case ' '  : printf("Indice = ");
                scanf("%f",&indice);
                if ( indice < 0.01F )
                  indice = 0.01F ;
                if ( sce == 2 )
                  c5.indice = indice;
                reAnime();
                glutIdleFunc(idle);
                break ;
    case 43   : indice += 0.01F;
                if ( sce == 2 )
                  c5.indice = indice;
                reAnime();
                glutIdleFunc(idle);
                break;
    case 45   : indice -= 0.01F;
                if ( indice < 1.0F )
                  indice = 1.0F;
                if ( sce == 2 )
                  c5.indice = indice;
                reAnime();
                glutIdleFunc(idle);
                break;
    case 's'  :
    case 'S'  : sce = (sce+1) % nsce;
                if ( sce == 2 )
                  c5.indice = indice;
                if ( sce == 4 )
                  c7.r = c8.r = c9.r = c10.r = c11.r = 0;
                if ( sce == 5 )
                  c7.r = c8.r = c9.r = c10.r = c11.r = 1;
                reAnime();
                glutIdleFunc(idle);
                break ;
    case 0x1B : exit(0) ;
                break; }
}

void key(unsigned char ky,int x,int y) {
  if ( keyManipulateur(ky,x,y) )
    glutPostRedisplay();
    else
    key2(ky,x,y);
}

void displayLancerDeRayon(scene *sc) {
  glPushMatrix() ;
  int w = width2;
  int h = height2;
  if ( im == NULL ) {
    int t = w*h*3 ;
    im =(GLubyte *) calloc(t,sizeof(GLubyte)); }
  glRasterPos2f(0.0F,0.0F) ;
  glDrawPixels(w,h,GL_RGB,GL_UNSIGNED_BYTE,im) ;
  glPopMatrix() ;
}

void display2(void) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  displayLancerDeRayon(scenes[sce]);
  if ( sce == 2 ) {
    setAlignement(CENTER);
    placeFontCursor(width2/2,10.0,0.1F);
    simpleBitmapOutput(1,REGULAR8x13,"INDICE : %6.4f",indice) ; }
  glFlush();
  glutSwapBuffers();
}

void reshape2(int w,int h) {
  glutIdleFunc(idle);
  glViewport(0,0,w,h);
  width2 = w;
  height2 = h;
  int ww = w;
  int hh = h;
  int t = ww*hh*3 ;
  im =(GLubyte *) calloc(t,sizeof(GLubyte));
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,0,h,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  { glutInitWindowSize(320,180); 
    glutInitWindowPosition(20,20); 
    f1 = glutCreateWindow("Mini lancer de rayons: Z-Buffer et Gouraud"); 
    myinit(); 
    ajustementTailleFenetre();
    creationMenuBasique();
    glutKeyboardFunc(key);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutSpecialFunc(specialBasique);
    glutMotionFunc(motionBasique);
    glutMouseFunc(sourisBasique); }
  { glutInitWindowPosition(30,300); 
    glutInitWindowSize(320,180); 
    f2 = glutCreateWindow("Mini lancer de rayons: Lancer de rayons"); 
    myinit(); 
    ajustementTailleFenetre();
    creationMenuBasique();
    glutIdleFunc(idle);
    glutKeyboardFunc(key2);
    glutReshapeFunc(reshape2);
    glutDisplayFunc(display2); }
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR