L'exécutable

Bresenham-01.png (5604 octets) Bresenham-02.png (8057 octets)

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);
}

RETOUR