Fichier source : Bresenham.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2007 */
/* Rasterisation de segments de droites */
/* sur un ecran bitmap */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
/* Variables globales de definition de couleurs */
static float noir[] = { 0.0F,0.0F,0.0F,1.0F };
static float rouge[] = { 1.0F,0.0F,0.0F,1.0F };
static float bleu[] = { 0.0F,0.0F,1.0F,1.0F };
static float vertFonce[] = { 0.0F,0.5F,0.0F,1.0F };
/* Variables globales de gestion */
/* de l'interactivite clavier et souris */
static int clic = 0;
static int mx;
static int my;
static float rx = 0.0F;
static float ry = 0.0F;
static float zoom = 1.0F;
struct coordonnees {
int x;
int y;
int z;
int t; };
struct segment {
coordonnees pi;
coordonnees pf; };
struct facette {
coordonnees p1;
coordonnees p2;
coordonnees p3; };
static int aff = 0;
static int mode = 0;
static segment seg1 = { { -9, 2, 3,1 },
{ 8, 8, -4,1 } };
static segment seg2 = { { 3, -9, -6,1 },
{ 9, 6, 5,1 } };
static segment seg3 = { { -8, -2,-10,1 },
{ -1, -7, 9,1 } };
static facette f = { { -9, 2, 0,1 },
{ 9, 6, 0,1 },
{ 6, -8, 0,1 } };
void pixel(int x,int y,float *c) {
glColor4fv(c);
glBegin(GL_QUADS);
glVertex2i(x,y);
glVertex2i(x+1,y);
glVertex2i(x+1,y+1);
glVertex2i(x,y+1);
glEnd();
glColor4fv(noir);
glBegin(GL_LINE_LOOP);
glVertex2i(x,y);
glVertex2i(x+1,y);
glVertex2i(x+1,y+1);
glVertex2i(x,y+1);
glEnd();
}
void pixel3D(int x,int y,int z,float *c) {
glColor4fv(c);
glPushMatrix();
glTranslatef(x+0.5F,y+0.5F,z+0.5F);
glutWireCube(1.0);
glPopMatrix();
}
void lignePixels(int xi,int yi,int xf,int yf,float *c) {
int i,cumul;
int x = xi;
int y = yi;
int dx = xf - xi;
int dy = yf - yi;
int xinc = ( dx > 0 ) ? 1 : -1;
int yinc = ( dy > 0 ) ? 1 : -1;
dx = abs(dx);
dy = abs(dy);
pixel(x,y,c);
if ( dx > dy ) {
cumul = dx / 2;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc;
cumul += dy;
if (cumul >= dx) {
cumul -= dx;
y += yinc; }
pixel(x,y,c); } }
else {
cumul = dy / 2;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc;
cumul += dx;
if ( cumul >= dy ) {
cumul -= dy;
x += xinc; }
pixel(x,y,c); } }
}
void lignePixels3D(int xi,int yi,int xf,int yf,float *c) {
int i,cumul;
int x = xi;
int y = yi;
int dx = xf - xi;
int dy = yf - yi;
int xinc = ( dx > 0 ) ? 1 : -1;
int yinc = ( dy > 0 ) ? 1 : -1;
dx = abs(dx);
dy = abs(dy);
pixel3D(x,y,0,c);
if ( dx > dy ) {
cumul = dx / 2;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc;
cumul += dy;
if (cumul >= dx) {
cumul -= dx;
y += yinc; }
pixel3D(x,y,0,c); } }
else {
cumul = dy / 2;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc;
cumul += dx;
if ( cumul >= dy ) {
cumul -= dy;
x += xinc; }
pixel3D(x,y,0,c); } }
}
void dessineSegment(float *c,coordonnees *pi,coordonnees *pf) {
glColor4fv(c);
glLineWidth(3.0);
glBegin(GL_LINES);
glVertex3d(pi->x+0.5,pi->y+0.5,0.5);
glVertex3d(pf->x+0.5,pf->y+0.5,0.5);
glEnd();
glLineWidth(1.0);
}
void dessineSegment(float *c,segment *s) {
dessineSegment(c,&s->pi,&s->pf);
}
void dessineQuadrillage(float *c,int n) {
int i;
glColor4fv(c);
glBegin(GL_LINES);
for ( i = -n ; i <= n ; i++ ) {
glVertex2d(-n,i);
glVertex2d(n,i); }
for ( i = -n ; i <= n ; i++ ) {
glVertex2d(i,-n);
glVertex2d(i,n); }
glEnd();
}
void display1() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
switch (aff) {
case 0 : dessineSegment(rouge,&seg1);
dessineSegment(rouge,&seg2);
dessineSegment(rouge,&seg3);
break;
case 1 : dessineQuadrillage(bleu,11);
dessineSegment(rouge,&seg1);
dessineSegment(rouge,&seg2);
dessineSegment(rouge,&seg3);
break;
case 2 : dessineQuadrillage(bleu,11);
lignePixels(seg1.pi.x,seg1.pi.y,
seg1.pf.x,seg1.pf.y,
vertFonce);
lignePixels(seg2.pi.x,seg2.pi.y,
seg2.pf.x,seg2.pf.y,
vertFonce);
lignePixels(seg3.pi.x,seg3.pi.y,
seg3.pf.x,seg3.pf.y,
vertFonce);
dessineSegment(rouge,&seg1);
dessineSegment(rouge,&seg2);
dessineSegment(rouge,&seg3);
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void dessineSegment3D(float *c,coordonnees *pi,coordonnees *pf) {
glColor4fv(c);
glLineWidth(3.0);
glBegin(GL_LINES);
glVertex3d(pi->x+0.5,pi->y+0.5,pi->z+0.5);
glVertex3d(pf->x+0.5,pf->y+0.5,pf->z+0.5);
glEnd();
glLineWidth(1.0);
}
void dessineSegment3D(float *c,segment *s) {
dessineSegment(c,&s->pi,&s->pf);
}
void dessineQuadrillage3D(float *c,int n) {
glColor4fv(c);
glPushMatrix();
glutWireCube(2*n);
glPopMatrix();
}
void display2() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(rx,1.0F,0.0F,0.0F);
glRotatef(ry,0.0F,1.0F,0.0F);
glScalef(zoom,zoom,zoom);
switch (aff) {
case 0 : dessineSegment3D(rouge,&seg1);
dessineSegment3D(rouge,&seg2);
dessineSegment3D(rouge,&seg3);
break;
case 1 : dessineQuadrillage3D(bleu,11);
dessineSegment3D(rouge,&seg1);
dessineSegment3D(rouge,&seg2);
dessineSegment3D(rouge,&seg3);
break;
case 2 : dessineQuadrillage3D(bleu,11);
lignePixels3D(seg1.pi.x,seg1.pi.y,
seg1.pf.x,seg1.pf.y,
vertFonce);
lignePixels3D(seg2.pi.x,seg2.pi.y,
seg2.pf.x,seg2.pf.y,
vertFonce);
lignePixels3D(seg3.pi.x,seg3.pi.y,
seg3.pf.x,seg3.pf.y,
vertFonce);
dessineSegment3D(rouge,&seg1);
dessineSegment3D(rouge,&seg2);
dessineSegment3D(rouge,&seg3);
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void myinit() {
glClearColor(0.8F,0.8F,0.8F,1.0F);
}
/* Fonction executee lors d'un changement */
/* de la taille de la fenetre OpenGL */
/* Configuration d'une camera de visualisation */
/* en projection parallele */
void reshape(int tx,int ty) {
glViewport(0,0,tx,ty);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((-12.0*tx)/ty,(12.0*tx)/ty,-12.0,12.0,-20.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Fonction executee lors d'un clic de souris */
/* dans la fenetre */
void mouse(int bouton,int etat,int x,int y) {
if ( bouton == GLUT_LEFT_BUTTON ) {
if ( etat == GLUT_DOWN ) {
clic = 1;
mx = x;
my = y; }
if ( etat == GLUT_UP ) {
clic = 0; } }
}
/* Fonction executee lors d'un deplacement */
/* de la souris sur la fenetre */
/* avec un bouton appuye */
void motion(int x,int y) {
if ( clic ) {
ry += (x-mx);
rx += (y-my);
mx = x;
my = y;
glutPostRedisplay(); }
}
/* Fonction executee lors de la frappe */
/* d'une touche alphanumerique du clavier */
void key(unsigned char key,int x,int y) {
switch ( key ) {
case 43 : zoom *= 1.01F;
glutPostRedisplay();
break;
case 45 : zoom /= 1.01F;
glutPostRedisplay();
break;
case 0x1B : exit(0);
break;
case 0x20 : mode = (mode+1)%2;
switch (mode) {
case 0 : glutDisplayFunc(display1);
glutMouseFunc(NULL);
glutMotionFunc(NULL);
aff = 0;
break;
case 1 : glutDisplayFunc(display2);
glutMouseFunc(mouse);
glutMotionFunc(motion);
aff = 0;
break; }
glutPostRedisplay();
break;
case 0x0D : aff = (aff+1)%3;
glutPostRedisplay();
break; }
}
/* Fonction principale */
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(350,350);
glutInitWindowPosition(50,50);
glutCreateWindow("Rasterisation selon Bresenham");
myinit();
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc(display1);
glutMainLoop();
return(0);
}