L'exécutable

Eclairage en blanc d'un objet avec réflexion diffuse dans le rouge et réflexion spéculaire dans le blanc

Lumières ponctuelles

Lumières directionnelles

Spots

Le source: Lights.cpp

/* Auteur: Nicolas JANEY                   */
/* nicolas.janey@univ-fcomte.fr            */
/* Octobre 2008                            */
/* Typologie des lumieres                  */

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

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

#include "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"

#ifndef M_PI
#define M_PI 3.14159
#endif

static int disc = 200;
static int fill = 1;
static int type = 0;
static GLfloat l_pos[] = { 0.0,0.0,6.0,1.0 };
static GLfloat l_dir[] = { 0.0,0.0,1.0,0.0 };
static int attenuation = 0;
static float ouverture = 30.0F;
static float spotDir[] = { 0.0F,0.0F,-1.0F };
static float shininess = 100.0F;
static int obj = 0;
static int mode = 0;

static const GLfloat blanc[] = { 1.0,1.0,1.0,1.0 };
static const GLfloat rouge[] = { 1.0,0.0,0.0,1.0 };
static const GLfloat noir[] = { 0.0,0.0,0.0,1.0 };
static const GLfloat gris[] = { 0.7,0.7,0.7,1.0 };

typedef struct Position {
  float x ;
  float y ;
  float z ; } Position ;

void dessineFacette(Position *p1,Position *p2,Position *p4,int disc) {
  float dx1 = (p2->x-p1->x)/disc;
  float dy1 = (p2->y-p1->y)/disc;
  float dz1 = (p2->z-p1->z)/disc;
  float dx2 = (p4->x-p1->x)/disc;
  float dy2 = (p4->y-p1->y)/disc;
  float dz2 = (p4->z-p1->z)/disc;
  glNormal3f(0.0F,0.0F,1.0F);
  glBegin(GL_QUADS);
  for ( int i = 0 ; i < disc ; i++ )
    for ( int j = 0 ; j < disc ; j++ ) {
      Position pp1 = { p1->x+i*dx1+j*dx2,
                       p1->y+i*dy1+j*dy2,
                       p1->z+i*dz1+j*dz2};
      Position pp2 = { pp1.x+dx1,pp1.y+dy1,pp1.z+dz1 };
      Position pp3 = { pp1.x+dx1+dx2,pp1.y+dy1+dy2,pp1.z+dz1+dz2 };
      Position pp4 = { pp1.x+dx2,pp1.y+dy2,pp1.z+dz2 };
      glVertex3fv((float *) &pp1);
      glVertex3fv((float *) &pp2);
      glVertex3fv((float *) &pp3);
      glVertex3fv((float *) &pp4); }
  glEnd();
}

void displayLumierePonctuelle(void) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glPolygonMode(GL_FRONT_AND_BACK,(fill) ? GL_FILL : GL_LINE);
  manipulateurSouris();
  manipulateurClavier();
  glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess);
  switch ( mode ) {
    case 0 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
      break;
    case 1 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,noir);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
      break;
    case 2 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,noir);
      break;
    case 3 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,noir);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,noir);
      break; }
  glRotatef(-50.0F,1.0F,0.0F,0.0F);
  glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
  glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,180.0F);
  switch ( attenuation ) {
    case 0 :
      glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.0F);
      glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F);
      break;
    case 1 :
      glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,1.0F);
      glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F);
      break;
    case 2 :
      glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.0F);
      break; }
  Position p1 = { -8.0F,-8.0F,0.0F } ;
  Position p2 = {  8.0F,-8.0F,0.0F } ;
  Position p3 = { -8.0F, 8.0F,0.0F } ;
  glEnable(GL_LIGHTING);
  switch ( obj ) {
    case 0 :
      dessineFacette(&p1,&p2,&p3,disc);
      break;
    case 1 :
      glutSolidTorus(2.0F,6.0F,disc,disc);
      break; }
  glTranslatef(l_pos[0],l_pos[1],l_pos[2]);
  glColor4fv(blanc);
  glDisable(GL_LIGHTING);
  glutSolidSphere(0.3F,36,36);
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur : %d\n",error);
}

void displayLumiereDirectionnelle(void) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glPolygonMode(GL_FRONT_AND_BACK,(fill) ? GL_FILL : GL_LINE);
  manipulateurSouris();
  manipulateurClavier();
  glRotatef(-50.0F,1.0F,0.0F,0.0F);
  glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess);
  switch ( mode ) {
    case 0 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
      break;
    case 1 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,noir);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
      break;
    case 2 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,noir);
      break;
    case 3 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,noir);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,noir);
      break; }
  glLightfv(GL_LIGHT0,GL_POSITION,l_dir);
  Position p1 = { -8.0F,-8.0F,0.0F } ;
  Position p2 = {  8.0F,-8.0F,0.0F } ;
  Position p3 = { -8.0F, 8.0F,0.0F } ;
  glEnable(GL_LIGHTING);
  switch ( obj ) {
    case 0 :
      dessineFacette(&p1,&p2,&p3,disc);
      break;
    case 1 :
      glutSolidTorus(2.0F,6.0F,disc,disc);
      break; }
  glTranslatef(0.0F,0.0F,7.0F);
  glColor4fv(blanc);
  glDisable(GL_LIGHTING);
  glutSolidSphere(0.2F,36,36);
  glBegin(GL_LINES);
  glVertex3f(0.0F,0.0F,0.0F);
  glVertex3f(-5.0F*l_dir[0],-5.0F*l_dir[1],-5.0F*l_dir[2]);
  glEnd();
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur : %d\n",error);
}

static void dessineCone(float *dir,float ouverture,int n) {
  if ( dir[2] != -1.0F ) {
    if ( dir[2] == 1.0F )
      glRotatef(180.0F,1.0F,0.0F,0.0F);
      else {
      float angle =(float) (acos(-dir[2])*180.0/3.14159);
      glRotatef(-angle,-dir[1],dir[0],0.0F); } }
  ouverture = ouverture/180.0*M_PI;
  float dx =(float) (4.0*sin(ouverture));
  float dz =(float) (-4.0*cos(ouverture));
  for ( int i = 0 ; i < n ; i++ ) {
    glPushMatrix();
    float angle = i*360.0F/n;
    glRotatef(angle,0.0F,0.0F,1.0F);
    glBegin(GL_LINES);
    glVertex3f(0.0F,0.0F,0.0F);
    glVertex3f(dx,0.0F,dz);
    glEnd();
    glPopMatrix(); }
}

void displayLumiereSpot(void) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glPolygonMode(GL_FRONT_AND_BACK,(fill) ? GL_FILL : GL_LINE);
  manipulateurSouris();
  manipulateurClavier();
  glRotatef(-50.0F,1.0F,0.0F,0.0F);
  glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess);
  switch ( mode ) {
    case 0 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
      break;
    case 1 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,noir);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
      break;
    case 2 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,blanc);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,noir);
      break;
    case 3 :
      glLightfv(GL_LIGHT0,GL_SPECULAR,noir);
      glLightfv(GL_LIGHT0,GL_DIFFUSE,noir);
      break; }
  glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
  glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,ouverture);
  glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spotDir);
  switch ( attenuation ) {
    case 0 :
      glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.0F);
      glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F);
      break;
    case 1 :
      glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,1.0F);
      glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0F);
      break;
    case 2 :
      glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0F);
      glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,1.0F);
      break; }
  Position p1 = { -8.0F,-8.0F,0.0F } ;
  Position p2 = {  8.0F,-8.0F,0.0F } ;
  Position p3 = { -8.0F, 8.0F,0.0F } ;
  glEnable(GL_LIGHTING);
  switch ( obj ) {
    case 0 :
      dessineFacette(&p1,&p2,&p3,disc);
      break;
    case 1 :
      glutSolidTorus(2.0F,6.0F,disc,disc);
      break; }
  glTranslatef(l_pos[0],l_pos[1],l_pos[2]);
  glColor4fv(blanc);
  glDisable(GL_LIGHTING);
  glutSolidSphere(0.3F,36,36);
  glBegin(GL_LINES);
  glVertex3f(0.0F,0.0F,0.0F);
  glVertex3f(5.0F*spotDir[0],5.0F*spotDir[1],5.0F*spotDir[2]);
  glEnd();
  glColor4fv(gris);
  dessineCone(spotDir,ouverture,9);
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur : %d\n",error);
}

void myinit (void) {
  glClearColor(0.75,0.75,0.95,1.0) ;
  glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,rouge);
  glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,blanc);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glDepthFunc(GL_LESS);
  glEnable(GL_DEPTH_TEST);
  glShadeModel(GL_SMOOTH);
}

static void rotateX(float *v,float ax) {
  ax = ax/180.0F*M_PI;
  float cs =(float) cos(ax);
  float sn =(float) sin(ax);
  float m[3][3] = { { 1.0F,0.0F,0.0F },
                    { 0.0F,  cs, -sn },
                    { 0.0F,  sn,  cs } };
  float nv[3];
  for ( int i = 0 ; i < 3 ; i++ ) {
    nv[i] = 0.0F;
    for ( int j = 0 ; j < 3 ; j++ )
      nv[i] += m[i][j]*v[j]; }
  for ( int i = 0 ; i < 3 ; i++ )
    v[i] = nv[i];
}

static void rotateY(float *v,float ay) {
  ay = ay/180.0F*M_PI;
  float cs =(float) cos(ay);
  float sn =(float) sin(ay);
  float m[3][3] = { {   cs,0.0F,  sn },
                    { 0.0F,1.0F,0.0F },
                    {  -sn,0.0F,  cs } };
  float nv[3];
  for ( int i = 0 ; i < 3 ; i++ ) {
    nv[i] = 0.0F;
    for ( int j = 0 ; j < 3 ; j++ )
      nv[i] += m[i][j]*v[j]; }
  for ( int i = 0 ; i < 3 ; i++ )
    v[i] = nv[i];
}

static void rotateZ(float *v,float az) {
  az = az/180.0F*M_PI;
  float cs =(float) cos(az);
  float sn =(float) sin(az);
  float m[3][3] = { {   cs, -sn,0.0F },
                    {   sn,  cs,0.0F },
                    { 0.0F,0.0F,1.0F } };
  float nv[3];
  for ( int i = 0 ; i < 3 ; i++ ) {
    nv[i] = 0.0F;
    for ( int j = 0 ; j < 3 ; j++ )
      nv[i] += m[i][j]*v[j]; }
  for ( int i = 0 ; i < 3 ; i++ )
    v[i] = nv[i];
}

void key(unsigned char key,int x,int y) {
  switch ( key ) {
    case 'm' :
    case 'M' :
      mode = (mode+1)%4;
      glutPostRedisplay();
      break;
    case 'a' :
    case 'A' :
      obj = (obj+1)%2;
      glutPostRedisplay();
      break;
    case 'o' :
      if ( type == 2 ) {
        ouverture -= 0.2F;
        if ( ouverture < 0.0F )
          ouverture = 0.0F;
          else
          glutPostRedisplay(); }
      break;
    case 'O' :
      if ( type == 2 ) {
        ouverture += 0.2F;
        if ( ouverture > 90.0F )
          ouverture = 90.0F;
          else
          glutPostRedisplay(); }
      break;
    case '1' :
      switch ( type ) {
        case 1 :
          rotateX(l_dir,1.0F);
          glutPostRedisplay();
          break;
        case 2 :
          rotateX(spotDir,1.0F);
          glutPostRedisplay();
          break; }
      break;
    case '4' :
      switch ( type ) {
        case 1 :
          rotateX(l_dir,-1.0F);
          glutPostRedisplay();
          break;
        case 2 :
          rotateX(spotDir,-1.0F);
          glutPostRedisplay();
          break; }
      break;
    case '2' :
      switch ( type ) {
        case 1 :
          rotateY(l_dir,1.0F);
          glutPostRedisplay();
          break;
        case 2 :
          rotateY(spotDir,1.0F);
          glutPostRedisplay();
          break; }
      break;
    case '5' :
      switch ( type ) {
        case 1 :
          rotateY(l_dir,-1.0F);
          glutPostRedisplay();
          break;
        case 2 :
          rotateY(spotDir,-1.0F);
          glutPostRedisplay();
          break; }
    case '3' :
      switch ( type ) {
        case 1 :
          rotateZ(l_dir,1.0F);
          glutPostRedisplay();
          break;
        case 2 :
          rotateZ(spotDir,1.0F);
          glutPostRedisplay();
          break; }
      break;
    case '6' :
      switch ( type ) {
        case 1 :
          rotateZ(l_dir,-1.0F);
          glutPostRedisplay();
          break;
        case 2 :
          rotateZ(spotDir,-1.0F);
          glutPostRedisplay();
          break; }
      break;
    case 'x' :
      switch ( type ) {
        case 0 :
        case 2 :
          l_pos[0] -= 0.1F;
          glutPostRedisplay();
          break; }
      break;
    case 'X' :
      switch ( type ) {
        case 0 :
        case 2 :
          l_pos[0] += 0.1F;
          glutPostRedisplay();
          break; }
      break;
    case 'y' :
      switch ( type ) {
        case 0 :
        case 2 :
          l_pos[1] -= 0.1F;
          glutPostRedisplay();
          break; }
      break;
    case 'Y' :
      switch ( type ) {
        case 0 :
        case 2 :
          l_pos[1] += 0.1F;
          glutPostRedisplay();
          break; }
      break;
    case 'z' :
      switch ( type ) {
        case 0 :
        case 2 :
          l_pos[2] -= 0.1F;
          glutPostRedisplay();
          break; }
      break;
    case 'Z' :
      switch ( type ) {
        case 0 :
        case 2 :
          l_pos[2] += 0.1F;
          glutPostRedisplay();
          break; }
      break;
    case 0x0D :
      type =(type+1)%3;
      switch ( type ) {
        case 0 :
          glutDisplayFunc(displayLumierePonctuelle);
          glutPostRedisplay();
          break;
        case 1 :
          glutDisplayFunc(displayLumiereDirectionnelle);
          glutPostRedisplay();
          break;
        case 2 :
          glutDisplayFunc(displayLumiereSpot);
          glutPostRedisplay();
          break; }
      break;
    case ' ' :
      if ( ( type == 0 ) || ( type == 2 ) ) {
        attenuation = (attenuation+1)%3;
        glutPostRedisplay(); }
      break;
    case 'F' :
    case 'f' :
      fill = !fill;
      glutPostRedisplay();
      break;
    case 's' :
      shininess += 1.0F;
      if ( shininess > 128.0F )
        shininess = 128.0F;
      glutPostRedisplay();
      break;
    case 'S' :
      shininess -= 1.0F;
      if ( shininess < 0.0F )
        shininess = 0.0F;
      glutPostRedisplay();
      break;
    case 43 : 
      disc++;
      glutPostRedisplay();
      break;
    case 45 :
      disc--;
      if ( disc < 3 )
        disc = 3;
      glutPostRedisplay();
      break;
    case 0x1B :
      exit(0); }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(220,200); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Typologie des lumières"); 
  myinit(); 
  creationMenuBasique();
  setParametresPerspectiveBasique(35.0F,1.5F,1.0F,30.0F,0.0F,0.0F,-20.0F);
  setManipulateurDistance(20.0F);
  glutReshapeFunc(reshapePerspectiveBasique);
  glutKeyboardFunc(key);
  glutSpecialFunc(specialBasique);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutIdleFunc(idleBasique);
  glutDisplayFunc(displayLumierePonctuelle);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR