L'exécutable
- Enter pour visualiser le calcul des différentes
facettes
- Espace pour augmenter la taille des pixels
- Touches de curseur pour les rotations

Le source: ZBuffer3.cpp
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float anglex = 0.0F ;
float angley = 0.0F ;
float anglez = 0.0F ;
int aff = 0 ;
int disc = 4 ;
static int discretisation[8] = { 1,2,4,8,10,20,40,80 } ;
static int dim ;
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 = dy / 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 = dy / 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 axes() {
float rouge[] = { 1.0F,1.0F,0.0F,1.0F };
glColor4fv(rouge) ;
glBegin(GL_LINES) ;
glVertex3f(0.0F,0.0F,0.0F) ;
glVertex3f(20.0F,0.0F,0.0F) ;
glEnd() ;
float vert[] = { 0.0F,1.0F,1.0F,1.0F };
glColor4fv(vert) ;
glBegin(GL_LINES) ;
glVertex3f(0.0F,0.0F,0.0F) ;
glVertex3f(0.0F,20.0F,0.0F) ;
glEnd() ;
float bleu[] = { 0.0F,0.0F,1.0F,1.0F };
glColor4fv(bleu) ;
glBegin(GL_LINES) ;
glVertex3f(0.0F,0.0F,0.0F) ;
glVertex3f(0.0F,0.0F,20.0F) ;
glEnd() ;
}
void CALLBACK init() {
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
}
void Facette(float *coul,float *p1,float *p2,float *p3) {
glColor4fv(coul) ;
glPushMatrix() ;
glBegin(GL_TRIANGLES) ;
glVertex3fv(p1) ;
glVertex3fv(p2) ;
glVertex3fv(p3) ;
glEnd() ;
glPopMatrix() ;
}
float taillePixel() {
return(discretisation[disc]/5.0F) ;
}
void Pixel(int x, int y,int z) {
glBegin(GL_QUADS) ;
glVertex3f(taillePixel()*x-40.0F,taillePixel()*y-40.0F,taillePixel()*z) ;
glVertex3f(taillePixel()*(x+1)-40.0F,taillePixel()*y-40.0F,taillePixel()*z) ;
glVertex3f(taillePixel()*(x+1)-40.0F,taillePixel()*(y+1)-40.0F,taillePixel()*z) ;
glVertex3f(taillePixel()*x-40.0F,taillePixel()*(y+1)-40.0F,taillePixel()*z) ;
glEnd() ;
}
void LigneDiscrete(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(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(x,y,z) ; } }
}
int coordonnee(float p) {
return((int) ((p+40.0F)*5.0F/discretisation[disc])) ;
}
int coordonneeZ(float p) {
return((int) (p*5.0F/discretisation[disc])) ;
}
void FacetteDiscrete(float *coul,float *p1,float *p2,float *p3) {
glColor4fv(coul) ;
glPushMatrix() ;
int *px1 = new int[dim];
int *px2 = new int[dim];
int *px3 = new int[dim];
int *pz1 = new int[dim];
int *pz2 = new int[dim];
int *pz3 = new int[dim];
for ( int i = 0 ; i < dim ; i++ ) {
px1[i] = px2[i] = px3[i] = -100 ;
pz1[i] = pz2[i] = pz3[i] = 0 ; }
ligne(coordonnee(p1[0]),coordonnee(p1[1]),coordonneeZ(p1[2]),coordonnee(p2[0]),coordonnee(p2[1]),coordonneeZ(p2[2]),px1,pz1) ;
ligne(coordonnee(p1[0]),coordonnee(p1[1]),coordonneeZ(p1[2]),coordonnee(p3[0]),coordonnee(p3[1]),coordonneeZ(p3[2]),px2,pz2) ;
ligne(coordonnee(p2[0]),coordonnee(p2[1]),coordonneeZ(p2[2]),coordonnee(p3[0]),coordonnee(p3[1]),coordonneeZ(p3[2]),px3,pz3) ;
int *x1 = new int[dim];
int *x2 = new int[dim];
int *z1 = new int[dim];
int *z2 = new int[dim];
for ( i = 0 ; i < dim ; i++ ) {
x1[i] = x2[i] = -100 ;
z1[i] = z2[i] = 0 ; }
for ( i = 0 ; i < dim ; 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 < dim ; i++ )
x2[i] = x1[i] ;
for ( i = 0 ; i < dim ; 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 < dim ; y++ )
LigneDiscrete(y,x2[y],z2[y],x1[y],z1[y]) ;
glPopMatrix() ;
delete(x1) ;
delete(x2) ;
delete(z1) ;
delete(z2) ;
delete(px1) ;
delete(px2) ;
delete(px3) ;
delete(pz1) ;
delete(pz2) ;
delete(pz3) ;
}
void CALLBACK display() {
float rouge[] = { 1.0F,0.0F,0.0F,1.0F };
float vert[] = { 0.0F,1.0F,0.0F,1.0F };
float f11[] = { -35.0F,-32.0F,-5.0F } ;
float f12[] = { -27.0F,27.0F,-9.0F } ;
float f13[] = { 33.0F,7.0F,17.0F } ;
float f21[] = { 33.0F,-34.0F,-3.0F } ;
float f22[] = { 13.0F,27.0F,-21.0F } ;
float f23[] = { -34.0F,7.0F,12.0F } ;
dim =(int) (400.0F/discretisation[disc]) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(anglex,1.0F,0.0F,0.0F) ;
glRotatef(angley,0.0F,1.0F,0.0F) ;
glRotatef(anglez,0.0F,0.0F,1.0F) ;
glPushMatrix();
switch (aff) {
case 0 : Facette(rouge,f11,f12,f13) ;
Facette(vert,f21,f22,f23) ;
break ;
case 1 : Facette(vert,f21,f22,f23) ;
break ;
case 2 : FacetteDiscrete(vert,f21,f22,f23) ;
break ;
case 3 : Facette(rouge,f11,f12,f13) ;
break ;
case 4 : FacetteDiscrete(rouge,f11,f12,f13) ;
break ;
case 5 : FacetteDiscrete(vert,f21,f22,f23) ;
FacetteDiscrete(rouge,f11,f12,f13) ;
break ; }
glPopMatrix();
glPushMatrix();
axes() ;
glPopMatrix();
glPopMatrix();
glFlush();
auxSwapBuffers() ;
}
void CALLBACK reshape(int w,int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if( w <= h)
glOrtho(-40.0,40.0,-40.0*(double) h/w,40.0*(double) h/w,-40.0,40.0);
else
glOrtho(-40.0*(double) h/w,40.0*(double) h/w,-40.0,40.0,-40.0,40.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void CALLBACK auxKeyLeft() {
angley-=2 ;
}
void CALLBACK auxKeyRight() {
angley+=2 ;
}
void CALLBACK auxKeyUp() {
anglex-=2 ;
}
void CALLBACK auxKeyDown() {
anglex+=2 ;
}
void CALLBACK auxKeyz() {
anglez+=2 ;
}
void CALLBACK auxKeyZ() {
anglez-=2 ;
}
void CALLBACK auxKeyReturn() {
aff++ ;
if ( aff == 6 )
aff = 0 ;
}
void CALLBACK auxKeySpace() {
disc++ ;
if ( disc == 8 )
disc = 0 ;
}
void main(void) {
auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA|AUX_DEPTH);
auxInitPosition (0,0,400,400);
auxInitWindow("ZBuffer Version 3") ;
init();
auxKeyFunc(AUX_RETURN,auxKeyReturn) ;
auxKeyFunc(AUX_SPACE,auxKeySpace) ;
auxKeyFunc(AUX_UP,auxKeyUp) ;
auxKeyFunc(AUX_DOWN,auxKeyDown) ;
auxKeyFunc(AUX_RIGHT,auxKeyRight) ;
auxKeyFunc(AUX_LEFT,auxKeyLeft) ;
auxKeyFunc(AUX_z,auxKeyz) ;
auxKeyFunc(AUX_Z,auxKeyZ) ;
auxReshapeFunc(reshape);
auxMainLoop(display);
}
RETOUR