/* 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 disc = 2; static float discretisation[6] = { 0.5F,1.0F,2.0F,5.0F,10.0F,20.0F }; 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(); } void myinit() { glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glClearColor(0.8F,0.8F,0.8F,1.0F); } static float taillePixel() { return(discretisation[disc]/2.0F); } static int coordonnee(int p) { return((p+20)*2/discretisation[disc]); } static int coordonneeZ(int p) { return(p*1000); } static void facette(float *coul,int *p1,int *p2,int *p3) { float dp = -(discretisation[disc] - discretisation[0])*0.25F; glColor4fv(coul); glPushMatrix(); glTranslatef(dp,dp,0.0F); glBegin(GL_TRIANGLES); glVertex3f((coordonnee(p1[0])+0.5F)*taillePixel()-20.0F, (coordonnee(p1[1])+0.5F)*taillePixel()-20.0F, p1[2]); glVertex3f((coordonnee(p2[0])+0.5F)*taillePixel()-20.0F, (coordonnee(p2[1])+0.5F)*taillePixel()-20.0F, p2[2]); glVertex3f((coordonnee(p3[0])+0.5F)*taillePixel()-20.0F, (coordonnee(p3[1])+0.5F)*taillePixel()-20.0F, p3[2]); glEnd(); glPopMatrix(); } static void pixelOpenGL(int x,int y,int z) { float dp = -(discretisation[disc] - discretisation[0])*0.25F; glPushMatrix(); glTranslatef(dp,dp,0.0F); glBegin(GL_QUADS); glVertex3f(taillePixel()*(x-0.0F)-20.0F,taillePixel()*(y-0.0F)-20.0F,z/1000.0F); glVertex3f(taillePixel()*(x+1.0F)-20.0F,taillePixel()*(y-0.0F)-20.0F,z/1000.0F); glVertex3f(taillePixel()*(x+1.0F)-20.0F,taillePixel()*(y+1.0F)-20.0F,z/1000.0F); glVertex3f(taillePixel()*(x-0.0F)-20.0F,taillePixel()*(y+1.0F)-20.0F,z/1000.0F); glEnd(); glPopMatrix(); } ///////////////////////////////////////////////// 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 = coordonnee(p1[0]),y1 = coordonnee(p1[1]),z1 = p1[2]*1000; int x2 = coordonnee(p2[0]),y2 = coordonnee(p2[1]),z2 = p2[2]*1000; int x3 = coordonnee(p3[0]),y3 = coordonnee(p3[1]),z3 = p3[2]*1000; glColor4fv(coul); glPushMatrix(); triangle(x1,y1,z1,x2,y2,z2,x3,y3,z3,pixelOpenGL); glPopMatrix(); } void display(void) { glEnable(GL_DEPTH_TEST); int f11[] = { -10,-20,-10 }; int f12[] = { 20,-10, 13 }; int f13[] = { -20, 20, -7 }; int f21[] = { 20,-20, -2 }; int f22[] = { -20,-10, 7 }; int f23[] = { 10, 20,-14 }; glPolygonMode(GL_FRONT_AND_BACK,(mode == 0) ? GL_FILL : GL_LINE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(20.0F,20.0F,20.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; case 43: disc++; if (disc >= 5) disc = 5; glutPostRedisplay(); break; case 45: disc--; if (disc < 0) disc = 0; glutPostRedisplay(); break; } } int main(int argc,char **argv) { int t = 28; glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(t*8,t*8); glutInitWindowPosition(50,50); glutCreateWindow("ZBuffer - Remplissage des facettes avec calcul du z des pixels"); myinit(); setParametresOrthoBasique(-t,t,-t,t,-4000.0,4000.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); creationMenuBasique(); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }