/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2007 */ /* Rasterisation de segments de droites */ /* sur un ecran bitmap */ #include #include #include #include #include #include /* 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); }