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