2 facettes à afficher
au moyen dun Z-Buffer
Pixélisation de chacune de ces facettes
Calcul daltitude 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)
/* 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);
}