/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Avril 2020 */ /* Illustration du Z-Buffer */ #include #include #include #include #include #include #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" static float rouge[4] = { 1.0F,0.0F,0.0F,1.0F }; static float vert[4] = { 0.0F,1.0F,0.0F,1.0F }; static float rougeFonce[4] = { 0.7F,0.0F,0.0F,1.0F }; static float vertFonce[4] = { 0.0F,0.7F,0.0F,1.0F }; static float jaune[4] = { 1.0F,1.0F,0.0F,1.0F }; static float cyan[4] = { 1.0F,1.0F,1.0F,1.0F }; static float magenta[4] = { 1.0F,0.0F,1.0F,1.0F }; static int aff = 0; static int mode = 0; static int eliminationPartiesCachees = 0; static int bord = 0; static void axes() { glColor4fv(jaune); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(3.0F,0.0F,0.0F); glEnd(); glColor4fv(cyan); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(0.0F,3.0F,0.0F); glEnd(); glColor4fv(magenta); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(0.0F,0.0F,3.0F); glEnd(); } static void myinit() { glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glClearColor(0.8F,0.8F,0.8F,1.0F); } static void facette(float *coul,int *p1,int *p2,int *p3) { glColor4fv(coul); glPushMatrix(); glBegin(GL_TRIANGLES); glVertex3f(p1[0],p1[1],p1[2]); glVertex3f(p2[0],p2[1],p2[2]); glVertex3f(p3[0],p3[1],p3[2]); glEnd(); glPopMatrix(); } static void pixelOpenGL(int x,int y,int z) { glBegin(GL_QUADS); glVertex3f(x-15.5F,y-15.5F,z/1000.0F); glVertex3f(x-14.5F,y-15.5F,z/1000.0F); glVertex3f(x-14.5F,y-14.5F,z/1000.0F); glVertex3f(x-15.5F,y-14.5F,z/1000.0F); glEnd(); } ///////////////////////////////////////////////// static void pixel(int x,int y,int z,int *xmin,int *xmax,int *zmin,int *zmax) { if ( x < xmin[y] ) { xmin[y] = x; zmin[y] = z; } if ( x > xmax[y] ) { xmax[y] = x; zmax[y] = z; } } static void cote(int xi,int yi,int zi,int xf,int yf,int zf, int *xmin,int *xmax,int *zmin,int *zmax) { 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); pixel(x,y,z,xmin,xmax,zmin,zmax); if ( dx > dy ) { cumul = dx / 2; cumulz = 0; 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; } pixel(x,y,z,xmin,xmax,zmin,zmax); } } else { cumul = dy / 2; cumulz = 0; 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; } pixel(x,y,z,xmin,xmax,zmin,zmax); } } pixel(xi,yi,zi,xmin,xmax,zmin,zmax); pixel(xf,yf,zf,xmin,xmax,zmin,zmax); } static void trame(int y,int x1,int z1,int x2,int z2, void (*pixel)(int,int,int)) { 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 = 0; for ( i = 1 ; i <= dx ; i++ ) { x += xinc; cumul += dz; while ( cumul > dx ) { cumul -= dx; z += zinc; } pixel(x,y,z); } } static void triangle(int x1,int y1,int z1, int x2,int y2,int z2, int x3,int y3,int z3, void (*pixel)(int,int,int)) { int dim = y3-y1+1; int dy = -y1; int *xmin = new int[dim]; int *xmax = new int[dim]; int *zmin = new int[dim]; int *zmax = new int[dim]; for ( int y = 0 ; y < dim ; y++ ) { xmin[y] = 8192; xmax[y] = -1; } cote(x1,y1+dy,z1,x2,y2+dy,z2,xmin,xmax,zmin,zmax); cote(x2,y2+dy,z2,x3,y3+dy,z3,xmin,xmax,zmin,zmax); cote(x1,y1+dy,z1,x3,y3+dy,z3,xmin,xmax,zmin,zmax); for ( int y = 0 ; y < dim ; y++ ) trame(y-dy,xmin[y],zmin[y],xmax[y],zmax[y],pixel); delete(xmin); delete(xmax); delete(zmin); delete(zmax); } ///////////////////////////////////////////////// static void triangle(float *coul,int *p1,int *p2,int *p3) { int x1 = 15+p1[0],y1 = 15+p1[1],z1 = p1[2]*1000; int x2 = 15+p2[0],y2 = 15+p2[1],z2 = p2[2]*1000; int x3 = 15+p3[0],y3 = 15+p3[1],z3 = p3[2]*1000; glColor4fv(coul); glPushMatrix(); triangle(x1,y1,z1,x2,y2,z2,x3,y3,z3,pixelOpenGL); glPopMatrix(); } static void display(void) { int f11[] = { -12,-12, -4 }; int f12[] = { 12, 2, 13 }; int f13[] = { -10, 10, -7 }; int f21[] = { 12,-12, -2 }; int f22[] = { -12, 2, 7 }; int f23[] = { 5, 10,-14 }; glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK,(mode == 0) ? GL_FILL : GL_LINE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(10.0F,10.0F,10.0F); manipulateurSouris(); manipulateurClavier(); axes(); glPopMatrix(); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); switch (aff) { case 0 : if ( !eliminationPartiesCachees ) glDisable(GL_DEPTH_TEST); facette(rougeFonce,f11,f12,f13); facette(vertFonce,f21,f22,f23); break; case 1 : facette(vertFonce,f21,f22,f23); break; case 2 : triangle(vertFonce,f21,f22,f23); if ( bord ) { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glLineWidth(3.0F); facette(vert,f21,f22,f23); glLineWidth(1.0F); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } break; case 3 : facette(rougeFonce,f11,f12,f13); break; case 4 : triangle(rougeFonce,f11,f12,f13); if ( bord ) { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glLineWidth(3.0F); facette(rouge,f11,f12,f13); glLineWidth(1.0F); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } break; case 5 : triangle(vertFonce,f21,f22,f23); triangle(rougeFonce,f11,f12,f13); if ( bord ) { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glLineWidth(3.0F); facette(rouge,f11,f12,f13); facette(vert,f21,f22,f23); glLineWidth(1.0F); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } static void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 0x20 : mode = !mode; glutPostRedisplay(); break; case 'c' : eliminationPartiesCachees = !eliminationPartiesCachees; glutPostRedisplay(); break; case 'b' : bord = !bord; glutPostRedisplay(); break; case 0x0D : aff = (aff+1)%6; glutPostRedisplay(); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(256,256); glutInitWindowPosition(50,50); glutCreateWindow("ZBuffer - Remplissage des facettes avec calcul du z des pixels"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-15.0,15.0,-15.0,15.0,-1000.0,1000.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }