Le source : TD-SegmentsBresenham3D.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Avril 2003 */
/* Rasterisation de segments de droites */
/* dans un espace Voxel */
/* par des variantes de l'algorithme */
/* de Bresenham */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#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 ligneEn2DetDemiVoxels(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 ) {
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 ;
while ( c2 >= dx ) {
c2 -= dx ;
n++ ;
z += zinc ; }
fonc(x,y,z) ; } }
else {
c1 = c2 = dy / 2 ;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc ;
c1 += dx ;
if ( c1 >= dy ) {
c1 -= dy ;
x += xinc ; }
c2 += dz ;
while ( c2 >= dy ) {
c2 -= dy ;
z += zinc ; }
fonc(x,y,z) ; } }
}
void parcoursEn2DetDemiVoxels(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 ) {
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 ;
while ( c2 >= dx ) {
c2 -= dx ;
n++ ;
z += zinc ; }
fonc(x,y,z) ; } }
else {
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 ;
while ( c2 >= dy ) {
c2 -= dy ;
z += zinc ; }
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 ;
case 3 : ligneEn2DetDemiVoxels(pix,piy,piz,pfx,pfy,pfz,voxel1);
glEnable(GL_LIGHTING);
ligneEn2DetDemiVoxels(pix,piy,piz,pfx,pfy,pfz,voxel2);
glDisable(GL_LIGHTING);
break ;
case 4 : parcoursEn2DetDemiVoxels(pix,piy,piz,pfx,pfy,pfz,lim,voxel1);
glEnable(GL_LIGHTING);
parcoursEn2DetDemiVoxels(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)%5 ;
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);
}