/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2005 */ /* Illustration du remplissage */ /* d'une facette 2D */ #include #include #include #include #include #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); }