Taches lumineuses en déplacement quand la lumière ponctuelle se déplace
Eclairages: Diffusion + réflexion spéculaire, diffusion uniquement, réflexion spéculaire uniquement
Apparition de problèmes d'aliasage liés à la facettisation
Programme principal : IlluminationsSphereGL.cpp
/* Une sphere illuminee */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Septembre 2010 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "CoordonneesHomogenes.h"
#include "Position3D.h"
#include "Direction3D.h"
#include "FacetteTriangulaire.h"
#include "LumierePonctuelle.h"
#include "Energie.h"
#include "Couleur.h"
#include "Rotation.h"
/* Variables et constantes globales */
/* pour les angles et les couleurs utilises */
static int lum = 0;
static float rx = 0.0F;
static float ry = 0.0F;
static float rz = 0.0F;
static int n = 36;
static LumierePonctuelle *lp;
static Position3D *obs;
/* Fonction d'initialisation des parametres */
/* OpenGL ne changeant pas au cours de la vie */
/* du programme */
void init(void) {
const GLfloat shininess[] = { 50.0 };
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_AUTO_NORMAL);
}
/* Scene dessinee */
void facette(Position3D *p1,Position3D *p2,Position3D *p3,
Direction3D *n1,Direction3D *n2,Direction3D *n3) {
Couleur *kd;
Couleur *kr;
switch ( lum ) {
case 0 :
kd = new Couleur(1.0,0.0,0.0);
kr = new Couleur(0.0,0.8,0.8);
break;
case 1 :
kd = new Couleur(1.0,0.0,0.0);
kr = new Couleur(0.0,0.0,0.0);
break;
case 2 :
kd = new Couleur(0.0,0.0,0.0);
kr = new Couleur(0.0,0.8,0.8);
break; }
Energie *e1 = new Energie();
Energie *e2 = new Energie();
Energie *e3 = new Energie();
{ Energie *ed1 = new Energie();
ed1->calculDiffusion(p1,n1,kd,lp);
Energie *er1 = new Energie();
er1->calculReflexionSpeculaire(p1,n1,kr,lp,obs);
e1->r = ed1->r+er1->r;
e1->v = ed1->v+er1->v;
e1->b = ed1->b+er1->b;
delete(ed1);
delete(er1); }
{ Energie *ed2 = new Energie();
ed2->calculDiffusion(p2,n2,kd,lp);
Energie *er2 = new Energie();
er2->calculReflexionSpeculaire(p2,n2,kr,lp,obs);
e2->r = ed2->r+er2->r;
e2->v = ed2->v+er2->v;
e2->b = ed2->b+er2->b;
delete(ed2);
delete(er2); }
{ Energie *ed3 = new Energie();
ed3->calculDiffusion(p3,n3,kd,lp);
Energie *er3 = new Energie();
er3->calculReflexionSpeculaire(p3,n3,kr,lp,obs);
e3->r = ed3->r+er3->r;
e3->v = ed3->v+er3->v;
e3->b = ed3->b+er3->b;
delete(ed3);
delete(er3); }
glBegin(GL_TRIANGLES);
glColor3dv((double *) e1);
glVertex3dv((double *) p1);
glColor3dv((double *) e2);
glVertex3dv((double *) p2);
glColor3dv((double *) e3);
glVertex3dv((double *) p3);
glEnd();
delete(e1);
delete(e2);
delete(e3);
delete(kd);
delete(kr);
}
#ifndef M_PI
#define M_PI 3.14159
#endif
void sphere(double r,float n,float m) {
for ( int i = 0 ; i < n ; i++ ) {
float a1 = -M_PI/2.0F + i*M_PI/n ;
float a2 = a1 + M_PI/n ;
float cs1 = cos(a1);
float cs2 = cos(a2);
float sn1 = sin(a1);
float sn2 = sin(a2);
for ( int j = 0 ; j < m ; j++ ) {
float a = j*2*M_PI/m;
float b = (j+1)*2*M_PI/m;
double csa = cos(a);
double sna = sin(a);
double csb = cos(b);
double snb = sin(b);
float ax1 = cs1*csa;
float ay1 = cs1*sna;
float ax2 = cs2*csa;
float ay2 = cs2*sna;
float bx1 = cs1*csb;
float by1 = cs1*snb;
float bx2 = cs2*csb;
float by2 = cs2*snb;
{ Position3D p1(r*bx2,r*by2,r*sn2);
Position3D p2(r*ax2,r*ay2,r*sn2);
Position3D p3(r*ax1,r*ay1,r*sn1);
Direction3D n1(bx2,by2,sn2);
Direction3D n2(ax2,ay2,sn2);
Direction3D n3(ax1,ay1,sn1);
facette(&p1,&p2,&p3,&n1,&n2,&n3); }
{ Position3D p1(r*bx1,r*by1,r*sn1);
Position3D p2(r*bx2,r*by2,r*sn2);
Position3D p3(r*ax1,r*ay1,r*sn1);
Direction3D n1(bx1,by1,sn1);
Direction3D n2(bx2,by2,sn2);
Direction3D n3(ax1,ay1,sn1);
facette(&p1,&p2,&p3,&n1,&n2,&n3); } } }
}
void scene() {
Rotation *rtx = new Rotation(95.0*sin(rx),1.0,0.0,0.0);
Rotation *rty = new Rotation(95.0*sin(ry),0.0,1.0,0.0);
Rotation *rtz = new Rotation(rz,0.0,0.0,1.0);
TransformationGeometrique *tg = new TransformationGeometrique();
tg->produit(rtx,rty);
tg->produit(tg,rtz);
Position3D *pos = new Position3D(0.0,0.0,10.0);
tg->transforme(pos);
Couleur *jaunatre = new Couleur(1.0,1.0,1.0);
lp = new LumierePonctuelle(pos,70.0,jaunatre);
obs = new Position3D(0.0,0.0,20.0);
delete(pos);
delete(jaunatre);
delete(tg);
delete(rtx);
delete(rty);
delete(rtz);
glPushMatrix();
sphere(3.0,n,n);
glPopMatrix();
delete(obs);
delete(lp);
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin */
void display(void) {
glClearColor(0.5F,0.5F,0.5F,1.0F);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
scene();
glPopMatrix();
glFlush();
glutSwapBuffers();
int error = glGetError();
if ( error != GL_NO_ERROR )
printf("Erreur OpenGL\n",error);
}
/* Fonction executee lorsqu'aucun evenement */
/* n'est en file d'attente */
void idle(void) {
rx += 0.00311F ;
ry += 0.00634F ;
rz += 0.17174F ;
glutPostRedisplay() ;
}
/* Fonction executee lors d'un changement */
/* de la taille de la fenetre OpenGL */
void reshape(int x,int y) {
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION) ;
glLoadIdentity() ;
gluPerspective(25.0F,(float) x/y,15.0,35.0) ;
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;
gluLookAt(0.0,0.0,20.0,0.0,0.0,0.0,0.0,1.0,0.0);
}
/* Fonction executee lors de l'appui */
/* d'une touche alphanumerique du clavier */
void keyboard(unsigned char key,int x,int y) {
switch (key) {
case 43 :
n++;
glutPostRedisplay();
break;
case 45 :
n--;
if ( n == 2 )
n = 3;
glutPostRedisplay();
break;
case 'f' :
{ static int face = 1;
face = !face;
glPolygonMode(GL_FRONT_AND_BACK,( face ) ? GL_FILL : GL_LINE); }
glutPostRedisplay();
break;
case 0x20 :
lum = (lum+1)%3;
glutPostRedisplay();
break;
case 0x0D :
{ static int anim = 1;
anim = !anim;
glutIdleFunc(( anim ) ? idle : NULL); }
break;
case 0x1B :
exit(0);
break; }
}
/* Fonction executee lors de l'appui */
/* d'une touche de curseur ou d'une touche */
/* page up ou page down */
void special(int key,int x,int y) {
switch(key) {
case GLUT_KEY_UP :
rx++;
glutPostRedisplay() ;
break;
case GLUT_KEY_DOWN :
rx--;
glutPostRedisplay() ;
break;
case GLUT_KEY_LEFT :
ry++;
glutPostRedisplay() ;
break;
case GLUT_KEY_RIGHT :
ry--;
glutPostRedisplay() ;
break;
case GLUT_KEY_PAGE_UP :
rz++;
glutPostRedisplay() ;
break;
case GLUT_KEY_PAGE_DOWN :
rz--;
glutPostRedisplay() ;
break; }
}
/* Fonction principale */
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(300,300);
glutInitWindowPosition(50,50);
glutCreateWindow("Une sphere illuminee");
init();
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}