L'exécutable

Les trois modules après remplissage des fonctions:

/* Definitions et fonctions d'utilite generale  */
/* pour la gestion de directions                */
/* dans un espace a 3 dimensions                */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2009                                */

#include <math.h>

#include "RayTracing-Direction.h"

/* Fonction de calcul de la direction du rayon  */
/* lumineux reflechi cree par un rayon lumineux */
/* incident defini par sa direction             */
/* de propagation                               */

void reflexion(direction *r,direction *i,direction *n) {
  double ps2 = 2.0*produitScalaire(n,i);
  r->x = ps2*n->x - i->x;
  r->y = ps2*n->y - i->y;
  r->z = ps2*n->z - i->z;
  r->t = 0.0;
}

/* Fonction de calcul de la direction du rayon  */
/* lumineux transmis eventuellement cree        */
/* par un rayon lumineux incident defini        */
/* par sa direction de propagation              */

int transmission(direction *t,direction *i,direction *n,
                 double niSurnt) {
  double ps = produitScalaire(n,i);
  double v = 1.0-(niSurnt*niSurnt*(1.0-ps*ps));
  if ( v < 0.0 )
    return(0);
  v = niSurnt*ps-sqrt(v);
  t->x = v*n->x - niSurnt*i->x;
  t->y = v*n->y - niSurnt*i->y;
  t->z = v*n->z - niSurnt*i->z;
  t->t = 0.0;
  return(1);
}

/* Fonction de normalisation d'une direction    */

void normalise(direction *d) {
  double l = sqrt(d->x*d->x+d->y*d->y+d->z*d->z);
  if ( l != 0 ) {
    d->x /= l;
    d->y /= l;
    d->z /= l; }
}

/* Fonction de calcul du produit scalaire       */
/* entre deux directions                        */

double produitScalaire(direction *d1,direction *d2) {
  return(d1->x*d2->x+d1->y*d2->y+d1->z*d2->z);
}

/* Fonction de calcul de la direction           */
/* normalisee definie d'une position            */
/* a une autre position                         */

void calculDirectionNormalisee(direction *d,position *p1,position *p2) {
  d->x = p2->x-p1->x;
  d->y = p2->y-p1->y;
  d->z = p2->z-p1->z;
  d->t = 0.0;
  normalise(d);
}

/* Definitions et fonctions d'utilite generale  */
/* pour la gestion de positions                 */
/* dans un espace a 3 dimensions                */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2009                                */

#include <math.h>

#include "RayTracing-Position.h"

/* Fonction de calcul du carre de la distance   */
/* entre deux positions                         */

double carreDistance(position *p1,position *p2) {
  double dx = p2->x-p1->x;
  double dy = p2->y-p1->y;
  double dz = p2->z-p1->z;
  return(dx*dx+dy*dy+dz*dz);
}

/* Fonction de calcul de la distance            */
/* entre deux positions                         */

double distance(position *p1,position *p2) {
  return(sqrt(carreDistance(p1,p2)));
}

/* Definitions et fonctions d'utilite generale  */
/* pour la gestion de spheres                   */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2009                                */

#include <math.h>

#include "RayTracing-Sphere.h"
#include "RayTracing-LumierePonctuelle.h"
#include "RayTracing-LumiereDirectionnelle.h"

/* Fonction de determination de l'intersection  */
/* entre un rayon lumineux et une sphere.       */
/* Un int booleen en retour pour indiquer       */
/* l'existence ou non d'une intersection.       */
/* Un double en passage par adresse pour        */
/* retourner la distance entre l'origine        */
/* du rayon en l'intersection la plus proche    */
/* de l'origine du rayon sur sa trajectoire.    */

int intersection(rayonLumineux *rl,sphere *sp,double *d) {
  double sx = rl->origine.x - sp->centre.x ;
  double sy = rl->origine.y - sp->centre.y;
  double sz = rl->origine.z - sp->centre.z;
  double a = rl->direction.x*rl->direction.x +
             rl->direction.y*rl->direction.y + 
             rl->direction.z*rl->direction.z;
  double b = 2.0F*(rl->direction.x*sx + 
                   rl->direction.y*sy + 
                   rl->direction.z*sz);
  double c = sx*sx + sy*sy + sz*sz - sp->rayon*sp->rayon;
  double delta = b*b-4*a*c;
  if ( delta < 0.0 )
    return(0);
  if ( delta == 0 ) {
    double t = -b/(2.0*a);
    if ( t >= 0.000001) {
      *d = t;
      return(1); }
      else
      return(0); }
  { double t = (-b-sqrt(delta))/(2.0*a);
    if ( t >= 0.000001 ) {
      *d = t;
      return(1); } }
  { double t = (-b+sqrt(delta))/(2.0*a);
    if ( t >= 0.000001 ) {
      *d = t;
      return(1); } }
  return(0);
}

/* Fonction de determination de l'existence     */
/* d'une intersection entre un rayon lumineux   */
/* et une sphere.                               */

int intersection(rayonLumineux *rl,sphere *sp) {
  double sx = rl->origine.x - sp->centre.x ;
  double sy = rl->origine.y - sp->centre.y;
  double sz = rl->origine.z - sp->centre.z;
  double a = rl->direction.x*rl->direction.x + 
             rl->direction.y*rl->direction.y + 
             rl->direction.z*rl->direction.z;
  double b = 2.0F*(rl->direction.x*sx + 
                   rl->direction.y*sy + 
                   rl->direction.z*sz);
  double c = sx*sx + sy*sy + sz*sz - sp->rayon*sp->rayon;
  double delta = b*b-4*a*c;
  if ( delta < 0.0F )
    return(0);
  if ( delta == 0 ) {
    double t = -b/(2.0*a);
    if ( t >= 0.000001) {
      return(1); }
      else
      return(0); }
  { double t = (-b-sqrt(delta))/(2.0*a);
    if ( t >= 0.000001 ) {
      return(1); } }
  { double t = (-b+sqrt(delta))/(2.0*a);
    if ( t >= 0.000001 ) {
      return(1); } }
  return(0);
}

/* Fonction de calcul de la normale exterieure  */
/* en un point d'une sphere                     */

void calculNormale(direction *d,position *p,sphere *sp) {
  d->x = (p->x - sp->centre.x)/sp->rayon;
  d->y = (p->y - sp->centre.y)/sp->rayon;
  d->z = (p->z - sp->centre.z)/sp->rayon;
  d->t = 0.0;
}

/* Fonction de calcul de la quantite d'energie  */
/* diffusee en un point d'une sphere            */
/* sous l'ensemble des eclairages crees         */
/* par les sources lumineuses presentes         */
/* dans une scene                               */
/* La normale a la sphere au point est donnee   */
/* en entete                                    */

void calculDiffusion(energie *e,
                     scene *scn,
                     sphere *sp,position *p,direction *n) {
  e->r = e->v = e->b = 0.0;
  int i;
  for ( i = 0 ; i < scn->nbLumieresPonctuelles ; i++ ) {
    lumierePonctuelle *lp = &scn->lumieresPonctuelles[i]; 
    double d = distance(p,&lp->position);
    if ( estEclaire(p,scn,lp,d) ) {
      energie ed;
      calculDiffusion(&ed,p,n,&sp->materiel.kd,lp);
      e->r += ed.r;
      e->v += ed.v;
      e->b += ed.b; } }
  for ( i = 0 ; i < scn->nbLumieresDirectionnelles ; i++ ) {
    lumiereDirectionnelle *ld = &scn->lumieresDirectionnelles[i]; 
    if ( estEclaire(p,scn,ld) ) {
      energie ed;
      calculDiffusion(&ed,n,&sp->materiel.kd,ld);
      e->r += ed.r;
      e->v += ed.v;
      e->b += ed.b; } }
}

/* Fonction de calcul du rayon lumineux         */
/* reflechi cree par un rayon lumineux incident */

void rayonReflechi(rayonLumineux *rr,
                   rayonLumineux *ri,
                   sphere *sp,position *p,direction *n) {
  direction i = ri->direction;
  i.x *= -1;
  i.y *= -1;
  i.z *= -1;
  rr->origine = *p;
  reflexion(&rr->direction,&i,n);
}

/* Fonction de calcul du rayon lumineux         */
/* transmis genere eventuellement               */
/* par un rayon lumineux incident               */                            

int rayonTransmis(rayonLumineux *rt,
                  rayonLumineux *ri,
                  sphere *sp,position *p,direction *n,
                  double niSurnt,int exterieur) {
  direction norm = *n;
  if ( !exterieur ) {
    norm.x *= -1;
    norm.y *= -1;
    norm.z *= -1; }
  direction i = ri->direction;
  i.x *= -1;
  i.y *= -1;
  i.z *= -1;
  if ( transmission(&rt->direction,&i,&norm,niSurnt) ) {
    rt->origine = *p;
    return(1); }
    else
    return(0);
}

Fichier principal : RayTracingSurSpheres.cpp

/* Un mini programme de ray-tracing             */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2009                                */

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

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "RayTracing-Position.h"
#include "RayTracing-Direction.h"
#include "RayTracing-Scene.h"
#include "RayTracing-Sphere.h"
#include "RayTracing-LumierePonctuelle.h"
#include "RayTracing-LumiereDirectionnelle.h"

#include "RayTracing-Image.h"
#include "RayTracing-MathematiquesMatricielles.h"

/* Variables globales de gestion                */
/* de l'interactivite clavier et souris         */

static int clic = 0;
static int mx;
static int my;
static float rx = 0.0F;
static float ry = 0.0F;
static float csc = 200.0F;

/* Definition d'une premiere scene en statique  */

static sphere spheres1[6] = 
  { { { 0.0,0.0,-610.0,1.0 },
      40.0,
      { { 1.0,1.0,0.0 },
        { 0.0,0.0,0.0 },
        { 0.0,0.0,0.0 },
        1.0 } },
    { { -90.0,90.0,-600.0,1.0 },
      40.0,
      { { 1.0,0.0,0.0 },
        { 0.0,0.0,0.0 },
        { 0.0,0.0,0.0 },
        1.0 } },
    { { 90.0,-90.0,-600.0,1.0 },
      40.0,
      { { 0.0,1.0,0.0 },
        { 0.0,0.0,0.0 },
        { 0.0,0.0,0.0 },
        1.0 } },
    { { -90.0,-90.0,-600.0,1.0 },
      40.0,
      { { 0.0,0.0,1.0 },
        { 0.0,0.0,0.0 },
        { 0.0,0.0,0.0 },
        1.0 } },
    { { 90.0,90.0,-600.0,1.0 },
      40.0,
      { { 1.0,1.0,1.0 },
        { 0.0,0.0,0.0 },
        { 0.0,0.0,0.0 },
        1.0 } },
    { { 0.0,0.0,-200.0,1.0 },
      120.0,
      { { 0.25,0.25,0.25 },
        { 0.0,0.0,0.0 },
        { 0.75,0.75,0.75 },
        1.5 } } };
static lumierePonctuelle lumieresPonctuelles1[2] =
  { { { 80.0,20.0,0.0,1.0 },
      15000.0,
      { 0.9,0.9,0.0 } },
    { { -80.0,-20.0,0.0,1.0 },
      28000.0,
      { 0.8,0.8,0.8 } } };
static lumiereDirectionnelle lumieresDirectionnelles1[3] =
  { { { 0.57735,0.57735,0.57735,0.0 },
      3.0,
      { 0.0,0.9,0.9 } },
    { { -0.57735,0.57735,0.57735,0.0 },
      1.5,
      { 0.8,0.0,0.8 } },
    { { 0.0,0.707,-0.707,0.0 },
      1.5,
      { 0.8,0.0,0.8 } } };
static scene scn1 =
  { 6,
    spheres1,
    2,
    lumieresPonctuelles1,
    2,
    lumieresDirectionnelles1 };

/* Definition d'une seconde scene en statique   */

static sphere spheres2[8] =
  { { { 160.0,50.0,-200.0,1.0 },
      90.0,
      { { 0.8,0.8,0.8 },
        { 0.1,0.1,0.1 },
        { 0.1,0.1,0.1 },
        1.3 } },
    { { 130.0,115.0,-100.0,1.0 },
      20.0,
      { { 0.3,0.3,0.8 },
        { 0.6,0.6,0.1 },
        { 0.1,0.1,0.1 },
        1.3 } },
    { { 10.0,-10.0,-150.0,1.0 },
      70.0,
      { { 0.1,0.2,0.4 },
        { 0.9,0.8,0.6 },
        { 0.0,0.0,0.0 },
        1.5 } },
    { { -150.0,-60.0,-150.0,1.0 },
      60.0,
      { { 0.5,0.4,0.3 },
        { 0.1,0.1,0.1 },
        { 0.4,0.5,0.6 },
        1.4 } },
    { { -110.0,-80.0,-30.0,1.0 },
      30.0,
      { { 0.4,0.3,0.2 },
        { 0.3,0.2,0.4 },
        { 0.2,0.4,0.3 },
        1.2 } },
    { { 50.0,20.0,-30.0,1.0 },
      10.0,
      { { 0.2,0.3,0.0 },
        { 0.8,0.6,0.7 },
        { 0.0,0.1,0.3 },
        1.2 } },
    { { -90.0,90.0,-70.0,1.0 },
      50.0,
      { { 1.0,0.5,0.5 },
        { 0.0,0.5,0.5 },
        { 0.0,0.0,0.0 },
        1.2 } },
    { { 0.0,65.0,-45.0,1.0 },
      44.0,
      { { 0.25,0.25,0.25 },
        { 0.0,0.0,0.0 },
        { 0.75,0.75,0.75 },
        1.45 } } };
static lumierePonctuelle lumieresPonctuelles2[2] =
  { { { 80.0,20.0,0.0,1.0 },
      15000.0,
      { 0.9,0.9,0.0 } },
    { { -80.0,-20.0,0.0,1.0 },
      28000.0,
      { 0.8,0.8,0.8 } } };
static lumiereDirectionnelle lumieresDirectionnelles2[2] =
  { { { 0.57735,0.57735,0.57735,0.0 },
      3.0,
      { 0.0,0.9,0.9 } },
    { { -0.57735,0.57735,0.57735,0.0 },
      1.5,
      { 0.8,0.0,0.8 } } };
static scene scn2 =
  { 8,
    spheres2,
    2,
    lumieresPonctuelles2,
    2,
    lumieresDirectionnelles2 };

/* Definition d'un tableau de 2 scenes          */

static scene *scn[2] =
  { &scn1,
    &scn2 };

void orienteScene(scene *scene) {
  matrice tr1;
  matrice rtx;
  matrice rty;
  matrice tr2;
  matrice m;
  toTranslation(tr1,0.0,0.0,csc);
  toTranslation(tr2,0.0,0.0,-csc);
  toRotationX(rtx,rx);
  toRotationY(rty,ry);
  produitMatriceMatrice(rty,tr1,m);
  produitMatriceMatrice(rtx,m,m);
  produitMatriceMatrice(tr2,m,m);
  int i;
  for ( i = 0 ; i < scene->nbSpheres ; i++ )
    produitMatriceVecteur(m,
                          (double *) &scene->spheres[i].centre,
                          (double *) &scene->spheres[i].centre);
  for ( i = 0 ; i < scene->nbLumieresPonctuelles ; i++ )
    produitMatriceVecteur(m,
                          (double *) &scene->lumieresPonctuelles[i].position,
                          (double *) &scene->lumieresPonctuelles[i].position);
  for ( i = 0 ; i < scene->nbLumieresDirectionnelles ; i++ )
    produitMatriceVecteur(m,
                          (double *) &scene->lumieresDirectionnelles[i].direction,
                          (double *) &scene->lumieresDirectionnelles[i].direction);
}

/* Variables globales de stockage des handles   */
/* des deux fenetres                            */

static int f1;
static int f2;

/* Variables globales                           */

static int lignesTraitees = 0;
static image ima = { 0,0,NULL } ;
static long nbRayons;
static int sc = 0;
static int mode = 1;

/* Variables globales de gestion du ray-tracing */

static int niveauRecursivite = 10;
static int resolutionX = 480;
static int resolutionY = 300;
static double sensibilite = 100.0;

/* Fonction d'affichage d'une eventuelle        */
/* erreur OpenGL                                */

static void checkError(int line) {
  GLenum err = glGetError();
  if (err) {
    printf("GL Error %s (0x%x) at line %d\n",
           gluErrorString(err), (int) err, line); }
}

/* Fonction display GLUT d'affichage            */
/* de la bitmap resultat du ray-tracing         */

void display(void) { 
  glClear(GL_COLOR_BUFFER_BIT); 
  glPushMatrix();
  glClearColor(0.0,0.0,0.0,1.0); 
  glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
  glPixelStorei(GL_PACK_ALIGNMENT,1); 
  affichageImage(&ima);
  glPopMatrix();
  glFlush(); 
  checkError(__LINE__);
  glutSwapBuffers();


/* Fonction de test de nullite d'une couleur   */
/* (noir)                                      */

static int estNul(couleur *cf) {
  return(( cf->r == 0.0 ) && ( cf->v == 0.0 ) && ( cf->b == 0.0 ) );
}

/* Fonction de calcul de la position d'un point */
/* sur un rayon lumineux                        */

static void calculPositionSurRayon(position *p,rayonLumineux *rl,double d) {
  p->x = rl->origine.x + d*rl->direction.x;
  p->y = rl->origine.y + d*rl->direction.y;
  p->z = rl->origine.z + d*rl->direction.z;
  p->t = 1.0;
}

/* Fonction principale recursive de calcul      */
/* de ray-tracing                               */

void rayTracing(energie *e,
                rayonLumineux *rl,
                scene *scn,
                int niveau,
                double indiceRefraction,
                int exterieur) {
  nbRayons++;
  e->r = e->v = e->b = 0.0;
  double dmin = 1000000000.0;
  int obj = -1;
  int i;
  for ( i = 0 ; i < scn->nbSpheres ; i++ ) {
    double dist;
    if ( intersection(rl,&scn->spheres[i],&dist) ) {
      if ( dist < dmin ) {
        dmin = dist;
        obj = i; } } }
  if ( obj != -1 ) {
    position p;
    calculPositionSurRayon(&p,rl,dmin);
    direction n;
    calculNormale(&n,&p,&scn->spheres[obj]);
    if ( exterieur ) {
      energie ed;
      calculDiffusion(&ed,scn,&scn->spheres[obj],&p,&n);
      e->r += ed.r;
      e->v += ed.v;
      e->b += ed.b; }
    if ( niveau != 1 ) {
      sphere *sp = &scn->spheres[obj];
      couleur *kr = &sp->materiel.kr;
      couleur *kt = &sp->materiel.kt;
      if ( !estNul(kr) && exterieur ) {
        rayonLumineux rr;
        rayonReflechi(&rr,rl,sp,&p,&n);
        energie er;
        rayTracing(&er,&rr,scn,niveau-1,indiceRefraction,1);
        e->r += er.r*kr->r;
        e->v += er.v*kr->v;
        e->b += er.b*kr->b; }
      if ( !estNul(kt) ) {
        rayonLumineux rt;
        double niSurnt = indiceRefraction/sp->materiel.indice;
        if ( rayonTransmis(&rt,
                           rl,sp,&p,&n,niSurnt,exterieur) ) {
          energie et;
          rayTracing(&et,
                     &rt,
                     scn,
                     niveau-1,
                     (exterieur) ? sp->materiel.indice : 1.0,
                     !exterieur);
          e->r += et.r*kt->r;
          e->v += et.v*kt->v;
          e->b += et.b*kt->b; } } } }
}

/* Fonction de calcul en ray-tracing            */
/* d'une ligne de pixels de l'image             */
/* Chaque rayon primaire est dirige en -z       */
/* -> projection parallele orthographique       */

void traiteLigne(int ligne,image *img) {
  for ( int i = 0 ; i < img->tx ; i++ ) {
    rayonLumineux rl;
    rl.origine.x = (i-img->tx/2.0)/(img->tx/480.0);
    rl.origine.y = (ligne-img->ty/2.0)/(img->tx/480.0);
    rl.origine.z = 2000.0;
    rl.origine.t = 1.0;
    rl.direction.x = 0.0;
    rl.direction.y = 0.0;
    rl.direction.z = -1.0;
    rl.direction.t = 0.0;
    energie energieRecue;
    scene nsc;
    copieScene(scn[sc],&nsc);
    orienteScene(&nsc);
    rayTracing(&energieRecue,&rl,&nsc,niveauRecursivite,1.0,1);
    affecteEnergieSurPixel(&energieRecue,sensibilite,img,i,ligne);
    liberationScene(&nsc); }
}

/* Fonction idle                                */
/* Calcul de 20 lignes de pixels en ray-tracing */
/* Arret quand l'image est entierement calculee */

void idle(void) {
  for ( int i = 0 ; i < 20 ; i++ ) {
    traiteLigne(lignesTraitees,&ima);
    lignesTraitees++;
    if ( lignesTraitees == resolutionY ) {
      glutIdleFunc(NULL);
      printf("%d %d\n",niveauRecursivite,nbRayons);
      glutPostWindowRedisplay(f1);
      return; } }
  glutPostWindowRedisplay(f1);
}

/* Fonction executee lors de la frappe          */
/* d'une touche alphanumerique du clavier       */

void key(unsigned char key,int x,int y) {
  switch ( key ) {
    case 43   : niveauRecursivite++;
                lignesTraitees = 0;
                desallocationMemoire(&ima);
                allocationMemoire(resolutionX,resolutionY,&ima);
                nbRayons = 0;
                glutIdleFunc(idle);
                break;
    case 45   : niveauRecursivite--;
                if ( niveauRecursivite < 1 )
                  niveauRecursivite = 1;
                lignesTraitees = 0;
                desallocationMemoire(&ima);
                allocationMemoire(resolutionX,resolutionY,&ima);
                nbRayons = 0;
                glutIdleFunc(idle);
                break;
    case 0x20 : sc = (sc+1)%2;
                csc = (sc) ? 150.0F : 200.0F;
                glutIdleFunc(NULL);
                glutPostWindowRedisplay(f2);
                break;
    case 0x0D : lignesTraitees = 0;
                desallocationMemoire(&ima);
                allocationMemoire(resolutionX,resolutionY,&ima);
                nbRayons = 0;
                glutIdleFunc(idle);
                break;
    case 0x1B : desallocationMemoire(&ima);
                exit(0);
                break; }
}

/* Fonction reshape de l'affichage ray-tracing  */

void reshape(int w,int h) {
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,0,h,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  resolutionX = w;
  resolutionY = h;
  desallocationMemoire(&ima);
  allocationMemoire(resolutionX,resolutionY,&ima);
  glutIdleFunc(NULL);
  glutSetWindow(f2);
  glutReshapeWindow(w,h);
}

/* Fonction reshape de l'affichage OpenGL       */

void reshapeOpenGL(int w,int h) {
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-240.0,240.0,
          -240.0*(double) h/w,240.0*(double) h/w,
          -5000.0,5000.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

/* Fonction display GLUT d'affichage OpenGL     */
/* de la scene                                  */

void displayOpenGL(void) { 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_NORMALIZE);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_CULL_FACE);
  glEnable(GL_ALPHA_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  float noir[4] = { 0.0F,0.0F,0.0F,0.0F };
  glPushMatrix();
  glTranslatef(0.0F,0.0F,-csc);
  glRotatef(rx,1.0F,0.0F,0.0F);
  glRotatef(ry,0.0F,1.0F,0.0F);
  glTranslatef(0.0F,0.0F,csc);
  int lum = GL_LIGHT0;
  int i;
  for ( i = 0 ; i < scn[sc]->nbLumieresPonctuelles ; i++ ) {
    lumierePonctuelle *lp = &scn[sc]->lumieresPonctuelles[i];
    float fact = lp->intensite * sensibilite / 255.0;
    glEnable(lum);
    float pos[4] = { lp->position.x,
                     lp->position.y,
                     lp->position.z,
                     1.0F };
    glLightfv(lum,GL_POSITION,pos);
    glLightf(lum,GL_CONSTANT_ATTENUATION,1.0F);
    glLightf(lum,GL_LINEAR_ATTENUATION,1.0F);
    glLightf(lum,GL_QUADRATIC_ATTENUATION,1.0F);
    float dif[4] = { lp->couleur.r * fact,
                     lp->couleur.v * fact,
                     lp->couleur.b * fact,
                     1.0F };
    glLightfv(lum,GL_SPECULAR,noir);
    glLightfv(lum,GL_DIFFUSE,dif);
    lum++; }
  for ( i = 0 ; i < scn[sc]->nbLumieresDirectionnelles ; i++ ) {
    lumiereDirectionnelle *ld = &scn[sc]->lumieresDirectionnelles[i];
    glEnable(lum);
    float dir[4] = { ld->direction.x,
                     ld->direction.y,
                     ld->direction.z,
                     0.0F };
    glLightfv(lum,GL_POSITION,dir);
    glLightf(lum,GL_CONSTANT_ATTENUATION,1.0F);
    glLightf(lum,GL_LINEAR_ATTENUATION,1.0F);
    glLightf(lum,GL_QUADRATIC_ATTENUATION,1.0F);
    float fact = ld->intensite * sensibilite / 255.0;
    float dif[4] = { ld->couleur.r * fact,
                     ld->couleur.v * fact,
                     ld->couleur.b * fact,
                     1.0F };
    glLightfv(lum,GL_SPECULAR,noir);
    glLightfv(lum,GL_DIFFUSE,dif);
    lum++; } 
  for ( i = 0 ; i < scn[sc]->nbSpheres ; i++ ) {
    sphere *sp = &scn[sc]->spheres[i];
    float alpha =(sp->materiel.kt.r+
                  sp->materiel.kt.v+
                  sp->materiel.kt.b)/3.0F;
    glPushMatrix();
    glTranslated(sp->centre.x,sp->centre.y,sp->centre.z);
    float dif[4] = { sp->materiel.kd.r,
                     sp->materiel.kd.v,
                     sp->materiel.kd.b,
                     1.0F-alpha };
    glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,dif);
    glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,noir);
    glutSolidSphere(sp->rayon,180,180);
    glPopMatrix(); }
  glPopMatrix();
  glFlush(); 
  checkError(__LINE__);
  glutSwapBuffers();


/* Fonction executee lors d'un clic de souris   */
/* dans la fenetre                              */

void mouse(int bouton,int etat,int x,int y) {
  if ( bouton == GLUT_LEFT_BUTTON ) {
    if ( etat == GLUT_DOWN ) {
      clic = 1;
      mx = x;
      my = y; }
    if ( etat == GLUT_UP ) {
      clic = 0; } }
}

/* Fonction executee lors d'un deplacement      */
/* de la souris sur la fenetre                  */
/* avec un bouton appuye                        */

void motion(int x,int y) {
  if ( clic ) {
    ry += (x-mx);
    rx += (y-my);
    mx = x;
    my = y;
    glutPostWindowRedisplay(f2); }
}

/* Fonction Pricipale                           */

int main(int argc,char **argv) {
  allocationMemoire(resolutionX,resolutionY,&ima);
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  glutInitWindowSize(resolutionX,resolutionY); 
  glutInitWindowPosition(30,30); 
  f1 = glutCreateWindow("Mini Ray-Tracing"); 
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutDisplayFunc(display);
  glutInitWindowPosition(530,30); 
  f2 = glutCreateWindow("OpenGL");
  glutMouseFunc(mouse);
  glutMotionFunc(motion);
  glutKeyboardFunc(key);
  glutReshapeFunc(reshapeOpenGL);
  glutDisplayFunc(displayOpenGL);
  glutMainLoop();
  return(0);
}

Tous les fichiers originaux : RayTracing.zip

RETOUR