/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Avril 2001 */ /* Une fonction de clipping recursive */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleMenus.h" typedef struct Point2D { int x; int y; } Point2D ; typedef struct Segment { Point2D pi; Point2D pf; } Segment ; typedef struct MyRectangle { int xmin; int ymin; int xmax; int ymax; } MyRectangle ; static int height ; static int mouvement = 0 ; static int button = 0 ; static int ext = 0 ; static Segment s = { {10,50},{270,180} }; int code(Point2D *p,MyRectangle *r) { int res = 0x0000; if ( p->x < r->xmin ) res |= 0x0001; if ( p->x > r->xmax ) res |= 0x0010; if ( p->y < r->ymin ) res |= 0x0100; if ( p->y > r->ymax ) res |= 0x1000; return(res); } int adjacents(Point2D *p1,Point2D *p2) { if ( ( abs(p1->x-p2->x) <=1 ) && ( abs(p1->y-p2->y) <=1 ) ) return(1); return(0); } void traceRectangle(MyRectangle *r) { glBegin(GL_LINE_LOOP); glVertex2i(r->xmin,r->ymin); glVertex2i(r->xmax,r->ymin); glVertex2i(r->xmax,r->ymax); glVertex2i(r->xmin,r->ymax); glEnd(); } void traceSegment(Segment *s) { glBegin(GL_LINES); glVertex2i(s->pi.x,s->pi.y); glVertex2i(s->pf.x,s->pf.y); glEnd(); } void clippingRecursif(Segment *s,MyRectangle *r) { int cpi = code(&s->pi,r); int cpf = code(&s->pf,r); //printf("%04x %04x\n",cpi,cpf); if ( ( cpi == 0 ) && ( cpf == 0 ) ) { traceSegment(s); //printf("Trace entre (%d,%d) et (%d,%d)\n",s->pi.x,s->pi.y,s->pf.x,s->pf.y); return; } if ( (cpi&cpf) != 0 ) { //printf("Ne trace pas\n"); return; } //printf("Decompose entre (%d,%d) et (%d,%d)\n",s->pi.x,s->pi.y,s->pf.x,s->pf.y); if ( adjacents(&s->pi,&s->pf) ) { Segment s1 = { { s->pi.x,s->pi.y } , { s->pi.x,s->pi.y } }; Segment s2 = { { s->pf.x,s->pf.y } , { s->pf.x,s->pf.y } }; clippingRecursif(&s2,r); clippingRecursif(&s1,r);} else { int x = (s->pi.x+s->pf.x)/2; int y = (s->pi.y+s->pf.y)/2; Segment s1 = { { s->pi.x,s->pi.y } , { x,y } }; Segment s2 = { { x,y } , { s->pf.x,s->pf.y } }; clippingRecursif(&s2,r); clippingRecursif(&s1,r);} } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); MyRectangle r = { 80,60,240,200 }; glColor4fv(couleurBlanc()); traceRectangle(&r); glColor4fv(couleurBleu()); traceSegment(&s); glColor4fv(couleurRouge()); clippingRecursif(&s,&r); glPopMatrix(); glFlush(); glutSwapBuffers() ; } void souris(int bouton,int etat,int x,int y) { button = bouton; if ( bouton == GLUT_LEFT_BUTTON ) { s.pi.x = x ; s.pi.y = height-y ; if ( etat == GLUT_DOWN ) { mouvement = 1 ;} if ( etat == GLUT_UP ) { mouvement = 0 ; } glutPostRedisplay(); } if ( bouton == GLUT_RIGHT_BUTTON ) { s.pf.x = x ; s.pf.y = height-y ; if ( etat == GLUT_DOWN ) { mouvement = 1 ;} if ( etat == GLUT_UP ) { mouvement = 0 ; } glutPostRedisplay(); } } void motion(int x,int y) { switch ( button ) { case GLUT_LEFT_BUTTON : if ( mouvement == 1 ) { s.pi.x = x ; s.pi.y = height-y ; glutPostRedisplay(); } break; case GLUT_RIGHT_BUTTON : if ( mouvement == 1 ) { s.pf.x = x ; s.pf.y = height-y ; glutPostRedisplay(); } } } void reshape(int w,int h) { glViewport(0,0,w,h); height = h ; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,w,0,h,-40.0,40.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void init() { glShadeModel(GL_SMOOTH); glClearColor(0.8F,0.8F,0.8F,1.0F); } void key(unsigned char key,int x,int y) { switch ( key ) { case 0x0D : ext = 1-ext ; glutPostRedisplay(); break; case '\033' : exit(0); break ; } } void special(int k,int x,int y) { switch (k) { case GLUT_KEY_UP : if ( ext ) s.pi.y += 1 ; else s.pf.y += 1 ; glutPostRedisplay(); break; case GLUT_KEY_DOWN : if ( ext ) s.pi.y -= 1 ; else s.pf.y -= 1 ; glutPostRedisplay(); break; case GLUT_KEY_LEFT : if ( ext ) s.pi.x -= 1 ; else s.pf.x -= 1 ; glutPostRedisplay(); break; case GLUT_KEY_RIGHT : if ( ext ) s.pi.x += 1 ; else s.pf.x += 1 ; glutPostRedisplay(); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitWindowSize(300,300); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutCreateWindow("Clipping recursif"); glutKeyboardFunc(key); glutSpecialFunc(special); glutMotionFunc(motion); glutMouseFunc(souris); glutDisplayFunc(display); init(); creationMenuBasique(); glutReshapeFunc(reshape); glutMainLoop(); return(0); }