#include "stdafx.h" #include "glut.h" #include #include #define RED 1 #define GREEN 2 #define BLUE 3 #define WHITE 4 #define Circle 5 #define Elip 6 #define Lines 7 #define To 8 float red=1.0, blue=1.0, green=1.0; int screenWidth=640;//kich thuoc chieu rong man hinh int screenHeight=640;//kich thuoc chieu cao man hinh typedef struct { GLint x1,y1; GLint x2,y2; float red; float blue; float green; } GLintPoint;//tao cau truc du lieu luu 2 toa do #define NUM 100// khai bao kich thuoc mang GLintPoint list[NUM];//mang chua toa do cua hinh elip GLintPoint list1[NUM];//mang chua toa do cua hinh tron GLintPoint listdt[NUM]; int last=-1;//trang thai ban dau cua mang elip =-1 int last1=-1;//tuong tu hinh tron int lastdt=-1; int xt1,xt2,yt1,yt2;//khai bao toa do lay tu chuot de ve elip int xt1c,xt2c,yt1c,yt2c;//tuong tu hinh tron int xtdt1,xtdt2,ytdt1,ytdt2; int xto,yto; //ham hoan vi de chuyen doi toa do void BRE(int,int,int,int,float,float,float); float red1,green1,blue1; GLintPoint a[NUM]; int dem=-1; void hoanvi(int &x,int &y) { int tam; tam=x; x=y; y=tam; } //tao man hinh nen void DinhDangNen(GLsizei w,GLsizei h) { glClearColor(0.0,0.0,0.0,0.0); //Set mau nen la den // glPointSize(1.0); // Kich thuoc 1 diem // glMatrixMode(GL_PROJECTION); //glLoadIdentity(); //gluOrtho2D(0.0,screenWidth, 0.0, screenHeight);//tao kich thuoc man hinh hien thi glClear(GL_COLOR_BUFFER_BIT); } //ve doi xung 8 dinh void put8pixel(int xc,int yc,int x,int y) { glBegin(GL_POINTS); glVertex2i(xc+x,yc+y); glVertex2i(xc-x,yc+y); glVertex2i(xc+x,yc-y); glVertex2i(xc-x,yc-y); glVertex2i(xc+y,yc+x); glVertex2i(xc-y,yc+x); glVertex2i(xc+y,yc-x); glVertex2i(xc-y,yc-x); glEnd(); } void to_c(int x1,int y1,int x2,int y2,float r,float g,float b) { int xc,yc; xc=(x1+x2)/2;//tinh tam x duong tron yc=(y1+y2)/2;//tinh tam y duong tron float r1=(x1+x2)/2-x1;//tinh ban kinh for(int i=x1;ifor(int j=y1-r1;jfloat d=sqrt(float(xc-i)*(xc-i)+(yc-j)*(yc-j)); if(d<=r1) glBegin(GL_POINTS); glColor3f(r,g,b); glVertex2i(i,j); glEnd(); } } //ve hinh tron thuat toan midpoint,toa do chuot dau tien,toa do chuot thu 2 void c_mid(int xc1,int yc1,int xc2,int yc2,float red,float blue,float green) { glColor3f(red,green,blue); //hoan vi toa do if(xc1>xc2) { hoanvi(xc1,xc2); if(yc1>yc2) hoanvi(yc1,yc2); } if(xc1if(yc1>yc2) hoanvi(yc1,yc2); //to_c(xc1,yc1,xc2,yc2,red,green,blue); int xc,yc; xc=(xc1+xc2)/2;//tinh tam x duong tron yc=(yc1+yc2)/2;//tinh tam y duong tron int r=(xc1+xc2)/2-xc1;//tinh ban kinh int x=0; int y=r; int p=(1-r); while(x<=y) { put8pixel(xc,yc,x,y); x++; if(p<0) p+=((2*x)+3); else { y--; p+=((2*(x-y))+5); } } } //ve 1 diem void Setpixel(int x,int y) { glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); } //lay doi xung 4 dinh void Set4pixel(int xc,int yc,int x,int y) { Setpixel(xc+x,yc+y); Setpixel(xc+x,yc-y); Setpixel(xc-x,yc+y); Setpixel(xc-x,yc-y); } struct Color { float red; float green; float blue; } ; struct toado { int x; int y; }; bool IsEmpty(int t) { if(t==0) return true; return false; } bool IsFull(int t) { if(t==65000) return true; return false; } void Push(int x,int y,toado S[],int &t) { if(IsFull(t)==true) return; t++; S[t].x=x; S[t].y=y; //printf("t=%d x=%d y=%d\n",t,x,y); return; } toado Pop(toado S[],int &t) { toado x; x.x = -1; x.y = -1; if(t>0) { x.x=S[t].x; x.y=S[t].y; t--; //printf("pop:t=%d x=%d y=%d\n",t,x.x,x.y); } return x; } bool Iscolor(float *pixel,Color &bgcolor) { if((pixel[0]==bgcolor.red)&&(pixel[1]==bgcolor.green)&&(pixel[2]==bgcolor.blue)) return true; return false; } void Fill(int sx,int sy,Color &fill) { toado S[65000]; int t=0; Push(sx,sy,S,t); //printf("fill SX=%d Sy=%d\n",sx,sy); toado d; d.x=sx; d.y=sy; float *p=new float[screenWidth*screenHeight*3]; glReadPixels(0,0,screenWidth,screenHeight,GL_RGB,GL_FLOAT,p); float *pixel=&p[(d.y*screenWidth+d.x)*3]; Color bgcolor; bgcolor.red=pixel[0]; bgcolor.green=pixel[1]; bgcolor.blue=pixel[2]; while(!IsEmpty(t)) { printf("t=%d %d %d\n",t,d.x,d.y); d=Pop(S,t); if(d.x == -1 && d.y == -1) break; if(d.x>screenWidth||d.y>screenHeight||d.x<0||d.y<0) continue; pixel=&p[(d.y*screenWidth+d.x)*3]; if(Iscolor(pixel,bgcolor)==true&&Iscolor(pixel,fill)==false) { pixel[0]=fill.red; pixel[1]=fill.green; pixel[2]=fill.blue; toado d1; d1.x=d.x-1; d1.y=d.y; Push(d1.x,d1.y,S,t); toado d2; d2.x=d.x; d2.y=d.y+1; Push(d2.x,d2.y,S,t); toado d3; d3.x=d.x+1; d3.y=d.y; Push(d3.x,d3.y,S,t); toado d4; d4.x=d.x; d4.y=d.y-1; Push(d4.x,d4.y,S,t); } } printf("Chay xong roi."); glDrawPixels(screenWidth,screenHeight,GL_RGB,GL_FLOAT,p); delete []p; } void E_mid(int xc1,int yc1,int xc2,int yc2,float red,float blue,float green) { //can hoan vi toa do de luon luon x2>x1,y2>y1 glColor3f(red,green,blue); if(xc1>xc2) { hoanvi(xc1,xc2); if(yc1>yc2) hoanvi(yc1,yc2); } if(xc1if(yc1>yc2) hoanvi(yc1,yc2); int xc,yc; xc=(xc1+xc2)/2;//tinh tam x elip yc=(yc1+yc2)/2;//tinh tam y elip int a,b; a=(xc1+xc2)/2-xc1;//tinh a b=(yc1+yc2)/2-yc1;//tinh b // BoundaryFillEnhanced( xc,yc,255, 0); int x,y; long p; long a2 = (long)a*a; long b2 = (long)b*b; long four_a2 = 4*a2; long four_b2 = 4*b2; x = 0; y = b; p = a2 - four_a2*b + four_b2; Set4pixel(xc,yc,x,y); while(a2*y>b2*x) { if(p>=0) { p+=four_b2*(2*x+3) - four_a2*(2*y-2); y--; } else p+=four_b2*(2*x+3); x++; Set4pixel(xc,yc,x,y); } x = a; y = 0; p = b2 - four_b2*a + four_a2; Set4pixel(xc,yc,x,y); while (b2*x>a2*y) { if(p>=0) { p+=four_a2*(2*y+3)-four_b2*(2*x-2); x--; } else p+=four_a2*(2*y+3); y++; Set4pixel(xc,yc,x,y); } } //xuat mang elip ra man hinh void output() { glClear(GL_COLOR_BUFFER_BIT); for(int i=0 ;i <=last;i++) { E_mid(list[i].x1,list[i].y1,list[i].x2,list[i].y2,list[i].red,list[i].blue,list[i].green);//xuat mang elip da dc ve } E_mid(xt1,yt1,xt2,yt2,red,blue,green);//xuat elip tam thoi for(int i=0;i <=last1;i++) { c_mid(list1[i].x1,list1[i].y1,list1[i].x2,list1[i].y2,list1[i].red,list1[i].blue,list1[i].green);//xuat mang hinh tron da dc ve } for(int i=0;i <=lastdt;i++) { BRE(listdt[i].x1,listdt[i].y1,listdt[i].x2,listdt[i].y2,listdt[i].red,listdt[i].blue,listdt[i].green); } glEnd(); glutSwapBuffers(); } //lay toa do chuot cua elip void xulychuot(int button,int status,int x,int y) { if(button==0&&status==0) { xt1=x;//lay toa do x dau tien yt1=screenHeight-y;//lay toa do y dau tien chuyen ve toa do binh thuong } //lay toa do sau cung,nhap vao mang va xuat ra if(button==0&&status==1) { xt2=x; yt2=screenHeight-y; last++; list[last].x1=xt1; list[last].y1=yt1; list[last].x2=xt2; list[last].y2=yt2; list[last].blue=blue; list[last].green=green; list[last].red=red; output(); } } //ham keo re chuotcua elip void chuotdichuyen(int x,int y) { glClear(GL_COLOR_BUFFER_BIT); xt2 = x; yt2 = screenHeight-y; output(); } //xuat mang duong tron,hinh elip void output1() { glClear(GL_COLOR_BUFFER_BIT); for(int i=0;i <=last1;i++) { c_mid(list1[i].x1,list1[i].y1,list1[i].x2,list1[i].y2,list1[i].red,list1[i].blue,list1[i].green); } c_mid(xt1c,yt1c,xt2c,yt2c,red,blue,green); for(int i=0;i <=last;i++) { E_mid(list[i].x1,list[i].y1,list[i].x2,list[i].y2,list[i].red,list[i].blue,list[i].green); } for(int i=0;i <=lastdt;i++) { BRE(listdt[i].x1,listdt[i].y1,listdt[i].x2,listdt[i].y2,listdt[i].red,listdt[i].blue,listdt[i].green); } glEnd(); glutSwapBuffers(); } //xac dinh toa do chuot cua duongtron,tuong tu cua elip void xulychuot1(int button,int status,int x,int y) { if(button==0&&status==0) { xt1c=x; yt1c=screenHeight-y; } if(button==0&&status==1) { xt2c=x; yt2c=screenHeight-y; last1++; list1[last1].x1=xt1c; list1[last1].y1=yt1c; list1[last1].x2=xt2c; list1[last1].y2=yt2c; list1[last1].red=red; list1[last1].blue=blue; list1[last1].green=green; output1(); } } //keo re chuot duong tron void chuotdichuyen1(int x,int y) { glClear(GL_COLOR_BUFFER_BIT); xt2c = x; yt2c = screenHeight-y; output1(); } void BRE(int x1,int y1,int x2,int y2,float red,float blue,float green) { int x,y,dx,dy,p; if(x1>x2) { hoanvi(x1,x2); hoanvi(y1,y2); } glColor3f(red,green,blue); glBegin(GL_POINTS); glVertex2i(x1,y1); dx=abs(x2-x1); dy=abs(y2-y1); x=x1; y=y1; long const1y=2*dy; long const1x=2*dx; long const2y=2*(dy-dx); long const2x=2*(dx-dy); if(dx>dy) { p=2*dy-dx; glVertex2i(x,y); while(x<=x2) { if(p<0) p+=const1y; else { if(y1else { p+=const2y; y--; } } x++; glVertex2i(x,y); } } else { p=2*dx-dy; glVertex2i(x,y); if(y1while(y<=y2) { if(p<0) p+=const1x; else { p+=const2x; x++; } y++; glVertex2i(x,y); } } else { while(y>=y2) { if(p<0) p+=const1x; else { p+=const2x; x++; } y--; glVertex2i(x,y); } } } } void outputdt() { glClear(GL_COLOR_BUFFER_BIT); for(int i=0;i <=lastdt;i++) { BRE(listdt[i].x1,listdt[i].y1,listdt[i].x2,listdt[i].y2,listdt[i].red,listdt[i].blue,listdt[i].green); } BRE(xtdt1,ytdt1,xtdt2,ytdt2,red,blue,green); glClear(GL_COLOR_BUFFER_BIT); for(int i=0 ;i <=last;i++) { E_mid(list[i].x1,list[i].y1,list[i].x2,list[i].y2,list[i].red,list[i].blue,list[i].green);//xuat mang elip da dc ve } for(int i=0;i <=last1;i++) { c_mid(list1[i].x1,list1[i].y1,list1[i].x2,list1[i].y2,list1[i].red,list1[i].blue,list1[i].green);//xuat mang hinh tron da dc ve } glEnd(); glutSwapBuffers(); } void xulychuotdt(int button,int status,int x,int y) { if(button==0&&status==0) { xtdt1=x; ytdt1=screenHeight-y; } if(button==0&&status==1) { xtdt2=x; ytdt2=screenHeight-y; lastdt++; listdt[lastdt].x1=xtdt1; listdt[lastdt].y1=ytdt1; listdt[lastdt].x2=xtdt2; listdt[lastdt].y2=ytdt2; listdt[lastdt].red=red; listdt[lastdt].blue=blue; listdt[lastdt].green=green; outputdt(); } } void xulychuotto(int button,int status,int x,int y) { if(button==0&&status==0) { Color F; F.red=red; F.green=green; F.blue=blue; Fill(x,screenHeight-y,F); glutSwapBuffers(); } } void chuotdichuyento(int x,int y) { glClear(GL_COLOR_BUFFER_BIT); Color F; F.red=red; F.green=green; F.blue=blue; Fill(x,screenHeight-y,F); glutSwapBuffers(); } void chuotdichuyendt(int x,int y) { glClear(GL_COLOR_BUFFER_BIT); xtdt2 = x; ytdt2 = screenHeight-y; outputdt(); } // xu ly phim e ve elip,c ve duong tron, d ve duong thang void xulyphim(unsigned char key,int x,int y) { switch(key) { case 'e': glutMouseFunc(xulychuot); glutMotionFunc(chuotdichuyen); glutDisplayFunc(output); break; case 'c': glutMouseFunc(xulychuot1); glutMotionFunc(chuotdichuyen1); glutDisplayFunc(output1); break; case 'd': glutMouseFunc(xulychuotdt); glutMotionFunc(chuotdichuyendt); glutDisplayFunc(outputdt); break; } } void processMenuEvents(int option) { switch (option) { case RED : red = 1.0; green = 0.0; blue = 0.0; break; case GREEN : red = 0.0; green = 1.0; blue = 0.0; break; case BLUE : red = 0.0; green = 0.0; blue = 1.0; break; case WHITE : red = 1.0; green = 1.0; blue = 1.0; break; case Circle: glutMouseFunc(xulychuot1); glutMotionFunc(chuotdichuyen1); glutDisplayFunc(output1); break; case Elip : glutMouseFunc(xulychuot); glutMotionFunc(chuotdichuyen); glutDisplayFunc(output); break; case Lines : glutMouseFunc(xulychuotdt); glutMotionFunc(chuotdichuyendt); glutDisplayFunc(outputdt); break; case To: glutMouseFunc(xulychuotto); glutMotionFunc(chuotdichuyento); break; } } //khi nhap chuot phai tao ra menu chon mau void createGLUTMenus() { int submenu; submenu = glutCreateMenu(processMenuEvents); glutAddMenuEntry("Red",RED); glutAddMenuEntry("Blue",BLUE); glutAddMenuEntry("Green",GREEN); glutAddMenuEntry("White",WHITE); glutAddMenuEntry("Circle",Circle); glutAddMenuEntry("Elip",Elip); glutAddMenuEntry("Lines",Lines); glutAddMenuEntry("Tô Màu",To); glutAttachMenu(GLUT_RIGHT_BUTTON); } void Setup() { glViewport(0,0,screenWidth,screenHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,screenWidth,0,screenHeight,1,-1); } int _tmain(int argc, char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE); glutInitWindowSize(screenWidth,screenHeight); glutCreateWindow("Vẽ và Tô"); Setup(); createGLUTMenus(); glutDisplayFunc(output); glutReshapeFunc(DinhDangNen); glutKeyboardFunc(xulyphim); glutMainLoop(); return 0; }