
    Vue extérieure correspondant au rayon primaire du pixel en bas à droite de l'image
    
    Vue extérieur d'une partie des rayons primaires
    
    Vue depuis l'observateur de la scène et du quadrillage des pixels
    Carré rouge : Pixel correspondant au rayon en cours de calcul 
    
     
 
    
    Augmentation de la résolution de l'image
/* Auteur: Nicolas JANEY             */
    /* nicolas.janey@univ-fcomte.fr      */
    /* Avril 2020                        */
    /* Illustration du lancer de rayons  */
    
    #include <GL/glut.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    
    #include <stdio.h>
    #include <math.h>
    
    #include "ModuleCouleurs.h"
    #include "ModuleManipulateur.h"
    #include "ModuleMenus.h"
    
    static int rayons = 0;
    static int aff = 0;
    static int visu = 0;
    static float ratio;
    static int resolution = 1;
    
    void myinit(void) {
      GLfloat light_position0[] = { 0.0F,0.0F,1.0F,0.0F };
      glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir());
      glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurGrisClair());
      glLightfv(GL_LIGHT0,GL_SPECULAR,couleurNoir());
      glLightfv(GL_LIGHT0,GL_POSITION,light_position0);
      glEnable(GL_LIGHT0);
      glEnable(GL_AUTO_NORMAL);
      glEnable(GL_NORMALIZE);
      glEnable(GL_DEPTH_TEST);
      glDepthFunc(GL_LESS);
      glEnable(GL_ALPHA_TEST);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
      setManipulateurClavierAngle(0.0F,135.0F,3.0F);
      glClearColor(0.3F,0.3F,0.3F,1.0F);
    }
    
    void displayObjets(void) {
      float x,y;
      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
      glPushMatrix();
      if ( !visu ) {
        manipulateurSouris();
        manipulateurClavier(); }
      glPushMatrix();
      glLineWidth(3.0F);
      glColor4fv(couleurBlanc());
      glBegin(GL_LINE_LOOP);
      glVertex3f(-4.0F,-3.0F,0.0F);
      glVertex3f(-4.0F,3.0F,0.0F);
      glVertex3f(4.0F,3.0F,0.0F);
      glVertex3f(4.0F,-3.0F,0.0F);
      glEnd();
      glLineWidth(1.0F);
      glBegin(GL_LINES);
      for ( x = -4.0F ; x < 4.0F ; x += 1.0F/resolution ) {
        glVertex3f(x,-3.0F,0.0F);
        glVertex3f(x,3.0F,0.0F); } 
      for ( y = -3.0F ; y < 3.0F ; y += 1.0F/resolution ) {
        glVertex3f(-4.0F,y,0.0F);
        glVertex3f(4.0F,y,0.0F); } 
      if ( aff == 0 )
        for ( int i = 0 ; i <= rayons ; i++ ) {
          x = -4.0F+0.5F/resolution+(i%(8*resolution))/(float) resolution;
          y = -3.0F+0.5F/resolution+(i/(8*resolution))/(float) resolution;
          glVertex3f(3*x,3*y,16.0F);
          glVertex3f(0.0F,0.0F,-8.0F); }
        else {
        x = -4.0F+0.5F/resolution+(rayons%(8*resolution))/(float) resolution;
        y = -3.0F+0.5F/resolution+(rayons/(8*resolution))/(float) resolution;
        glVertex3f(3*x,3*y,16.0F);
        glVertex3f(0.0F,0.0F,-8.0F); }
      glEnd();
      glPopMatrix();
      glEnable(GL_LIGHTING);
      glPushMatrix();
      glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurVert());
      glTranslatef(3.2F,-2.0F,7.0F);
      glutSolidSphere(2.3,36,36);
      glPopMatrix();
      glPushMatrix();
      glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurBleu());
      glTranslatef(-3.7F,2.5F,6.0F);
      glRotatef(-45.0F,1.0F,1.0F,1.0F);
      glScalef(4.2F,3.6F,2.3F);
      glutSolidCube(1.0);
      glPopMatrix();
      glPushMatrix();
      glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurJaune());
      glTranslatef(-3.9F,-2.1F,4.0F);
      glScalef(0.8F,1.0F,1.5F);
      glRotatef(45.0F,1.0F,1.0F,1.0F);
      glutSolidTorus(0.8,1.5,36,36);
      glPopMatrix();
      glDisable(GL_LIGHTING);
      glPushMatrix();
      glColor4fv(couleurRouge(0.5F));
      glBegin(GL_QUADS);
      x = -4.0F+0.5F/resolution+(rayons%(8*resolution))/(float) resolution;
      y = -3.0F+0.5F/resolution+(rayons/(8*resolution))/(float) resolution;
      glVertex3f(x-0.5F/resolution,y-0.5F/resolution,0.0F);
      glVertex3f(x+0.5F/resolution,y-0.5F/resolution,0.0F);
      glVertex3f(x+0.5F/resolution,y+0.5F/resolution,0.0F);
      glVertex3f(x-0.5F/resolution,y+0.5F/resolution,0.0F);
      glEnd();
      glPopMatrix();
      glPopMatrix();
    }
    
    void display(void) {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      if ( visu ) {
        glFrustum(-4.0,4.0,-4.0*ratio,4.0*ratio,8.0,125.0);
        setManipulateurDistance(10.0F); }
        else {
        glOrtho(-10.0,10.0,-ratio*10.0,ratio*10.0,0.0,25.0);
        setManipulateurDistance(10.0F); }
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      if ( visu ) {
        glRotatef(180.0F,0.0F,1.0F,0.0F);
        glTranslatef(0.0F,0.0F,8.0F); }
        else
        glTranslatef(0.0F,0.0F,-12.0F);
      glPushMatrix();
      glEnable(GL_DEPTH_TEST);
      displayObjets();
      glPopMatrix();
      glFlush();
      glutSwapBuffers();
    }
    
    void reshape(int w,int h) {
      glViewport(0,0,w,h);
      ratio =(float) h/w;
    }
    
    void key(unsigned char key,int x,int y) {
      if ( keyManipulateur(key,x,y) )
        glutPostRedisplay();
        else
        switch ( key ) {
          case 43    : resolution *= 2;
                       if ( resolution > 16 )
                         resolution = 16;
                       rayons = 0;
                       glutPostRedisplay();
                       break;
          case 45    : resolution /= 2;
                       if ( resolution < 1 )
                         resolution = 1;
                       rayons = 0;
                       glutPostRedisplay();
                       break;
          case 'm'   : visu = (visu+1)%2;
                       glutPostRedisplay();
                       break;
          case 0x0D  : aff = (aff+1)%2;
                       glutPostRedisplay();
                       break;
          case 32    : rayons = (rayons+1)%(48*resolution*resolution);
                       glutPostRedisplay();
                       break; }
    }
    
    int main(int argc,char **argv) {
      glutInit(&argc,argv);
      glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
      glutInitWindowSize(400,300); 
      glutInitWindowPosition(50,50); 
      glutCreateWindow("Le lancer de rayons"); 
      myinit(); 
      creationMenuBasique();
      glutKeyboardFunc(key);
      glutSpecialFunc(specialBasique);
      glutMotionFunc(motionBasique);
      glutMouseFunc(sourisBasique);
      glutReshapeFunc(reshape);
      glutDisplayFunc(display);
      glutMainLoop();
      return(0);
    }