L'exécutable

Le source: SchemaPhong.cpp

/* Auteur: Nicolas JANEY                 */
/* nicolas.janey@univ-fcomte.fr          */
/* Decembre 2001                         */
/* Schema pour un calcul d'illumination  */
/* de Phong                              */

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

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

#include "ModuleCouleurs.h"
#include "ModuleFont.h"
#include "ModuleManipulateur.h"
#include "ModuleMatriceVecteur.h"
#include "ModuleMenus.h"
#include "ModuleFleche.h"
#include "ModuleReshape.h"

typedef float couleur[4];

struct facette3 {
  vecteur pa;
  vecteur na;
  vecteur pb;
  vecteur nb;
  vecteur pc;
  vecteur nc; } ;

static float px1;
static float pz1;
static float px2;
static float pz2;
static float px;
static float pz;
static float h1;
static float h2;
static vecteur n1;
static vecteur n2;
static vecteur n;
static int f1;
static int f2;
static int disc = 0;
static int fleches = 0;
static float posx = 0.5F;
static float posy = 0.0F;
static int mode = 0;
static facette3 f = { { 0.05F,0.8F,0.0F },
                      { 0.660303F,0.063246F,0.748331F },
                      { -0.55F,-0.2F,0.0F },
                      { -0.1F,0.547722F,0.774597F },
                      { 0.85F,-0.75F,0.0F } ,
                      { -0.593296F,-0.089442F,0.8F } };
static GLfloat l_pos[] = { -1.5F,0.0F,1.0F,0.0F };

void myinit(void) {
  glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
  glEnable(GL_LIGHT0);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);
  glClearColor(0.7F,0.7F,0.8F,1.0F) ;
  glDepthFunc(GL_LESS);
}

int intersection(vecteur pi,vecteur pf,vecteur ni,vecteur nf,float y,float *x,float *z,vecteur nn,float *h) {
  if ( ( y > pi[1] ) || ( y < pf[1] ) )
    return(0);
  float fact = (y-pf[1])/(pi[1]-pf[1]);
  *h = 1.0F-fact;
  *x = pf[0] + fact*(pi[0]-pf[0]);
  *z = pf[2] + fact*(pi[2]-pf[2]);
  nn[0] = nf[0] + fact*(ni[0]-nf[0]);
  nn[1] = nf[1] + fact*(ni[1]-nf[1]);
  nn[2] = nf[2] + fact*(ni[2]-nf[2]);
  normalise(nn);
  return(1);
}

void evaluationIntersections(void) {
  if ( intersection(f.pa,f.pb,f.na,f.nb,posy,&px1,&pz1,n1,&h1) ) {
    if ( !intersection(f.pa,f.pc,f.na,f.nc,posy,&px2,&pz2,n2,&h2) )
      intersection(f.pb,f.pc,f.nb,f.nc,posy,&px2,&pz2,n2,&h2); }
    else {
    intersection(f.pa,f.pc,f.na,f.nc,posy,&px2,&pz2,n2,&h2);
    intersection(f.pb,f.pc,f.nb,f.nc,posy,&px1,&pz1,n1,&h1); }
  px = px1 + posx*(px2-px1);
  pz = pz1 + posx*(pz2-pz1);
  n[0] = n1[0] + posx*(n2[0]-n1[0]);
  n[1] = n1[1] + posx*(n2[1]-n1[1]);
  n[2] = n1[2] + posx*(n2[2]-n1[2]);
  normalise(n);
}

void copie(vecteur a,vecteur b) {
  a[0] = b[0];
  a[1] = b[1];
  a[2] = b[2];
  a[3] = b[3];
}

void positionIntermediaire(vecteur a,vecteur b,vecteur i) {
  i[0] = (a[0]+b[0])/2.0F;
  i[1] = (a[1]+b[1])/2.0F;
  i[2] = (a[2]+b[2])/2.0F;
}

void normaleIntermediaire(vecteur a,vecteur b,vecteur i) {
  i[0] = (a[0]+b[0]);
  i[1] = (a[1]+b[1]);
  i[2] = (a[2]+b[2]);
  normalise(i);
}

void dessineFacetteTriangulairePhong(facette3 *f,vecteur l_pos,int disc) {
  if ( disc == 0 ) {
    float facta = produitScalaire(f->na,l_pos);
    float factb = produitScalaire(f->nb,l_pos);
    float factc = produitScalaire(f->nc,l_pos);
    if ( fleches ) {
      glEnable(GL_LIGHTING);
      glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurGrisMoyen());
      glPushMatrix();
      glTranslatef(f->pa[0],f->pa[1],f->pa[2]);
      flecheEnVolume(f->na[0]/3.0F,f->na[1]/3.0F,f->na[2]/3.0F,0.01F,0.06F,0.004F);
      glPopMatrix();
      glPushMatrix();
      glTranslatef(f->pb[0],f->pb[1],f->pb[2]);
      flecheEnVolume(f->nb[0]/3.0F,f->nb[1]/3.0F,f->nb[2]/3.0F,0.01F,0.06F,0.004F);
      glPopMatrix();
      glPushMatrix();
      glTranslatef(f->pc[0],f->pc[1],f->pc[2]);
      flecheEnVolume(f->nc[0]/3.0F,f->nc[1]/3.0F,f->nc[2]/3.0F,0.01F,0.06F,0.004F);
      glPopMatrix();
      glDisable(GL_LIGHTING); }
    glBegin(GL_POLYGON);
    glColor3f(facta,facta,facta);
    glVertex3fv(f->pa);
    glColor3f(factb,factb,factb);
    glVertex3fv(f->pb);
    glColor3f(factc,factc,factc);
    glVertex3fv(f->pc);
    glEnd();}
    else {
    facette3 f1;
    facette3 f2;
    facette3 f3;
    facette3 f4;
    vecteur pab;
    vecteur nab;
    vecteur pac;
    vecteur nac;
    vecteur pbc;
    vecteur nbc;
    positionIntermediaire(f->pa,f->pb,pab);
    positionIntermediaire(f->pa,f->pc,pac);
    positionIntermediaire(f->pb,f->pc,pbc);
    normaleIntermediaire(f->na,f->nb,nab);
    normaleIntermediaire(f->na,f->nc,nac);
    normaleIntermediaire(f->nb,f->nc,nbc);
    copie(f1.pa,f->pa);
    copie(f1.na,f->na);
    copie(f1.pb,pab);
    copie(f1.nb,nab);
    copie(f1.pc,pac);
    copie(f1.nc,nac);
    copie(f2.pa,f->pb);
    copie(f2.na,f->nb);
    copie(f2.pb,pab);
    copie(f2.nb,nab);
    copie(f2.pc,pbc);
    copie(f2.nc,nbc);
    copie(f3.pa,f->pc);
    copie(f3.na,f->nc);
    copie(f3.pb,pac);
    copie(f3.nb,nac);
    copie(f3.pc,pbc);
    copie(f3.nc,nbc);
    copie(f4.pa,pab);
    copie(f4.na,nab);
    copie(f4.pb,pac);
    copie(f4.nb,nac);
    copie(f4.pc,pbc);
    copie(f4.nc,nbc);
    dessineFacetteTriangulairePhong(&f1,l_pos,disc-1);
    dessineFacetteTriangulairePhong(&f2,l_pos,disc-1);
    dessineFacetteTriangulairePhong(&f3,l_pos,disc-1);
    dessineFacetteTriangulairePhong(&f4,l_pos,disc-1); }
}

void display(void) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  manipulateurSouris();
  manipulateurClavier();
  glColor4fv(couleurGrisClair());
  glEnable(GL_DEPTH_TEST);
  switch (mode) {
    case 0 : glBegin(GL_POLYGON);
             glVertex3fv(f.pa);
             glVertex3fv(f.pb);
             glVertex3fv(f.pc);
             glEnd();
             break;
    case 1 : { float facta = produitScalaire(f.na,l_pos);
               float factb = produitScalaire(f.nb,l_pos);
               float factc = produitScalaire(f.nc,l_pos);
               glBegin(GL_POLYGON);
               glColor3f(facta,facta,facta);
               glVertex3fv(f.pa);
               glColor3f(factb,factb,factb);
               glVertex3fv(f.pb);
               glColor3f(factc,factc,factc);
               glVertex3fv(f.pc);
               glEnd(); }
             break;
    case 2 : dessineFacetteTriangulairePhong(&f,l_pos,disc) ;
             break; }
  glDisable(GL_DEPTH_TEST);
  glColor4fv(couleurNoir());
  glBegin(GL_LINES);
  glVertex3f(px1,posy,pz1);
  glVertex3f(px2,posy,pz2);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3fv(f.pa);
  glVertex3fv(f.pb);
  glVertex3fv(f.pc);
  glEnd();
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHTING);
  if ( posy > f.pb[1] ) { 
    glPushMatrix();
    glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurVert());
    glTranslatef(f.pa[0],f.pa[1],f.pa[2]);
    flecheEnVolume(px1-f.pa[0],posy-f.pa[1],pz1-f.pa[2],0.022F,0.1F,0.009F);
    glPopMatrix(); }
    else {
    glPushMatrix();
    glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurRouge());
    glTranslatef(f.pb[0],f.pb[1],f.pb[2]);
    flecheEnVolume(px1-f.pb[0],posy-f.pb[1],pz1-f.pb[2],0.022F,0.1F,0.009F);
    glPopMatrix(); }
  glPushMatrix();
  glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurBleu());
  glTranslatef(f.pa[0],f.pa[1],f.pa[2]);
  flecheEnVolume(px2-f.pa[0],posy-f.pa[1],pz2-f.pa[2],0.022F,0.1F,0.009F);
  glPopMatrix();
  glPushMatrix();
  glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurJaune());
  glTranslatef(px1,posy,pz1);
  flecheEnVolume(px-px1,0.0F,pz-pz1,0.022F,0.1F,0.009F);
  glPopMatrix();
  glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurGrisMoyen());
  glPushMatrix();
  glTranslatef(f.pa[0],f.pa[1],f.pa[2]);
  flecheEnVolume(f.na[0],f.na[1],f.na[2],0.025F,0.12F,0.009F);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(f.pb[0],f.pb[1],f.pb[2]);
  flecheEnVolume(f.nb[0],f.nb[1],f.nb[2],0.025F,0.12F,0.009F);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(f.pc[0],f.pc[1],f.pc[2]);
  flecheEnVolume(f.nc[0],f.nc[1],f.nc[2],0.025F,0.12F,0.009F);
  glPopMatrix();
  float fact1 = produitScalaire(n1,l_pos);
  float coul1[4] = { fact1,fact1,fact1 }; 
  glMaterialfv(GL_FRONT,GL_DIFFUSE,coul1);
  glPushMatrix();
  glTranslatef(px1,posy,pz1);
  glutSolidSphere(0.035F,10,10);
  flecheEnVolume(n1[0],n1[1],n1[2],0.025F,0.12F,0.009F);
  glPopMatrix();
  float fact2 = produitScalaire(n2,l_pos);
  float coul2[4] = { fact2,fact2,fact2 }; 
  glMaterialfv(GL_FRONT,GL_DIFFUSE,coul2);
  glPushMatrix();
  glTranslatef(px2,posy,pz2);
  glutSolidSphere(0.035F,10,10);
  flecheEnVolume(n2[0],n2[1],n2[2],0.025F,0.12F,0.009F);
  glPopMatrix();
  float fact = produitScalaire(n,l_pos);
  float coul[4] = { fact,fact,fact }; 
  glMaterialfv(GL_FRONT,GL_DIFFUSE,coul);
  glPushMatrix();
  glTranslatef(px,posy,pz);
  glutSolidSphere(0.035F,10,10);
  flecheEnVolume(n[0],n[1],n[2],0.025F,0.12F,0.009F);
  glPopMatrix();
  glDisable(GL_LIGHTING);
  glDisable(GL_DEPTH_TEST);
  glColor4fv(couleurBleu());
  setAlignement(RIGHT);
  if ( posy > f.pb[1] ) { 
    placeFontCursor((f.pa[0]+px1)/2.0F-0.05F,(f.pa[1]+posy)/2.0F,(f.pa[2]+pz1)/2.0F) ;
    simpleBitmapOutput(REGULAR8x13,"PaP1 = h1PaPb") ;
    deplacementCursor(-2,-5,0) ;
    simpleBitmapOutput(DESSIN,"TTTTF      TTTTF") ; }
    else {
    placeFontCursor((f.pb[0]+px1)/2.0F-0.05F,(f.pb[1]+posy)/2.0F,(f.pb[2]+pz1)/2.0F) ;
    simpleBitmapOutput(REGULAR8x13,"PbP1 = h1PbPc") ;
    deplacementCursor(-2,-5,0) ;
    simpleBitmapOutput(DESSIN,"TTTTF      TTTTF") ; }
  setAlignement(LEFT);
  placeFontCursor((f.pa[0]+px2)/2.0F+0.05F,(f.pa[1]+posy)/2.0F,(f.pa[2]+pz2)/2.0F) ;
  simpleBitmapOutput(REGULAR8x13,"PaP2 = h2PaPb") ;
  deplacementCursor(0,-5,0) ;
  simpleBitmapOutput(DESSIN,"TTTTF      TTTTF") ;
  setAlignement(CENTER);
  placeFontCursor(px,posy-0.1F,pz) ;
  simpleBitmapOutput(REGULAR8x13,"P1P = hP1P2") ;
  deplacementCursor(0,-5,0) ;
  simpleBitmapOutput(DESSIN,"TTTF     TTTTF") ;
  setAlignement(CENTER);
  placeFontCursor(f.pa[0]+0.05F,f.pa[1]+0.05F,f.pa[2]+0.05F) ;
  simpleBitmapOutput(REGULAR8x13,"Pa (Na)") ;
  deplacementCursor(-1,-5,0) ;
  simpleBitmapOutput(DESSIN,"    TTF") ;
  setAlignement(RIGHT);
  placeFontCursor(f.pb[0]-0.05F,f.pb[1],f.pb[2]+0.05F) ;
  simpleBitmapOutput(REGULAR8x13,"Pb (Nb)") ;
  deplacementCursor(0,-5,0) ;
  simpleBitmapOutput(DESSIN,"    TTF ") ;
  setAlignement(LEFT);
  placeFontCursor(f.pc[0]+0.05F,f.pc[1],f.pc[2]+0.05F) ;
  simpleBitmapOutput(REGULAR8x13,"Pc (Nc)") ;
  deplacementCursor(-3,-5,0) ;
  simpleBitmapOutput(DESSIN,"     TTF") ;
  setAlignement(CENTER);
  placeFontCursor(px1-0.1F,posy+0.1F,pz1+0.1F) ;
  simpleBitmapOutput(REGULAR8x13,"P1") ;
  placeFontCursor(px2+0.1F,posy+0.1F,pz2+0.1F) ;
  simpleBitmapOutput(REGULAR8x13,"P2") ;
  placeFontCursor(px+0.1F,posy+0.1F,pz+0.1F) ;
  simpleBitmapOutput(REGULAR8x13,"P") ;
  setAlignement(LEFT);
  glPopMatrix();
  glPushMatrix();
  placeFontCursor(-1.2F,-0.82F,0.1F) ;
  if ( posy > f.pb[1] ) { 
    simpleBitmapOutput(REGULAR8x13,"N1 = Na+h1(Nb-Na)") ; }
    else {
    simpleBitmapOutput(REGULAR8x13,"N1 = Nb+h1(Nc-Nb)") ; }
  deplacementCursor(-3,-5,0) ;
  simpleBitmapOutput(DESSIN,"TTF   TTF     TTF TTF") ;
  placeFontCursor(-1.2F,-0.95F,0.1F) ;
  simpleBitmapOutput(REGULAR8x13,"N2 = Na+h2(Nc-Na)") ;
  deplacementCursor(-3,-5,0) ;
  simpleBitmapOutput(DESSIN,"TTF   TTF     TTF TTF") ;
  placeFontCursor(0.4F,-0.95F,0.1F) ;
  simpleBitmapOutput(REGULAR8x13,"N = N1+h(N2-N1)") ;
  deplacementCursor(-3,-5,0) ;
  simpleBitmapOutput(DESSIN,"TF   TTF   TTF TTF") ;
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  glutPostWindowRedisplay(f2) ;
}

void special(int k,int x,int y) {
  if ( specialManipulateur(k,x,y) ) {
    glutPostWindowRedisplay(f1); }
}

void key2(unsigned char key,int x,int y) {
  switch ( key ) {
    case '4'  : posx -= 0.01F;
                if ( posx < 0.0F )
                  posx = 0.0F;
                evaluationIntersections();
                glutPostWindowRedisplay(f1) ;
                break ;
    case '6'  : posx += 0.01F;
                if ( posx > 1.0F )
                  posx = 1.0F;
                evaluationIntersections();
                glutPostWindowRedisplay(f1) ;
                break ;
    case 'd'  : disc++ ;
                glutPostWindowRedisplay(f1) ;
                break ;
    case 'D'  : disc-- ;
                if ( disc < 0 )
                  disc = 0;
                glutPostWindowRedisplay(f1) ;
                break ;
    case 43   : posy += 0.01F;
                if ( posy > f.pa[1] )
                  posy = f.pa[1];
                evaluationIntersections();
                glutPostWindowRedisplay(f1) ;
                break ;
    case 45   : posy -= 0.01F;
                if ( posy < f.pc[1] )
                  posy = f.pc[1];
                evaluationIntersections();
                glutPostWindowRedisplay(f1) ;
                break ;
    case ' '  : fleches = (fleches+1)%2 ;
                glutPostWindowRedisplay(f1) ;
                break ;
    case 0x0D : mode = (mode+1)%3 ;
                glutPostWindowRedisplay(f1) ;
                break ;
    case 0x1B : exit(0);
                break ; }
}

void key(unsigned char key,int x,int y) {
  if ( keyManipulateur(key,x,y) )
    glutPostWindowRedisplay(f1);
    else
    key2(key,x,y);
}

void reshape2(int w,int h) {
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,-h,0,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void display2() {
  glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  glClearColor(0.0F,0.0F,0.0F,1.0F) ;
  glPushAttrib(GL_LIGHTING);
  glDisable(GL_LIGHTING);
  glPushMatrix();
  glColor4fv(couleurBlanc());
  float pos = 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"PA : %6.3f %6.3f %6.3f",f.pa[0],f.pa[1],f.pa[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"PB : %6.3f %6.3f %6.3f",f.pb[0],f.pb[1],f.pb[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"PC : %6.3f %6.3f %6.3f",f.pc[0],f.pc[1],f.pc[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"NA : %6.3f %6.3f %6.3f",f.na[0],f.na[1],f.na[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"NB : %6.3f %6.3f %6.3f",f.nb[0],f.nb[1],f.nb[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"NC : %6.3f %6.3f %6.3f",f.nc[0],f.nc[1],f.nc[2]) ;
  glColor4fv(couleurBlanc());
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"h1 : %6.3f",h1) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"P1 : %6.3f %6.3f %6.3f",px1,posy,pz1) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"h2 : %6.3f",h2) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"P2 : %6.3f %6.3f %6.3f",px2,posy,pz2) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"h  : %6.3f",posx) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"P  : %6.3f %6.3f %6.3f",px,posy,pz) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"N1 : %6.3f %6.3f %6.3f",n1[0],n1[1],n1[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"N2 : %6.3f %6.3f %6.3f",n2[0],n2[1],n2[2]) ;
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
  simpleBitmapOutput(REGULAR8x13,"N  : %6.3f %6.3f %6.3f",n[0],n[1],n[2]) ;
  glPopMatrix();
  glPopAttrib();
  glutSwapBuffers();
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  normalise(l_pos);
  evaluationIntersections();
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(450,300); 
  glutInitWindowPosition(10,50); 
  f1 = glutCreateWindow("Schema Phong");
  myinit(); 
  creationMenuBasique();
  setParametresOrthoBasique(-1.0,1.0,-1.0,1.0,-5.0,5.0);
  setManipulateurDistance(1.0F);
  glutReshapeFunc(reshapeOrthoBasique);
  glutKeyboardFunc(key);
  glutSpecialFunc(special);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutDisplayFunc(display);
  glutInitWindowSize(260,310);
  glutInitWindowPosition(480,45);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  f2 = glutCreateWindow("Valeurs");
  creationMenuBasique();
  glutDisplayFunc(display2);
  glutReshapeFunc(reshape2);
  glutKeyboardFunc(key2);
  glutSpecialFunc(special);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR