L'exécutable

Ci-dessous, mise en évidence sur le coté supérieur de la disparition de la ligne supérieure de pixels gauches liée au sens de parcourt du coté.

Le source : SegmentEtFacette2D.cpp

/* Auteur: Nicolas JANEY         */
/* nicolas.janey@univ-fcomte.fr  */
/* Novembre 2005                 */
/* Illustration du remplissage   */
/* d'une facette 2D              */

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

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

#include "ModuleCouleurs.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
#include "ModuleFont.h"

#define YMAX 40
#define XMAX 40

static int aff = 0;
static int yy = 0;
static int b = 1;
static int f = 0;
static int sx = 0;
static int sy = 0;

static int x1 = 35;
static int y1 = 22;
static int x2 = 11;
static int y2 = 37;
static int x3 = 3;
static int y3 = 4;

static int f1;
static int fv;

struct pix {
  int x;
  int y; } pix;

int *ligneCote(int xi,int yi,int xf,int yf) {
  int *px =(int *) calloc(YMAX,sizeof(int));
  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);
  px[y] = x;
  if ( dx > dy ) {
    cumul = dx / 2;
    for ( i = 1; i <= dx; i++ ) {
      x += xinc;
      cumul += dy;
      if (cumul >= dx) {
        cumul -= dx;
        y += yinc; }
      px[y] = x; } }
    else {
    cumul = dy / 2;
    for ( i = 1; i <= dy; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      px[y] = x; } }
  return(px);
}

void myinit() {
  glDepthFunc(GL_LESS);
  glShadeModel(GL_SMOOTH);
  glClearColor(0.8F,0.8F,0.8F,1.0F);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);
}

void bordFacette(int x1,int y1,int x2,int y2,int x3,int y3,float *coul) {
  glPushMatrix();
  glColor4fv(coul);
  glLineWidth(3.0);
  glBegin(GL_LINE_LOOP);
  glVertex2f(x1+0.5F,y1+0.5F);
  glVertex2f(x2+0.5F,y2+0.5F);
  glVertex2f(x3+0.5F,y3+0.5F);
  glEnd();
  glLineWidth(1.0);
  glPopMatrix();
}

void facette(int x1,int y1,int x2,int y2,int x3,int y3,float *coul) {
  glPushMatrix();
  glColor4fv(coul);
  glBegin(GL_TRIANGLES);
  glVertex2f(x1+0.5F,y1+0.5F);
  glVertex2f(x2+0.5F,y2+0.5F);
  glVertex2f(x3+0.5F,y3+0.5F);
  glEnd();
  glPopMatrix();
}

void pixel(int x,int y,float *coul) {
  glColor3fv(coul);
  glBegin(GL_QUADS);
  glVertex2f(x,y);
  glVertex2f(x+1,y);
  glVertex2f(x+1,y+1);
  glVertex2f(x,y+1);
  glEnd();
  glColor3fv(couleurNoir());
  glBegin(GL_LINE_LOOP);
  glVertex2f(x,y);
  glVertex2f(x+1,y);
  glVertex2f(x+1,y+1);
  glVertex2f(x,y+1);
  glEnd();
}

void pixel(int x,int y) {
  glBegin(GL_QUADS);
  glVertex2f(x,y);
  glVertex2f(x+1,y);
  glVertex2f(x+1,y+1);
  glVertex2f(x,y+1);
  glEnd();
}

void ligneDiscrete(int y,int x1,int x2,float *coul) {
  if ( x2 != -100 ) {
    int i;
    int x = x1;
    int dx = x2 - x1;
    int xinc = ( dx > 0 ) ? 1 : -1;
    dx = abs(dx);
    for ( i = 0; i <= dx; i++ ) {
      pixel(x,y,coul);
      x += xinc; } }
}

void echange(int *x1,int *y1,int *x2,int *y2) {
  float aux = *x1;
  *x1 = *x2;
  *x2 = aux;
  aux = *y1;
  *y1 = *y2;
  *y2 = aux;
}

int typeFacette(int x1,int y1,int x2,int y2,int x3,int y3) {
  int dx2 = x2-x1;
  int dy2 = y2-y1;
  int dx3 = x3-x1;
  int dy3 = y3-y1;
  int t = dy3*dx2-dy2-dx3;
  return((t > 0) ? 1 : 0);
}

void facetteDiscrete(int x1,int y1,int x2,int y2,int x3,int y3,float *coul) {
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  if ( y2 > y3 )
    echange(&x2,&y2,&x3,&y3);
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  int type = typeFacette(x1,y1,x2,y2,x3,y3);
  int *px1 = ligneCote(x1,y1,x2,y2);
  int *px2 = ligneCote(x2,y2,x3,y3);
  int *px3 = ligneCote(x1,y1,x3,y3);
  int y;
  for ( y = y1 ; y < y2 ; y++ )
    ligneDiscrete(y,px1[y],px3[y],coul);
  for ( ; y <= y3 ; y++ )
    ligneDiscrete(y,px2[y],px3[y],coul);
  free(px3);
  free(px2);
  free(px1);
}

struct pix *lignePixels(int xi,int yi,int xf,int yf,int *t) {
  struct pix *p;
  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);
  if ( dx > dy ) {
    p =(struct pix *) calloc(*t = dx+1,sizeof(struct pix));
    p[0].x = x;
    p[0].y = y;
    int ind = 1;
    cumul = dx / 2;
    for ( i = 1; i <= dx; i++ ) {
      x += xinc;
      cumul += dy;
      if (cumul >= dx) {
        cumul -= dx;
        y += yinc; }
      p[ind].x = x;
      p[ind].y = y;
      ind++; } }
    else {
    p =(struct pix *) calloc(*t = dy+1,sizeof(struct pix));
    p[0].x = x;
    p[0].y = y;
    int ind = 1;
    cumul = dy / 2;
    for ( i = 1; i <= dy; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      p[ind].x = x;
      p[ind].y = y;
      ind++; } }
  return(p);
}

void lignePixels(int xi,int yi,int xf,int yf,float *coul) {
  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,coul);
  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,coul); } }
    else {
    cumul = dy / 2;
    for ( i = 1; i <= dy; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      pixel(x,y,coul); } }
}

void coteFacette(int x1,int y1,int x2,int y2,float *coul) {
  glPushMatrix();
  lignePixels(x1,y1,x2,y2,coul);
  glPopMatrix();
}

void facetteDiscreteTrame(int x1,int y1,int x2,int y2,int x3,int y3,
                          int yy,
                          float *c,float *c1,float *c2,float *c3) {
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  if ( y2 > y3 )
    echange(&x2,&y2,&x3,&y3);
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  int type = typeFacette(x1,y1,x2,y2,x3,y3);
  int *px1 = ligneCote(x1,y1,x2,y2);
  int *px2 = ligneCote(x2,y2,x3,y3);
  int *px3 = ligneCote(x1,y1,x3,y3);
  yy += y1;
  int y;
  for ( y = y1 ; ( y < y2 ) && ( y <= yy) ; y++ )
    ligneDiscrete(y,px1[y],px3[y],c);
  for ( ; ( y <= y3 ) && ( y <= yy) ; y++ )
    ligneDiscrete(y,px2[y],px3[y],c);
  free(px3);
  free(px2);
  free(px1);
}

void pixelsExtremesFacette(int x1,int y1,int x2,int y2,int x3,int y3,float *coul) {
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  if ( y2 > y3 )
    echange(&x2,&y2,&x3,&y3);
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  int type = typeFacette(x1,y1,x2,y2,x3,y3);
  int *px1 = ligneCote(x1,y1,x2,y2);
  int *px2 = ligneCote(x2,y2,x3,y3);
  int *px3 = ligneCote(x1,y1,x3,y3);
  int y;
  for ( y = y1 ; y < y2 ; y++ ) {
    pixel(px1[y],y,coul);
    pixel(px3[y],y,coul); }
  for ( ; y <= y3 ; y++ ) {
    pixel(px2[y],y,coul);
    pixel(px3[y],y,coul); }
  free(px3);
  free(px2);
  free(px1);
}

void cotesFacette(int x1,int y1,int x2,int y2,int x3,int y3,
                  float *c1,float *c2,float *c3) {
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  if ( y2 > y3 )
    echange(&x2,&y2,&x3,&y3);
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  coteFacette(x1,y1,x2,y2,c1);
  coteFacette(x1,y1,x3,y3,c2);
  coteFacette(x2,y2,x3,y3,c3);
}

void display() {
  switch (f) {
    case 0 : x1 = 35;
             y1 = 22;
             x2 = 11;
             y2 = 37;
             x3 =  3;
             y3 =  4;
             break;
    case 1 : x1 = 38;
             y1 = 19;
             x2 = 21;
             y2 = 22;
             x3 =  3;
             y3 = 14;
             break;
    case 2 : x1 = 38;
             y1 = 24;
             x2 = 21;
             y2 = 19;
             x3 =  3;
             y3 = 31;
             break; }
  if ( sx ) {
    y1 = YMAX/2+(YMAX/2-y1);
    y2 = YMAX/2+(YMAX/2-y2);
    y3 = YMAX/2+(YMAX/2-y3); }
  if ( sy ) {
    x1 = XMAX/2+(XMAX/2-x1);
    x2 = XMAX/2+(XMAX/2-x2);
    x3 = XMAX/2+(XMAX/2-x3); }
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  switch (aff) {
    case 0 : facette(x1,y1,x2,y2,x3,y3,couleurRouge());
             bordFacette(x1,y1,x2,y2,x3,y3,couleurNoir());
             break;
    case 1 : coteFacette(x1,y1,x2,y2,couleurRouge());
             break;
    case 2 : coteFacette(x1,y1,x3,y3,couleurVert());
             break;
    case 3 : coteFacette(x2,y2,x3,y3,couleurBleu());
             break;
    case 4 : cotesFacette(x1,y1,x2,y2,x3,y3,
                          couleurRouge(),
                          couleurVert(),
                          couleurBleu());
             break;
    case 5 : pixelsExtremesFacette(x1,y1,x2,y2,x3,y3,
                                   couleurMagenta());
             break;
    case 6 : facetteDiscreteTrame(x1,y1,x2,y2,x3,y3,
                                  yy,
                                  couleurJaune(),
                                  couleurVert(),
                                  couleurRouge(),
                                  couleurBleu());
             if ( b ) {
               coteFacette(x1,y1,x2,y2,couleurRouge());
               coteFacette(x1,y1,x3,y3,couleurVert());
               coteFacette(x2,y2,x3,y3,couleurBleu()); }
             break;
    case 7 : facetteDiscrete(x1,y1,x2,y2,x3,y3,couleurJaune());
             if ( b ) {
               coteFacette(x1,y1,x2,y2,couleurRouge());
               coteFacette(x1,y1,x3,y3,couleurVert());
               coteFacette(x2,y2,x3,y3,couleurBleu()); }
             bordFacette(x1,y1,x2,y2,x3,y3,couleurNoir());
             break; }
  glPopMatrix();
  glPushMatrix();
  glDisable(GL_DEPTH_TEST);
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void postRedisplay(void) {
  glutPostWindowRedisplay(f1);
  glutPostWindowRedisplay(fv);
}

void key(unsigned char key,int x,int y) {
  switch ( key ) {
    case 'y'  :  
    case 'Y'  : sy = !sy;
                postRedisplay();
                break;
    case 'x'  :
    case 'X'  : sx = !sx;
                postRedisplay();
                break;
    case 'f'  : 
    case 'F'  : f = (f+1)%3;
                postRedisplay();
                break;
    case 'b'  : 
    case 'B'  : b = !b;
                postRedisplay();
                break;
    case 0x0D : yy = 0;
                aff = (aff+1)%8;
                postRedisplay();
                break;
    case 43   : aff = (aff+1)%8;
                postRedisplay();
                break;
    case 45   : aff = (aff+7)%8;
                postRedisplay();
                break;
    case 32   : yy = (yy+1)%YMAX;
                postRedisplay();
                break;
    case 0x1B : exit(0);
                break; }
}


static int vmin(int v1,int v2) {
  return(( v1 < v2 ) ? v1 : v2);
}

static int vmax(int v1,int v2) {
  return(( v1 > v2 ) ? v1 : v2);
}

int pixelsExtremesFacette(int x1,int y1,int x2,int y2,int x3,int y3,float pos) {
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  if ( y2 > y3 )
    echange(&x2,&y2,&x3,&y3);
  if ( y1 > y2 )
    echange(&x1,&y1,&x2,&y2);
  int *px1 = ligneCote(x1,y1,x2,y2);
  int *px2 = ligneCote(x2,y2,x3,y3);
  int *px3 = ligneCote(x1,y1,x3,y3);
  int y;
  for ( y = y1 ; y < y2 ; y++ ) {
    placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
    int mn = min(px1[y],px3[y]);
    int mx = max(px1[y],px3[y]);
    simpleBitmapOutput(1,REGULAR6x10,"%2d   %3d %3d",y,mn,mx);
    pos += 1.0F; }
  for ( ; y <= y3 ; y++ ) {
    placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
    int mn = min(px2[y],px3[y]);
    int mx = max(px2[y],px3[y]);
    simpleBitmapOutput(1,REGULAR6x10,"%2d   %3d %3d",y,mn,mx);
    pos += 1.0F; }
  free(px3);
  free(px2);
  free(px1);
  return(y3-y1+1);
}

void displayV(void) {
  glClearColor(0.8F,0.8F,0.8F,1.0F);
  glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  float pos = 1.0F;
  glColor4fv(couleurNoir());
  placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
  simpleBitmapOutput(1,REGULAR8x13,"SOMMETS");
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
  simpleBitmapOutput(1,REGULAR6x10,"P1 : %3d %3d",x1,y1);
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
  simpleBitmapOutput(1,REGULAR6x10,"P2 : %3d %3d",x2,y2);
  pos += 1.0F;
  placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
  simpleBitmapOutput(1,REGULAR6x10,"P3 : %3d %3d",x3,y3);
  pos += 1.5F;
  switch ( aff ) {
    case 0 :
    case 4 : 
    case 7 : glutReshapeWindow(85,60);
             break;
    case 1 : { int t;
               struct pix *p = lignePixels(x1,y1,x2,y2,&t);
               glutReshapeWindow(85,80+(t+1)*14);
               glColor4fv(couleurRougeFonce());
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR8x13,"PIXELS");
               pos += 1.0F;
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR6x10,"       x   y");
               pos += 1.0F;
               for ( int i = 0 ; i < t ; i++ ) {
                 placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
                 simpleBitmapOutput(1,REGULAR6x10,"%2d   %3d %3d",i,p[i].x,p[i].y);
                 pos += 1.0F; }
               free(p); }
             break;
    case 2 : { int t;
               struct pix *p = lignePixels(x1,y1,x3,y3,&t);
               glutReshapeWindow(85,80+(t+1)*14);
               glColor4fv(couleurVertFonce());
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR8x13,"PIXELS");
               pos += 1.0F;
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR6x10,"       x   y");
               pos += 1.0F;
               for ( int i = 0 ; i < t ; i++ ) {
                 placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
                 simpleBitmapOutput(1,REGULAR6x10,"%2d   %3d %3d",i,p[i].x,p[i].y);
                 pos += 1.0F; }
               free(p); }
             break;
    case 3 : { int t;
               struct pix *p = lignePixels(x2,y2,x3,y3,&t);
               glutReshapeWindow(85,80+(t+1)*14);
               glColor4fv(couleurBleu());
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR8x13,"PIXELS");
               pos += 1.0F;
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR6x10,"       x   y");
               pos += 1.0F;
               for ( int i = 0 ; i < t ; i++ ) {
                 placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
                 simpleBitmapOutput(1,REGULAR6x10,"%2d   %3d %3d",i,p[i].x,p[i].y);
                 pos += 1.0F; }
               free(p); }
             break;
    case 5 : { glColor3fv(couleurMagentaFonce());
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR8x13,"EXTREMES");
               pos += 1.0F;
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR6x10," y    xi  xf");
               pos += 1.0F;
               int h = pixelsExtremesFacette(x1,y1,x2,y2,x3,y3,pos);
               glutReshapeWindow(85,80+(h+1)*14); }
             break;
    case 6 : { glColor3fv(couleurJauneFonce());
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR8x13,"EXTREMES");
               pos += 1.0F;
               placeFontCursor(5.0F,-pos*14.0F,0.0F) ;
               simpleBitmapOutput(1,REGULAR6x10," y    xi  xf");
               pos += 1.0F;
               int h = pixelsExtremesFacette(x1,y1,x2,y2,x3,y3,pos);
               if ( yy < h )
                 glutReshapeWindow(85,80+(yy+2)*14);
                 else
                 glutReshapeWindow(85,80+(h+1)*14); }
             break; }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void reshapeV(int w,int h) {
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,-h,0,-1.0,1.0); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  { glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
    glutInitWindowSize(320,320); 
    glutInitWindowPosition(50,50); 
    f1 = glutCreateWindow("Remplissage d'une facette 2D"); 
    myinit(); 
    creationMenuBasique();
    setParametresOrthoBasique(0.0,XMAX,0.0,YMAX,-1.0,1.0);
    glutReshapeFunc(reshapeOrthoBasique);
    glutKeyboardFunc(key);
    glutDisplayFunc(display); }
  { glutInitWindowSize(80,100);
    glutInitWindowPosition(380,50);
    glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
    fv = glutCreateWindow("Valeurs");
    creationMenuBasique();
    glutDisplayFunc(displayV);
    glutReshapeFunc(reshapeV);
    glutKeyboardFunc(key); }
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR