/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Mars 2002 */ /* Illustration du Z-Buffer */ #include #include #include #include #include #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); }