/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Mai 2004 */ /* Rasterisation de segments de droites */ /* dans un espace Voxel */ /* par des variantes de l'algorithme */ /* de Bresenham */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" static int aff = 0 ; static int lim = 0 ; static int pix = -9 ; static int piy = -4 ; static int piz = -13 ; static int pfx = 8 ; static int pfy = 3 ; static int pfz = 15 ; void myinit(void) { GLfloat light_position0[] = { 1.0F,1.0F,1.0F,0.0F }; glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT0,GL_SPECULAR,couleurBlanc()); glLightfv(GL_LIGHT0,GL_POSITION,light_position0); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); } void voxel1(int x,int y,int z) { glColor4fv(couleurBlanc(0.5F)) ; glBegin(GL_LINES) ; glVertex3i(x,y,z) ; glVertex3i(x+1,y,z) ; glVertex3i(x,y+1,z) ; glVertex3i(x+1,y+1,z) ; glVertex3i(x,y,z+1) ; glVertex3i(x+1,y,z+1) ; glVertex3i(x,y+1,z+1) ; glVertex3i(x+1,y+1,z+1) ; glVertex3i(x,y,z) ; glVertex3i(x,y+1,z) ; glVertex3i(x+1,y,z) ; glVertex3i(x+1,y+1,z) ; glVertex3i(x,y,z+1) ; glVertex3i(x,y+1,z+1) ; glVertex3i(x+1,y,z+1) ; glVertex3i(x+1,y+1,z+1) ; glVertex3i(x,y,z) ; glVertex3i(x,y,z+1) ; glVertex3i(x+1,y,z) ; glVertex3i(x+1,y,z+1) ; glVertex3i(x,y+1,z) ; glVertex3i(x,y+1,z+1) ; glVertex3i(x+1,y+1,z) ; glVertex3i(x+1,y+1,z+1) ; glEnd() ; } void voxel2(int x,int y,int z) { glPushMatrix() ; glTranslatef(x+0.5F,y+0.5F,z+0.5F) ; glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurRouge(0.5F)) ; glEnable(GL_CULL_FACE); glutSolidCube(1.0) ; glDisable(GL_CULL_FACE); glPopMatrix() ; } void ligneVoxels(int xi,int yi,int zi, int xf,int yf,int zf, void (*fonc) (int x,int y,int z)) { int dx,dy,dz,i,xinc,yinc,zinc,c1,c2,x,y,z ; x = xi ; y = yi ; z = zi ; dx = xf - xi ; dy = yf - yi ; dz = zf - zi ; xinc = ( dx > 0 ) ? 1 : -1 ; yinc = ( dy > 0 ) ? 1 : -1 ; zinc = ( dz > 0 ) ? 1 : -1 ; dx = abs(dx) ; dy = abs(dy) ; dz = abs(dz) ; fonc(x,y,z) ; if ( ( dx > dy ) && ( dx > dz ) ) { c1 = c2 = dx / 2 ; for ( i = 1 ; i <= dx ; i++ ) { x += xinc ; c1 += dy ; int n = 0 ; if ( c1 >= dx ) { c1 -= dx ; n++ ; y += yinc ; } c2 += dz ; if ( c2 >= dx ) { c2 -= dx ; n++ ; z += zinc ; } fonc(x,y,z) ; } } else if ( ( dy > dx ) && ( dy > dz ) ) { c1 = c2 = dy / 2 ; for ( i = 1 ; i <= dy ; i++ ) { y += yinc ; c1 += dx ; if ( c1 >= dy ) { c1 -= dy ; x += xinc ; } c2 += dz ; if ( c2 >= dy ) { c2 -= dy ; z += zinc ; } fonc(x,y,z) ; } } else { c1 = c2 = dz / 2 ; for ( i = 1 ; i <= dz ; i++ ) { z += zinc ; c1 += dy ; if ( c1 >= dz ) { c1 -= dz ; y += yinc ; } c2 += dx ; if ( c2 >= dz ) { c2 -= dz ; x += xinc ; } fonc(x,y,z) ; } } } void parcoursVoxels(int xi,int yi,int zi, int xf,int yf,int zf, int lim,void (*fonc) (int x,int y,int z)) { int dx,dy,dz,i,xinc,yinc,zinc,c1,c2,x,y,z ; x = xi ; y = yi ; z = zi ; dx = xf - xi ; dy = yf - yi ; dz = zf - zi ; xinc = ( dx > 0 ) ? 1 : -1 ; yinc = ( dy > 0 ) ? 1 : -1 ; zinc = ( dz > 0 ) ? 1 : -1 ; dx = abs(dx) ; dy = abs(dy) ; dz = abs(dz) ; fonc(x,y,z) ; if ( ( dx > dy ) && ( dx > dz ) ) { c1 = c2 = dx / 2 ; for ( i = 1 ; ( i <= dx ) && ( i <= lim ) ; i++ ) { x += xinc ; c1 += dy ; int n = 0 ; if ( c1 >= dx ) { c1 -= dx ; n++ ; y += yinc ; } c2 += dz ; if ( c2 >= dx ) { c2 -= dx ; n++ ; z += zinc ; } fonc(x,y,z) ; } } else if ( ( dy > dx ) && ( dy > dz ) ) { c1 = c2 = dy / 2 ; for ( i = 1 ; ( i <= dy ) && ( i <= lim ) ; i++ ) { y += yinc ; c1 += dx ; if ( c1 >= dy ) { c1 -= dy ; x += xinc ; } c2 += dz ; if ( c2 >= dy ) { c2 -= dy ; z += zinc ; } fonc(x,y,z) ; } } else { c1 = c2 = dz / 2 ; for ( i = 1 ; ( i <= dz ) && ( i <= lim ) ; i++ ) { z += zinc ; c1 += dy ; if ( c1 >= dz ) { c1 -= dz ; y += yinc ; } c2 += dx ; if ( c2 >= dz ) { c2 -= dz ; x += xinc ; } fonc(x,y,z) ; } } } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix() ; manipulateurSouris(); manipulateurClavier(); glLineWidth(4.0) ; glColor4fv(couleurBleu()) ; glBegin(GL_LINES) ; glVertex3f(pix+0.5F,piy+0.5F,piz+0.5F) ; glVertex3f(pfx+0.5F,pfy+0.5F,pfz+0.5F) ; glEnd() ; glLineWidth(1.0) ; switch ( aff ) { case 1 : ligneVoxels(pix,piy,piz,pfx,pfy,pfz,voxel1); glEnable(GL_LIGHTING); ligneVoxels(pix,piy,piz,pfx,pfy,pfz,voxel2); glDisable(GL_LIGHTING); break ; case 2 : parcoursVoxels(pix,piy,piz,pfx,pfy,pfz,lim,voxel1); glEnable(GL_LIGHTING); parcoursVoxels(pix,piy,piz,pfx,pfy,pfz,lim,voxel2); glDisable(GL_LIGHTING); break ; } glPopMatrix() ; glFlush(); glutSwapBuffers(); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case '1' : pix--; glutPostRedisplay(); break; case '4' : pix++; glutPostRedisplay(); break; case '2' : piy--; glutPostRedisplay(); break; case '5' : piy++; glutPostRedisplay(); break; case '3' : piz--; glutPostRedisplay(); break; case '6' : piz++; glutPostRedisplay(); break; case 0x0D : lim = 0 ; aff = (aff+1)%3 ; glutPostRedisplay(); break; case 32 : lim = (lim+1)%40 ; glutPostRedisplay(); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(400,220); glutInitWindowPosition(50,50); glutCreateWindow("Un segment de voxels par Bresenham"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-6.0,6.0,-6.0,6.0,-500.0,500.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }