Facettes monolithique et subdivisée
Eclairages: Diffusion + réflexion spéculaire, diffusion uniquement, réflexion spéculaire uniquement
Programme principal : IlluminationsGL.cpp
/* Une facette 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 obj = 0;
static int lum = 0;
static float rx = 0.0F;
static float ry = 0.0F;
static float rz = 0.0F;
static int n = 4;
static Rotation *rt = new Rotation();
/* 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) {
FacetteTriangulaire *fct = new FacetteTriangulaire(p1,p2,p3);
Couleur *kd;
Couleur *kr;
switch ( lum ) {
case 0 :
kd = new Couleur(1.0,0.2,0.2);
kr = new Couleur(0.0,0.8,0.8);
break;
case 1 :
kd = new Couleur(1.0,0.2,0.2);
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; }
Position3D *pos = new Position3D(4.2,0.3,0.5);
Couleur *jaunatre = new Couleur(1.0,1.0,1.0);
LumierePonctuelle *lp = new LumierePonctuelle(pos,10.0,jaunatre);
Position3D *obs = new Position3D(0.0,0.0,20.0);
Energie *e1 = new Energie();
Energie *e2 = new Energie();
Energie *e3 = new Energie();
{ Energie *ed1 = new Energie();
ed1->calculDiffusion(p1,fct,kd,lp);
Energie *er1 = new Energie();
er1->calculReflexionSpeculaire(p1,fct,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,fct,kd,lp);
Energie *er2 = new Energie();
er2->calculReflexionSpeculaire(p2,fct,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,fct,kd,lp);
Energie *er3 = new Energie();
er3->calculReflexionSpeculaire(p3,fct,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(obs);
delete(pos);
delete(jaunatre);
delete(lp);
delete(kd);
delete(kr);
delete(fct);
}
void facetteSimple(void) {
Position3D *p1 = new Position3D(3.0,-1.0,0.0);
Position3D *p2 = new Position3D(-1.0,3.0,1.0);
Position3D *p3 = new Position3D(-3.0,-3.0,-1.0);
p1->transforme(rt);
p2->transforme(rt);
p3->transforme(rt);
facette(p1,p2,p3);
delete(p3);
delete(p2);
delete(p1);
}
void subdivisionRecursive(Position3D *p1,Position3D *p2,Position3D *p3,int n) {
if ( n == 0 )
facette(p1,p2,p3);
else {
Position3D *p12 = new Position3D((p1->c[0]+p2->c[0])/2.0,
(p1->c[1]+p2->c[1])/2.0,
(p1->c[2]+p2->c[2])/2.0);
Position3D *p23 = new Position3D((p3->c[0]+p2->c[0])/2.0,
(p3->c[1]+p2->c[1])/2.0,
(p3->c[2]+p2->c[2])/2.0);
Position3D *p31 = new Position3D((p3->c[0]+p1->c[0])/2.0,
(p3->c[1]+p1->c[1])/2.0,
(p3->c[2]+p1->c[2])/2.0);
subdivisionRecursive(p1,p12,p31,n-1);
subdivisionRecursive(p2,p23,p12,n-1);
subdivisionRecursive(p3,p31,p23,n-1);
subdivisionRecursive(p23,p31,p12,n-1);
delete(p12);
delete(p23);
delete(p31); }
}
void facetteSubdivisee(void) {
Position3D *p1 = new Position3D(3.0,-1.0,0.0);
Position3D *p2 = new Position3D(-1.0,3.0,1.0);
Position3D *p3 = new Position3D(-3.0,-3.0,-1.0);
p1->transforme(rt);
p2->transforme(rt);
p3->transforme(rt);
subdivisionRecursive(p1,p2,p3,n);
delete(p1);
delete(p2);
delete(p3);
}
void scene() {
Rotation *rtx = new Rotation(35.0*cos(rx),1.0,0.0,0.0);
Rotation *rty = new Rotation(35.0*cos(ry),0.0,1.0,0.0);
Rotation *rtz = new Rotation(rz,0.0,0.0,1.0);
rt->produit(rtx,rty);
rt->produit(rt,rtz);
glPushMatrix();
switch ( obj ) {
case 0 :
facetteSimple();
break;
case 1 :
facetteSubdivisee();
break; }
glPopMatrix();
delete(rtx);
delete(rty);
delete(rtz);
}
/* 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 == 0 )
n = 1;
glutPostRedisplay();
break;
case 'f' :
{ static int face = 1;
face = !face;
glPolygonMode(GL_FRONT_AND_BACK,( face ) ? GL_FILL : GL_LINE); }
glutPostRedisplay();
break;
case 0x20 :
obj = (obj+1)%2;
glutPostRedisplay();
break;
case 'l' :
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 facette illuminee");
init();
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}