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