L'exécutable

2 facettes à afficher
au moyen d’un Z-Buffer

Pixélisation de chacune de ces facettes

Calcul d’altitude pour chacun des pixels
de chacune des deux facettes

Affichage des pixels visibles
par comparaison des altitudes
(deux affichages possibles suivant
l'ordre de parcours des facettes)

Le source: ZBuffer4.cpp

/* Auteur: Nicolas JANEY         */
/* nicolas.janey@univ-fcomte.fr  */
/* Mars 2002                     */
/* Illustration du Z-Buffer      */

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

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

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

static int mode = 0 ;
static float f11[3] = {-5.0F,6.0F,-3.0F};
static float f12[3] = {6.0F,4.0F,4.0F};
static float f13[3] = {-2.0F,-6.0F,6.0F};
static float f21[3] = {0.0F,3.0F,5.0F};
static float f22[3] = {3.0F,-6.0F,-1.0F};
static float f23[3] = {-5.0F,-4.0F,3.0F};

int arrondi(int z) {
  if ( z > 0 )
    z = (z+499)/1000;
    else
    z = (z-499)/1000;
  return(z);
}

void pixel(float *coul,int x,int y,int z) {
  glColor4fv(coul) ;
  z = arrondi(z) ;
  glBegin(GL_QUADS) ;
  glVertex3f(x-15.5,y-15.5,z) ;
  glVertex3f(x-14.5,y-15.5,z) ;
  glVertex3f(x-14.5,y-14.5,z) ;
  glVertex3f(x-15.5,y-14.5,z) ;
  glEnd() ;
  glColor4fv(couleurGrisFonce()) ;
  placeFontCursor(x-15,y-15,z+1) ;
  deplacementCursor(0,-3,0) ;
  simpleBitmapOutput(0,REGULAR6x10,"%d",z) ;
}

void ligneDiscrete(float *coul,int y,int x1,int z1,int x2,int z2) {
  if ( x2 != -100 ) {
    int i,cumul ;
    int x = x1 ;
    int z = z1 ;
    int dx = x2 - x1 ;
    int dz = z2 - z1 ;
    int xinc = ( dx > 0 ) ? 1 : -1 ;
    int zinc = ( dz > 0 ) ? 1 : -1 ;
    dx = abs(dx) ;
    dz = abs(dz) ;
    pixel(coul,x,y,z) ;
    cumul = dz / 2 ;
    while ( cumul > dx ) {
      cumul -= dx ;
      z += zinc ; }
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc ;
      cumul += dz ;
      while ( cumul > dx ) {
        cumul -= dx ;
        z += zinc ; }
      pixel(coul,x,y,z) ; } }
}

void ligne(int xi,int yi,int zi,int xf,int yf,int zf,int *px,int *pz) {
  int i,cumul,cumulz ;
  int x = xi ;
  int y = yi ;
  int z = zi ;
  int dx = xf - xi ;
  int dy = yf - yi ;
  int dz = zf - zi ;
  int xinc = ( dx > 0 ) ? 1 : -1 ;
  int yinc = ( dy > 0 ) ? 1 : -1 ;
  int zinc = ( dz > 0 ) ? 1 : -1 ;
  dx = abs(dx) ;
  dy = abs(dy) ;
  dz = abs(dz) ;
  px[y] = x ;
  pz[y] = z ;
  if ( dx > dy ) {
    cumul = dx / 2 ;
    cumulz = dx / 2 ;
    while (cumulz >= dx) {
      cumulz -= dx ;
      z += zinc ; }
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc ;
      cumul += dy ;
      cumulz += dz ;
      if (cumul >= dx) {
        cumul -= dx ;
        y += yinc ; }
      while (cumulz >= dx) {
        cumulz -= dx ;
        z += zinc ; }
      px[y] = x ; 
      pz[y] = z ; } }
    else {
    cumul = dy / 2 ;
    cumulz = dx / 2 ;
    while ( cumulz >= dy ) {
      cumulz -= dy ;
      z += zinc ; }
    for ( i = 1 ; i <= dy ; i++ ) {
      y += yinc ;
      cumul += dx ;
      cumulz += dz ;
      if ( cumul >= dy ) {
        cumul -= dy ;
        x += xinc ; }
      while ( cumulz >= dy ) {
        cumulz -= dy ;
        z += zinc ; }
      px[y] = x ;
      pz[y] = z ; } }
}

void facetteDiscrete(float *coul,float *p1,float *p2,float *p3) {
  glPushMatrix() ;
  int px1[30] ;
  int px2[30] ;
  int px3[30] ;
  int pz1[30] ;
  int pz2[30] ;
  int pz3[30] ;
  int i;
  for ( i = 0 ; i < 30 ; i++ ) {
    px1[i] = px2[i] = px3[i] = -100 ;
    pz1[i] = pz2[i] = pz3[i] = 0 ; }
  ligne((int) (p1[0]+15),(int) (p1[1]+15),(int) (p1[2]),(int) (p2[0]+15),(int) (p2[1]+15),(int) (p2[2]),px1,pz1) ;
  ligne((int) (p1[0]+15),(int) (p1[1]+15),(int) (p1[2]),(int) (p3[0]+15),(int) (p3[1]+15),(int) (p3[2]),px2,pz2) ;
  ligne((int) (p2[0]+15),(int) (p2[1]+15),(int) (p2[2]),(int) (p3[0]+15),(int) (p3[1]+15),(int) (p3[2]),px3,pz3) ;
  int x1[30] ;
  int x2[30] ;
  int z1[30] ;
  int z2[30] ;
  for ( i = 0 ; i < 30 ; i++ ) {
    x1[i] = x2[i] = -100 ;
    z1[i] = z2[i] = 0 ; }
  for ( i = 0 ; i < 30 ; i++ ) {
    if ( px1[i] > x1[i] ) {
      x1[i] = px1[i] ;
      z1[i] = pz1[i] ; }
    if ( px2[i] > x1[i] ) {
      x1[i] = px2[i] ;
      z1[i] = pz2[i] ; }
    if ( px3[i] > x1[i] ) {
      x1[i] = px3[i] ; 
      z1[i] = pz3[i] ; } }
  for ( i = 0 ; i < 30 ; i++ )
    x2[i] = x1[i] ;
  for ( i = 0 ; i < 30 ; i++ ) {
    if ( ( px1[i] <= x2[i] ) && ( px1[i] != -100 ) ) {
      x2[i] = px1[i] ;
      z2[i] = pz1[i] ; }
    if ( ( px2[i] <= x2[i] ) && ( px2[i] != -100 ) ) {
      x2[i] = px2[i] ;
      z2[i] = pz2[i] ; }
    if ( ( px3[i] <= x2[i] ) && ( px3[i] != -100 ) ) {
      x2[i] = px3[i] ;
      z2[i] = pz3[i] ; } }
  for ( int y = 0 ; y < 30 ; y++ )
    ligneDiscrete(coul,y,x2[y],z2[y],x1[y],z1[y]) ;
  glPopMatrix() ;
}

void dessineQuadrillage(void) {
  float i;
  glColor4fv(couleurGrisMoyen()) ;
  glBegin(GL_LINES);
  for ( i = -7.5 ; i < 8.5 ; i++ ) {
    glVertex3d(-7.5,i,-10.0);
    glVertex3d(7.5,i,-10.0); }
  for ( i = -7.5 ; i < 8.5 ; i++ ) {
    glVertex3d(i,-7.5,-10.0);
    glVertex3d(i,7.5,-10.0); }
  glEnd() ;
  glPushMatrix();
  glTranslatef(-7.0F,0.0F,-10.0F);
  flecheEnVolume(14.25F,0.0F,0.0F,0.4F,1.25F,0.12F);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,-7.0F,-10.0F);
  flecheEnVolume(0.0F,14.25F,0.0F,0.4F,1.25F,0.12F);
  glPopMatrix();
}

void objetDiscret1() {
  f11[2] *= 1000.0F;
  f12[2] *= 1000.0F;
  f13[2] *= 1000.0F;
  facetteDiscrete(couleurRose(0.7F),f11,f12,f13);
  f11[2] /= 1000.0F;
  f12[2] /= 1000.0F;
  f13[2] /= 1000.0F;
  glColor4fv(couleurBleu()) ;
  placeFontCursor(f11[0],f11[1],f11[2]) ;
  deplacementCursor(10,-16,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f11[0],(int) f11[1],(int) f11[2]) ;
  placeFontCursor(f12[0],f12[1],f12[2]) ;
  deplacementCursor(-7,-16,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f12[0],(int) f12[1],(int) f12[2]) ;
  placeFontCursor(f13[0],f13[1],f13[2]) ;
  deplacementCursor(-15,14,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f13[0],(int) f13[1],(int) f13[2]) ;
}

void objetDiscret2() {
  glColor4fv(couleurVert(0.7F)) ;
  f21[2] *= 1000.0F;
  f22[2] *= 1000.0F;
  f23[2] *= 1000.0F;
  facetteDiscrete(couleurVert(0.7F),f21,f22,f23);
  f21[2] /= 1000.0F;
  f22[2] /= 1000.0F;
  f23[2] /= 1000.0F;
  glColor4fv(couleurBleu()) ;
  placeFontCursor(f21[0],f21[1],f21[2]) ;
  deplacementCursor(0,-16,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f21[0],(int) f21[1],(int) f21[2]) ;
  placeFontCursor(f22[0],f22[1],f22[2]) ;
  deplacementCursor(10,14,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f22[0],(int) f22[1],(int) f22[2]) ;
  placeFontCursor(f23[0],f23[1],f23[2]) ;
  deplacementCursor(4,14,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f23[0],(int) f23[1],(int) f23[2]) ;
}

void objet1() {
  glColor4fv(couleurRose(0.7F)) ;
  glBegin(GL_TRIANGLES) ;
  glVertex3fv(f11) ;
  glVertex3fv(f12) ;
  glVertex3fv(f13) ;
  glEnd() ;
  glColor4fv(couleurBleu()) ;
  placeFontCursor(f11[0],f11[1],f11[2]) ;
  deplacementCursor(10,-16,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f11[0],(int) f11[1],(int) f11[2]) ;
  placeFontCursor(f12[0],f12[1],f12[2]) ;
  deplacementCursor(-7,-16,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f12[0],(int) f12[1],(int) f12[2]) ;
  placeFontCursor(f13[0],f13[1],f13[2]) ;
  deplacementCursor(-15,14,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f13[0],(int) f13[1],(int) f13[2]) ;
}

void objet2() {
  glColor4fv(couleurVert(0.7F)) ;
  glBegin(GL_TRIANGLES) ;
  glVertex3fv(f21) ;
  glVertex3fv(f22) ;
  glVertex3fv(f23) ;
  glEnd() ;
  glColor4fv(couleurBleu()) ;
  placeFontCursor(f21[0],f21[1],f21[2]) ;
  deplacementCursor(0,-16,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f21[0],(int) f21[1],(int) f21[2]) ;
  placeFontCursor(f22[0],f22[1],f22[2]) ;
  deplacementCursor(10,14,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f22[0],(int) f22[1],(int) f22[2]) ;
  placeFontCursor(f23[0],f23[1],f23[2]) ;
  deplacementCursor(4,14,0) ;
  simpleBitmapOutput(0,REGULAR8x13,"(%d,%d,%d)",(int) f23[0],(int) f23[1],(int) f23[2]) ;
}

void pixel2(float *coul,int x,int y,int z) {
  glColor4fv(coul) ;
  glBegin(GL_QUADS) ;
  glVertex3f(x-15.5,y-15.5,z) ;
  glVertex3f(x-14.5,y-15.5,z) ;
  glVertex3f(x-14.5,y-14.5,z) ;
  glVertex3f(x-15.5,y-14.5,z) ;
  glEnd() ;
  glColor4fv(couleurGrisFonce()) ;
  placeFontCursor(x-15,y-15,z+1) ;
  deplacementCursor(0,-3,0) ;
  simpleBitmapOutput(0,REGULAR6x10,"%d",z) ;
}

void pixel(int coul,int x,int y,int z,int **bt,int **ht) {
  z = arrondi(z) ;
  if ( z > ht[y][x] ) {
    ht[y][x] = z;
    bt[y][x] = coul; }
}

void ligneDiscrete(int coul,int y,int x1,int z1,int x2,int z2,int **bt,int **ht) {
  if ( x2 != -100 ) {
    int i,cumul ;
    int x = x1 ;
    int z = z1 ;
    int dx = x2 - x1 ;
    int dz = z2 - z1 ;
    int xinc = ( dx > 0 ) ? 1 : -1 ;
    int zinc = ( dz > 0 ) ? 1 : -1 ;
    dx = abs(dx) ;
    dz = abs(dz) ;
    pixel(coul,x,y,z,bt,ht) ;
    cumul = dz / 2 ;
    while ( cumul > dx ) {
      cumul -= dx ;
      z += zinc ; }
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc ;
      cumul += dz ;
      while ( cumul > dx ) {
        cumul -= dx ;
        z += zinc ; }
      pixel(coul,x,y,z,bt,ht) ; } }
}

void facetteDiscrete(int coul,float *p1,float *p2,float *p3,int **bt,int **ht) {
  int px1[30] ;
  int px2[30] ;
  int px3[30] ;
  int pz1[30] ;
  int pz2[30] ;
  int pz3[30] ;
  int i;
  for ( i = 0 ; i < 30 ; i++ ) {
    px1[i] = px2[i] = px3[i] = -100 ;
    pz1[i] = pz2[i] = pz3[i] = 0 ; }
  ligne((int) (p1[0]+15),(int) (p1[1]+15),(int) (p1[2]),(int) (p2[0]+15),(int) (p2[1]+15),(int) (p2[2]),px1,pz1) ;
  ligne((int) (p1[0]+15),(int) (p1[1]+15),(int) (p1[2]),(int) (p3[0]+15),(int) (p3[1]+15),(int) (p3[2]),px2,pz2) ;
  ligne((int) (p2[0]+15),(int) (p2[1]+15),(int) (p2[2]),(int) (p3[0]+15),(int) (p3[1]+15),(int) (p3[2]),px3,pz3) ;
  int x1[30] ;
  int x2[30] ;
  int z1[30] ;
  int z2[30] ;
  for ( i = 0 ; i < 30 ; i++ ) {
    x1[i] = x2[i] = -100 ;
    z1[i] = z2[i] = 0 ; }
  for ( i = 0 ; i < 30 ; i++ ) {
    if ( px1[i] > x1[i] ) {
      x1[i] = px1[i] ;
      z1[i] = pz1[i] ; }
    if ( px2[i] > x1[i] ) {
      x1[i] = px2[i] ;
      z1[i] = pz2[i] ; }
    if ( px3[i] > x1[i] ) {
      x1[i] = px3[i] ; 
      z1[i] = pz3[i] ; } }
  for ( i = 0 ; i < 30 ; i++ )
    x2[i] = x1[i] ;
  for ( i = 0 ; i < 30 ; i++ ) {
    if ( ( px1[i] <= x2[i] ) && ( px1[i] != -100 ) ) {
      x2[i] = px1[i] ;
      z2[i] = pz1[i] ; }
    if ( ( px2[i] <= x2[i] ) && ( px2[i] != -100 ) ) {
      x2[i] = px2[i] ;
      z2[i] = pz2[i] ; }
    if ( ( px3[i] <= x2[i] ) && ( px3[i] != -100 ) ) {
      x2[i] = px3[i] ;
      z2[i] = pz3[i] ; } }
  for ( int y = 0 ; y < 30 ; y++ )
    ligneDiscrete(coul,y,x2[y],z2[y],x1[y],z1[y],bt,ht) ;
}

void objetDiscret2puis1(void) {
  int i;
  int **cl =(int **) calloc(30,sizeof(int *));
  int **ht =(int **) calloc(30,sizeof(int *));
  for ( i = 0 ; i < 30 ; i++ ) {
    cl[i] =(int *) calloc(30,sizeof(int));
    ht[i] =(int *) calloc(30,sizeof(int));
    for ( int j = 0 ; j < 30 ; j++ )
      ht[i][j] = -10000000; }
  f11[2] *= 1000.0F;
  f12[2] *= 1000.0F;
  f13[2] *= 1000.0F;
  f21[2] *= 1000.0F;
  f22[2] *= 1000.0F;
  f23[2] *= 1000.0F;
  facetteDiscrete(1,f11,f12,f13,cl,ht);
  facetteDiscrete(2,f21,f22,f23,cl,ht);
  f11[2] /= 1000.0F;
  f12[2] /= 1000.0F;
  f13[2] /= 1000.0F;
  f21[2] /= 1000.0F;
  f22[2] /= 1000.0F;
  f23[2] /= 1000.0F;
  for ( i = 0 ; i < 30 ; i++ ) {
    for ( int j = 0 ; j < 30 ; j++ ) {
      if ( ht[i][j] != -10000000.0 ) {
        float *c;
        switch ( cl[i][j] ) {
          case 1 : c = couleurRose(0.75F);
                   break;
          case 2 : c = couleurVert(0.75F);
                   break; }
        pixel2(c,j,i,ht[i][j]) ; } } }
  for ( i = 0 ; i < 30 ; i++ ) {
    free(cl[i]);
    free(ht[i]); }
  free(cl);
  free(ht);
}

void objetDiscret1puis2(void) {
  int i;
  int **cl =(int **) calloc(30,sizeof(int *));
  int **ht =(int **) calloc(30,sizeof(int *));
  for ( i = 0 ; i < 30 ; i++ ) {
    cl[i] =(int *) calloc(30,sizeof(int));
    ht[i] =(int *) calloc(30,sizeof(int));
    for ( int j = 0 ; j < 30 ; j++ )
      ht[i][j] = -10000000; }
  f11[2] *= 1000.0F;
  f12[2] *= 1000.0F;
  f13[2] *= 1000.0F;
  f21[2] *= 1000.0F;
  f22[2] *= 1000.0F;
  f23[2] *= 1000.0F;
  facetteDiscrete(2,f21,f22,f23,cl,ht);
  facetteDiscrete(1,f11,f12,f13,cl,ht);
  f11[2] /= 1000.0F;
  f12[2] /= 1000.0F;
  f13[2] /= 1000.0F;
  f21[2] /= 1000.0F;
  f22[2] /= 1000.0F;
  f23[2] /= 1000.0F;
  for ( i = 0 ; i < 30 ; i++ ) {
    for ( int j = 0 ; j < 30 ; j++ ) {
      if ( ht[i][j] != -10000000.0 ) {
        float *c;
        switch ( cl[i][j] ) {
          case 1 : c = couleurRose(0.75F);
                   break;
          case 2 : c = couleurVert(0.75F);
                   break; }
        pixel2(c,j,i,ht[i][j]) ; } } }
  for ( i = 0 ; i < 30 ; i++ ) {
    free(cl[i]);
    free(ht[i]); }
  free(cl);
  free(ht);
}

void display(void) {
  glClearColor(1.0,1.0,1.0,1.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  dessineQuadrillage();
  switch ( mode) {
    case 0 : objet2() ;
             objet1() ;
             break;
    case 1 : objet1() ;
             break;
    case 2 : objetDiscret1() ;
             break;
    case 3 : objet2() ;
             break;
    case 4 : objetDiscret2() ;
             break;
    case 5 : objetDiscret2puis1() ;
             break;
    case 6 : objetDiscret1puis2() ;
             break; }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void myinit(void) {
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_DEPTH_TEST) ;
  setAlignement(CENTER);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);
}

void key(unsigned char key,int x,int y) {
  switch ( key ) {
    case 0x1B : exit(0);
                break;
    case ' '  : mode = (mode+1)%7;
                glutPostRedisplay();
                break; }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(240,240); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("ZBuffer"); 
  myinit(); 
  creationMenuBasique();
  setParametresOrthoBasique(-8.0,8.0,-8.0,8.0,-50.0,50.0);
  glutReshapeFunc(reshapeOrthoBasique);
  glutKeyboardFunc(key);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

WB01624_.gif (281 octets) RETOUR