L'exécutable

Le source : BouteilleDeKlein.cpp

/* Auteur: Nicolas JANEY         */
/* nicolas.janey@univ-fcomte.fr  */
/* Mars 2002                     */
/* Une bouteille de Klein        */

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

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

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

#define LI 64 
#define LH 64 

static GLubyte image[LI][LH][3]; 
static int npv = 20;
static int npu = 60;
static int aff = 0;
static int texture = 1;
static int light = 1;
static float **au;
static float **av;
static float **x;
static float **y;
static float **z;
static float **nx;
static float **ny;
static float **nz;

void makeImage(void) { 
  int i,j,c; 
  for( i = 0 ; i < LI ; i++ ) { 
    for( j = 0 ; j < LH ; j++ ) { 
      c =(((i&0x8)==0)^((j&0x8)==0))*255; 
      image[i][j][0] =(GLubyte) 255; 
      image[i][j][1] =(GLubyte) c; 
      image[i][j][2] =(GLubyte) c; } } 


void normalize(double *x,double *y,double *z) {
  double d =sqrt(*x**x+*y**y+*z**z);
  *x /= d;
  *y /= d;
  *z /= d;
}

void bouteilleDeKlein(void) {
  int i,j;
  glPushMatrix();
  switch ( aff ) {
    case 0 : glBegin(GL_POINTS);
             for ( i = 0 ; i < npu ; i++ )
               for ( j = 0 ; j < npv ; j++ ) {
                 glTexCoord2f(au[i][j],av[i][j]);
                 glNormal3f(nx[i][j],ny[i][j],nz[i][j]);
                 glVertex3f(x[i][j],y[i][j],z[i][j]); }
             glEnd();
             break;
    case 1 : for ( i = 0 ; i < npu ; i++ )
               for ( j = 0 ; j < npv ; j++ ) {
                 int i2 = i+1;
                 int j2 = j+1;
                 glBegin(GL_LINE_STRIP);
                 glTexCoord2f(au[i2][j],av[i2][j]);
                 glNormal3f(nx[i2][j],ny[i2][j],nz[i2][j]);
                 glVertex3f(x[i2][j],y[i2][j],z[i2][j]);
                 glTexCoord2f(au[i][j],av[i][j]);
                 glNormal3f(nx[i][j],ny[i][j],nz[i][j]);
                 glVertex3f(x[i][j],y[i][j],z[i][j]);
                 glTexCoord2f(au[i][j2],av[i][j2]);
                 glNormal3f(nx[i][j2],ny[i][j2],nz[i][j2]);
                 glVertex3f(x[i][j2],y[i][j2],z[i][j2]);
                 glEnd(); }
             break;
    case 2 : glBegin(GL_QUADS);
             for ( i = 0 ; i < npu ; i++ )
               for ( j = 0 ; j < npv ; j++ ) {
                 int i2 = i+1;
                 int j2 = j+1;
                 glTexCoord2f(au[i][j],av[i][j]);
                 glNormal3f(nx[i][j],ny[i][j],nz[i][j]);
                 glVertex3f(x[i][j],y[i][j],z[i][j]);
                 glTexCoord2f(au[i2][j],av[i2][j]);
                 glNormal3f(nx[i2][j],ny[i2][j],nz[i2][j]);
                 glVertex3f(x[i2][j],y[i2][j],z[i2][j]);
                 glTexCoord2f(au[i2][j2],av[i2][j2]);
                 glNormal3f(nx[i2][j2],ny[i2][j2],nz[i2][j2]);
                 glVertex3f(x[i2][j2],y[i2][j2],z[i2][j2]);
                 glTexCoord2f(au[i][j2],av[i][j2]);
                 glNormal3f(nx[i][j2],ny[i][j2],nz[i][j2]);
                 glVertex3f(x[i][j2],y[i][j2],z[i][j2]); }
             glEnd();
             break; }
  glPopMatrix();
}

void initBouteilleDeKlein(void) {
  int i,j;
  au =(float **) calloc(npu+1,sizeof(float *));
  av =(float **) calloc(npu+1,sizeof(float *));
  x =(float **) calloc(npu+1,sizeof(float *));
  y =(float **) calloc(npu+1,sizeof(float *));
  z =(float **) calloc(npu+1,sizeof(float *));
  nx =(float **) calloc(npu+1,sizeof(float *));
  ny =(float **) calloc(npu+1,sizeof(float *));
  nz =(float **) calloc(npu+1,sizeof(float *));
  for ( i = 0 ; i <= npu ; i++ ) {
    au[i] =(float *) calloc(npv+1,sizeof(float));
    av[i] =(float *) calloc(npv+1,sizeof(float));
    x[i] =(float *) calloc(npv+1,sizeof(float));
    y[i] =(float *) calloc(npv+1,sizeof(float));
    z[i] =(float *) calloc(npv+1,sizeof(float)); 
    nx[i] =(float *) calloc(npv+1,sizeof(float));
    ny[i] =(float *) calloc(npv+1,sizeof(float));
    nz[i] =(float *) calloc(npv+1,sizeof(float)); }
  for ( i = 0 ; i <= npu ; i++ ) {
    for ( j = 0 ; j <= npv ; j++ ) {
      double angu = i * 2 * 3.14159 / npu;
      double angv = j * 2 * 3.14159 / npv;
      au[i][j] = i * 4.75 / npu;
      av[i][j] = j * 4.75 / npv;
      double csu = cos(angu);
      double snu = sin(angu);
      double csv = cos(angv);
      double snv = sin(angv);
      double r = 4.0-csu*2.0;
      double dxdu;
      double dydu;
      double dzdu = 2.0*snv*snu;
      double dxdv;
      double dydv;
      double dzdv = 4.0*csv-2.0*csu*csv;
      if ( angu <= 3.14159 ) {
        x[i][j] = 6.0*csu*(1.0+snu)+r*csu*csv;
        y[i][j] = 16*snu+r*snu*csv;
        dxdu = -6.0*snu*(1.0+snu)+6.0*csu*csu-4.0*snu*csv+4.0*snu*csu*csv;
        dxdv = (-4.0+2.0*csu)*csu*snv;
        dydu = 16*csu+2.0*snu*snu+4.0*csu*(1.0-csu/2);
        dydv = -(4.0-2.0*csu)*snu*snv; }
        else {
        x[i][j] = 6.0*csu*(1.0+snu)-r*csv;
        y[i][j] = 16*snu;
        dxdu = -6.0*snu*(1.0+snu)+6.0*csu*csu+2.0*snu*csv;
        dxdv = 4.0*snv-2.0*csu*snv;
        dydu = 16*csu;
        dydv = 0.0; }
      z[i][j] = r*snv;
      normalize(&dxdu,&dydu,&dzdu);
      normalize(&dxdv,&dydv,&dzdv);
      nx[i][j] = dydu*dzdv-dydv*dzdu;
      ny[i][j] = dzdu*dxdv-dzdv*dxdu;
      nz[i][j] = dxdu*dydv-dxdv*dydu; } }
}

void detruitBouteilleDeKlein(void) {
  for ( int i = 0 ; i <= npu ; i++ ) {
    free(au[i]);
    free(av[i]);
    free(x[i]);
    free(y[i]);
    free(z[i]); 
    free(nx[i]);
    free(ny[i]);
    free(nz[i]); }
  free(au);
  free(av);
  free(x);
  free(y);
  free(z);
  free(nx);
  free(ny);
  free(nz);
}

void display(void) { 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  glPushMatrix();
  manipulateurSouris();
  manipulateurClavier();
  glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurBlanc());
  glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,couleurBlanc());
  glColor4fv(couleurBlanc());
  glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,50.0F);
  if ( texture )
    glEnable(GL_TEXTURE_2D); 
  if ( light )
    glEnable(GL_LIGHTING);
  bouteilleDeKlein();
  glDisable(GL_TEXTURE_2D); 
  glDisable(GL_LIGHTING);
  glPopMatrix();
  glFlush();
  glutSwapBuffers();


void myinit(void) { 
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
  glEnable(GL_DEPTH_TEST);
  makeImage(); 
  glTexImage2D(GL_TEXTURE_2D,0,3,LI,LH,0,GL_RGB,GL_UNSIGNED_BYTE,&image[0][0][0]); 
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 
  glClearColor(0.0,0.0,0.0,1.0); 
  glShadeModel(GL_SMOOTH); 
  glDepthFunc(GL_LESS);
  GLfloat l_pos[] = { 1.0,1.0,1.0,0.0 };
  glLightfv(GL_LIGHT0,GL_POSITION,l_pos);
  glEnable(GL_LIGHT0);
  glEnable(GL_NORMALIZE);

  
void key(unsigned char key,int x,int y) {
  if ( keyManipulateur(key,x,y) )
    glutPostRedisplay();
    else
    switch ( key ) {
      case 'u'    : detruitBouteilleDeKlein();
                    npu++;
                    initBouteilleDeKlein();
                    glutPostRedisplay();
                    break;
      case 'U'    : detruitBouteilleDeKlein();
                    npu--;
                    if ( npu < 6 )
                      npu = 6;
                    initBouteilleDeKlein();
                    glutPostRedisplay();
                    break;
      case 'v'    : detruitBouteilleDeKlein();
                    npv++;
                    initBouteilleDeKlein();
                    glutPostRedisplay();
                    break;
      case 'V'    : detruitBouteilleDeKlein();
                    npv--;
                    if ( npv < 6 )
                      npv = 6;
                    initBouteilleDeKlein();
                    glutPostRedisplay();
                    break;
      case ' '    : texture = 1-texture;
                    glutPostRedisplay();
                    break;
      case 'l'    : light = 1-light;
                    glutPostRedisplay();
                    break;
      case 0x0D   : aff = (aff+1)%3;
                    glutPostRedisplay();
                    break; }
}

int main(int argc,char **argv) {
  initBouteilleDeKlein();
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(450,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Bouteille de Klein"); 
  myinit(); 
  creationMenuBasique();
  setParametresOrthoBasique(-16.0,16.0,-16.0,16.0,-50.0,50.0);
  setManipulateurDistance(1.0F);
  glutReshapeFunc(reshapeOrthoBasique);
  glutKeyboardFunc(key);
  glutSpecialFunc(specialBasique);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutIdleFunc(idleBasique);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR