L'exécutable

ModeliseSphere01.gif (11488 octets) ModeliseSphere02.gif (14895 octets) ModeliseSphere03.gif (14652 octets)

Le source: ModeliseSphere.cpp

/* Auteur: Nicolas JANEY         */
/* nicolas.janey@univ-fcomte.fr  */
/* Decembre 2001                 */
/* Une sphere illuminee          */

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

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

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

static int aff = 0;
static int niv = 2;
static int disc1 = 10;
static int disc2 = 10;
static vecteur ldir = { 1.0F,1.0F,1.0F,1.0F };

void myinit(void) {
  glClearColor(0.5F,0.5F,0.8F,1.0F) ;
  glDepthFunc(GL_LESS);
  glEnable(GL_DEPTH_TEST);
  normalise(ldir);
}

vecteur **coordonnees(int n,int m) {
  vecteur **p =(vecteur **) calloc(n,sizeof(vecteur *));
  int i;
  for ( i = 0 ; i < n ; i++ ) 
    p[i] =(vecteur *) calloc(m,sizeof(vecteur));
  for ( i = 1 ; i <= n ;i++ ) {
    float a = -3.14159F/2.0F + i*3.14159/(n+1);
    float csa = cos(a);
    float sna = sin(a); 
    for ( int j = 0 ; j < m ;j++ ) {
      float b = j*3.14159F*2.0F/m;  
      float csb = cos(b);
      float snb = sin(b);
      p[i-1][j][0] = csb*csa;
      p[i-1][j][1] = snb*csa;
      p[i-1][j][2] = sna; } }
  return(p);
}

void colorise(vecteur n,vecteur ldir) {
  float v = produitScalaire(n,ldir);
  if ( v < 0.0F )
    v = 0.0F;
  glColor3f(v,v,v);
}

void flatFacette3(vecteur p1,vecteur p2,vecteur p3,float r) {
  vecteur n;
  n[0] = p1[0]+p2[0]+p3[0];
  n[1] = p1[1]+p2[1]+p3[1];
  n[2] = p1[2]+p2[2]+p3[2];
  normalise(n);
  colorise(n,ldir);
  glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
  glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
  glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
}

void flatFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,float r) {
  vecteur n;
  n[0] = p1[0]+p2[0]+p3[0]+p4[0];
  n[1] = p1[1]+p2[1]+p3[1]+p4[1];
  n[2] = p1[2]+p2[2]+p3[2]+p4[2];
  normalise(n);
  colorise(n,ldir);
  glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
  glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
  glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
  glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r);
}

void flatSphere(float r,int n,int m) {
  vecteur sup = { 0.0F,0.0F,1.0F };
  vecteur inf = { 0.0F,0.0F,-1.0F };
  vecteur **p =coordonnees(n,m);
  int i;
  glBegin(GL_TRIANGLES);
  for ( i = 0 ; i < m ; i++ ) {
    flatFacette3(p[0][i],p[0][(i+1)%m],inf,r); }
  for ( i = 0 ; i < m ; i++ ) {
    flatFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,r); }
  glEnd();
  glBegin(GL_QUADS);
  for ( int j = 0 ; j < n-1 ; j++ ) {
    for ( i = 0 ; i < m ; i++ ) {
      flatFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r); } }
  glEnd();
  for ( i = 0 ; i < n ; i++ ) 
    free(p[i]);
  free(p);
}

void gouraudFacette3(vecteur p1,vecteur p2,vecteur p3,float r) {
  colorise(p1,ldir);
  glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
  colorise(p2,ldir);
  glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
  colorise(p3,ldir);
  glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
}

void gouraudFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,float r) {
  colorise(p1,ldir);
  glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
  colorise(p2,ldir);
  glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
  colorise(p3,ldir);
  glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
  colorise(p4,ldir);
  glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r);
}

void gouraudSphere(float r,int n,int m) {
  vecteur sup = { 0.0F,0.0F,1.0F };
  vecteur inf = { 0.0F,0.0F,-1.0F };
  vecteur **p =coordonnees(n,m);
  int i;
  glBegin(GL_TRIANGLES);
  for ( i = 0 ; i < m ; i++ ) {
    gouraudFacette3(p[0][i],p[0][(i+1)%m],inf,r); }
  for ( i = 0 ; i < m ; i++ ) {
    gouraudFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,r); }
  glEnd();
  glBegin(GL_QUADS);
  for ( int j = 0 ; j < n-1 ; j++ ) {
    for ( i = 0 ; i < m ; i++ ) {
      gouraudFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r); } }
  glEnd();
  for ( i = 0 ; i < n ; i++ ) 
    free(p[i]);
  free(p);
}

void normaleIntermediaire(vecteur p1,vecteur p2,vecteur p) {
  p[0] = p1[0]+p2[0];
  p[1] = p1[1]+p2[1];
  p[2] = p1[2]+p2[2];
  normalise(p);
}

void positionIntermediaire(vecteur p1,vecteur p2,vecteur p) {
  p[0] = (p1[0]+p2[0])/2.0F;
  p[1] = (p1[1]+p2[1])/2.0F;
  p[2] = (p1[2]+p2[2])/2.0F;
}

void normaleIntermediaire(vecteur p1,vecteur p2,vecteur p3,vecteur p4,vecteur p) {
  p[0] = p1[0]+p2[0]+p3[0]+p4[0];
  p[1] = p1[1]+p2[1]+p3[1]+p4[1];
  p[2] = p1[2]+p2[2]+p3[2]+p4[2];
  normalise(p);
}

void positionIntermediaire(vecteur p1,vecteur p2,vecteur p3,vecteur p4,vecteur p) {
  p[0] = (p1[0]+p2[0]+p3[0]+p4[0])/4.0F;
  p[1] = (p1[1]+p2[1]+p3[1]+p4[1])/4.0F;
  p[2] = (p1[2]+p2[2]+p3[2]+p4[2])/4.0F;
}

void phongFacette3(vecteur p1,vecteur p2,vecteur p3,vecteur n1,vecteur n2,vecteur n3,float r,int niveau) {
  if ( niveau == 0 ) {
    colorise(n1,ldir);
    glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
    colorise(n2,ldir);
    glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
    colorise(n3,ldir);
    glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r); }
    else {
    vecteur p12;
    positionIntermediaire(p1,p2,p12);
    vecteur p13;
    positionIntermediaire(p1,p3,p13);
    vecteur p23;
    positionIntermediaire(p2,p3,p23);
    vecteur n12;
    normaleIntermediaire(n1,n2,n12);
    vecteur n13;
    normaleIntermediaire(n1,n3,n13);
    vecteur n23;
    normaleIntermediaire(n2,n3,n23);
    phongFacette3(p1,p12,p13,n1,n12,n13,r,niveau-1);
    phongFacette3(p2,p12,p23,n2,n12,n23,r,niveau-1);
    phongFacette3(p3,p13,p23,n3,n13,n23,r,niveau-1);
    phongFacette3(p12,p13,p23,n12,n13,n23,r,niveau-1); }
}

void phongFacette4(vecteur p1,vecteur p2,vecteur p3,vecteur p4,vecteur n1,vecteur n2,vecteur n3,vecteur n4,float r,int niveau) {
  if ( niveau == 0 ) {
    colorise(n1,ldir);
    glVertex3f(p1[0]*r,p1[1]*r,p1[2]*r);
    colorise(n2,ldir);
    glVertex3f(p2[0]*r,p2[1]*r,p2[2]*r);
    colorise(n3,ldir);
    glVertex3f(p3[0]*r,p3[1]*r,p3[2]*r);
    colorise(n4,ldir);
    glVertex3f(p4[0]*r,p4[1]*r,p4[2]*r); }
    else {
    vecteur p12;
    positionIntermediaire(p1,p2,p12);
    vecteur p23;
    positionIntermediaire(p2,p3,p23);
    vecteur p34;
    positionIntermediaire(p3,p4,p34);
    vecteur p41;
    positionIntermediaire(p4,p1,p41);
    vecteur pi;
    positionIntermediaire(p1,p2,p3,p4,pi);
    vecteur n12;
    normaleIntermediaire(n1,n2,n12);
    vecteur n23;
    normaleIntermediaire(n2,n3,n23);
    vecteur n34;
    normaleIntermediaire(n3,n4,n34);
    vecteur n41;
    normaleIntermediaire(n4,n1,n41);
    vecteur ni;
    normaleIntermediaire(n1,n2,n3,n4,ni);
    phongFacette4(p1,p12,pi,p41,n1,n12,ni,n41,r,niveau-1);
    phongFacette4(p2,p12,pi,p23,n2,n12,ni,n23,r,niveau-1);
    phongFacette4(p3,p34,pi,p23,n3,n34,ni,n23,r,niveau-1);
    phongFacette4(p4,p34,pi,p41,n4,n34,ni,n41,r,niveau-1); }
}

void phongSphere(float r,int n,int m) {
  vecteur sup = { 0.0F,0.0F,1.0F };
  vecteur inf = { 0.0F,0.0F,-1.0F };
  vecteur **p =coordonnees(n,m);
  int i;
  glBegin(GL_TRIANGLES);
  for ( i = 0 ; i < m ; i++ ) {
    phongFacette3(p[0][i],p[0][(i+1)%m],inf,p[0][i],p[0][(i+1)%m],inf,r,niv); }
  for ( i = 0 ; i < m ; i++ ) {
    phongFacette3(p[n-1][i],p[n-1][(i+1)%m],sup,p[n-1][i],p[n-1][(i+1)%m],sup,r,niv); }
  glEnd();
  glBegin(GL_QUADS);
  for ( int j = 0 ; j < n-1 ; j++ ) {
    for ( i = 0 ; i < m ; i++ ) {
      phongFacette4(p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],p[j][i],p[j][(i+1)%m],p[j+1][(i+1)%m],p[j+1][i],r,niv); } }
  glEnd();
  for ( i = 0 ; i < n ; i++ ) 
    free(p[i]);
  free(p);
}

void display(void) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  manipulateurSouris();
  manipulateurClavier();
  switch ( aff ) {
    case 0 : flatSphere(1.3F,disc1,disc2);
             break;
    case 1 : gouraudSphere(1.3F,disc1,disc2);
             break;
    case 2 : phongSphere(1.3F,disc1,disc2);
             break; }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void key(unsigned char key,int x,int y) {
  if ( keyManipulateur(key,x,y) )
    glutPostRedisplay();
    else
    switch ( key ) {
      case 'a'  : disc1++ ;
                  glutPostRedisplay() ;
                  break ;
      case 'A'  : disc1-- ;
                  if ( disc1 < 3 )
                    disc1 = 3;
                  glutPostRedisplay() ;
                  break ;
      case 'b'  : disc2++ ;
                  glutPostRedisplay() ;
                  break ;
      case 'B'  : disc2-- ;
                  if ( disc2 < 2 )
                    disc2 = 2;
                  glutPostRedisplay() ;
                  break ;
      case 43   : niv++ ;
                  glutPostRedisplay() ;
                  break ;
      case 45   : niv-- ;
                  if ( niv < 0 )
                    niv = 0;
                  glutPostRedisplay() ;
                  break ;
      case 0x0D : aff = (aff+1)%3 ;
                  glutPostRedisplay() ;
                  break ; }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(200,200); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Modelise sphere");
  myinit(); 
  creationMenuBasique();
  setParametresOrthoBasique(-1.5,1.5,-1.5,1.5,-50.0,50.0);
  setManipulateurDistance(1.0F);
  setManipulateurSourisAngle(20.0F,30.0F,40.0F);
  glutReshapeFunc(reshapeOrthoBasique);
  glutKeyboardFunc(key);
  glutSpecialFunc(specialBasique);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR