L'exécutable

 

 

Le source : RasterisationTriangle.cpp

/* Un programme OpenGL de rasterisation         */
/* d'un triangle                                */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2009                                */

#include <stdlib.h>
#include <stdio.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

typedef struct position2D {
  int x;
  int y;
  int w; } position2D;
typedef struct triangle {
  position2D p1;
  position2D p2;
  position2D p3; } triangle;

static int scn = 0;
static triangle t1 =
  { {  -20, 110 },
    { -100, -10 },
    {   90, -90 } };
static triangle t2 =
  { {  -20, 110 },
    { -100, -90 },
    {   90, -30 } };
static triangle t = t1;

/* Scene dessinee                               */

void ligne(position2D *pi,position2D *pf) {
  int i,cumul;
  int x = pi->x;
  int y = pi->y;
  int dx = pf->x - pi->x;
  int dy = pf->y - pi->y;
  int xinc = ( dx > 0 ) ? 1 : -1;
  int yinc = ( dy > 0 ) ? 1 : -1;
  dx = abs(dx);
  dy = abs(dy);
  glBegin(GL_POINTS);
  glVertex2i(x,y);
  if ( dx > dy ) {
    cumul = dx>>1;
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc;
      cumul += dy;
      if (cumul >= dx) {
        cumul -= dx;
        y += yinc; }
      glVertex2i(x,y); } }
    else {
    cumul = dy / 2;
    for ( i = 1 ; i <= dy ; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      glVertex2i(x,y); } }
  glEnd();
}

void scene1(void) {
  glPushMatrix();
  glColor3f(1.0F,0.0F,0.0F);
  ligne(&t.p1,&t.p2);
  glColor3f(0.0F,1.0F,0.0F);
  ligne(&t.p2,&t.p3);
  glColor3f(0.0F,0.0F,1.0F);
  ligne(&t.p3,&t.p1);
  glPopMatrix();
}

void tourneSensMontre(triangle *t) {
  position2D p = t->p1;
  t->p1 = t->p2;
  t->p2 = t->p3;
  t->p3 = p;
}

void tourneInverseSensMontre(triangle *t) {
  position2D p = t->p1;
  t->p1 = t->p3;
  t->p3 = t->p2;
  t->p2 = p;
}

void ordonne(triangle *t) {
  if ( ( t->p1.y <= t->p2.y ) && ( t->p1.y <= t->p3.y ) )
    return;
  if ( t->p2.y <= t->p3.y )
    tourneSensMontre(t);
    else
    tourneInverseSensMontre(t);
}

void bord(int *tx,int ymin,position2D *pi,position2D *pf) {
  int i,cumul;
  int x = pi->x;
  int y = pi->y;
  int dx = pf->x - pi->x;
  int dy = pf->y - pi->y;
  int xinc = ( dx > 0 ) ? 1 : -1;
  int yinc = ( dy > 0 ) ? 1 : -1;
  dx = abs(dx);
  dy = abs(dy);
  tx[y-ymin] = x;
  if ( dx > dy ) {
    cumul = dx>>1;
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc;
      cumul += dy;
      if (cumul >= dx) {
        cumul -= dx;
        y += yinc; }
      tx[y-ymin] = x; } }
    else {
    cumul = dy / 2;
    for ( i = 1 ; i <= dy ; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      tx[y-ymin] = x; } }
}

void triangle(triangle *t) {
  ordonne(t);
  int ymin = t->p1.y;
  int ymax;
  int type;
  if ( t->p2.y > t->p3.y ) {
    ymax = t->p2.y;
    type = 0; }
    else {
    ymax = t->p3.y;
    type = 1; }
  int ydim = ymax-ymin+1;
  //printf("%d %d\n",t->p1.x,t->p1.y);
  //printf("%d %d\n",t->p2.x,t->p2.y);
  //printf("%d %d\n",t->p3.x,t->p3.y);
  //printf("%d\n",ymin);
  //printf("%d\n",ymax);
  //printf("%d\n",type);
  int *bd =(int *) calloc(ydim,sizeof(int));
  int *bg =(int *) calloc(ydim,sizeof(int));
  switch (type) {
    case 0 :
      bord(bd,ymin,&t->p1,&t->p2);
      bord(bg,ymin,&t->p2,&t->p3);
      bord(bg,ymin,&t->p3,&t->p1);
      break;
    case 1 :
      bord(bd,ymin,&t->p1,&t->p2);
      bord(bd,ymin,&t->p2,&t->p3);
      bord(bg,ymin,&t->p3,&t->p1);
      break; }
  //for ( int i = 0 ; i < ydim ; i++ )
  //  printf("%4d %4d %4d\n",i,bg[i],bd[i]);
  glBegin(GL_LINES);
  for ( int y = ymin ; y <= ymax ; y++ ) {
    glVertex2i(bg[y-ymin],y);
    glVertex2i(bd[y-ymin],y); }
  glEnd();
  free(bg);
  free(bd);
}

void scene2(void) {
  glPushMatrix();
  glColor3f(0.5F,0.5F,0.5F);
  triangle(&t);
  glPopMatrix();
}

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin                      */

void display(void) {
  glClearColor(1.0F,1.0F,1.0F,1.0F);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  if ( scn == 0 )
    scene1();
    else
    scene2();
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */

void reshape(int x,int y) {
  glViewport(0,0,x,y); 
  glMatrixMode(GL_PROJECTION) ;
  glLoadIdentity() ;
  glOrtho(-x/2,-x/2+x,-y/2,-y/2+y,-300.0,300.0) ;
  glMatrixMode(GL_MODELVIEW) ;
  glLoadIdentity() ;
}

/* Fonction executee lors de l'appui            */
/* d'une touche alphanumerique du clavier       */

void keyboard(unsigned char key,int x,int y) {
  switch (key) {
    case 0x20 :
      { static int tr = 0;
        tr = (tr+1)%2;
        if ( tr == 1 )
          t = t2;
          else
          t = t1; }
      glutPostRedisplay();
      break;
    case 0x0D :
      scn = !scn;
      glutPostRedisplay();
      break;
    case 0x1B :
      exit(0);
      break; }
}

/* Fonction principale                          */

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(240,240); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Rasterisation d'un triangle"); 
  glutKeyboardFunc(keyboard);
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

RETOUR