Bài giảng Đồ họa máy tính - Chương 2: Bước đầu tạo hình ảnh
Xây dựng chương trình đồ họa.
Thành phần cơ bản trong một chương trình sử dụng OpenGL.
Vẽ điểm, vẽ đoạn thẳng, vẽ đường gấp khúc, vẽ hình chữ nhật.
Giao tiếp với chuột và bàn phím.
Một số ứng dụng.
và bàn phím . Một số ứng dụng . XÂY DỰNG CHƯƠNG TRÌNH ĐỒ HỌA Môi trường lập trình Phần cứng : màn hình , card đồ họa . Phần mềm : hệ điều hành (Window), ngôn ngữ lập trình (MS Visual C++), thư viện đồ họa (OpenGL, Direct X). Trình tự xây dựng chương trình đồ họa Thiết lập chế độ hiển thị ( văn bản , đồ họa ) Thiết lập hệ trục tọa độ Sử dụng các hàm của môi trường lập trình để tạo dựng hình ảnh . THIẾT LẬP TRỤC TỌA ĐỘ Môi trường lập trình DOS Môi trường lập trình Window (100, 50) (150, 80) (0, 290) SỬ DỤNG CÁC HÀM ĐỂ XÂY DỰNG HÌNH ẢNH Hàm do hệ điều hành và ngôn ngữ lập trình cung cấp : setPixel(x , y, color) tên khác : putPixel (), SetPixel () hoặc drawPoint () line(100, 50, 150, 80); line(150, 80, 0, 290); Hàm do thư viện đồ họa cung cấp . Hàm tự xây dựng . THÀNH PHẦN CƠ BẢN CỦA CT SỬ DỤNG OpenGL OpenGL là thư viện lập trình đồ họa độc lập thiết bị Không phụ thuộc vào phần cứng và hệ điều hành Cách làm thống nhất cho cả đồ họa 2D và 3D Lập trình Window Lập trình sự kiện là gì ? Hàng đợi sự kiện (event queue). Callback function. Đăng ký hàm xử lý sự kiện : glutDisplayFunc(myDisplay ) glutReshapeFunc(myReshape ) glutMouseFunc(myMouse ) glutKeyboardFunc(myKeyboard ) THÀNH PHẦN CƠ BẢN CỦA CT SỬ DỤNG OpenGL // phần #include những file header cần thiết - xem phụ lục 1 void main(int argc , char** argv ) { glutInit(&argc , argv ); //initialize the tool kit glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB); //set the display mode glutInitWindowSize(640, 480); //set window size glutInitWindowPosition(100, 150); // set window position on screen glutCreateWindow("My first program"); // open the screen window // register the callback function glutDisplayFunc( myDisplay ); myInit (); //additional initialization as necessary glutMainLoop (); } THÀNH PHẦN CƠ BẢN CỦA CT SỬ DỤNG OpenGL Thiết lập hệ trục tọa độ void myInit () { glMatrixMode(GL_PROJECTION ); glLoadIdentity (); gluOrtho2D(0.0, 640.0, 0.0,480.0); } VẼ ĐIỂM glBegin(GL_POINTS); glVertex2i(100, 50); glVertex2i(100, 130); glVertex2i(150, 130); glEnd(); My first program glVertex2i(...) thư viện gl phần cơ bản của tên hàm số lượng đối số kiểu của đối số VẼ ĐIỂM Trạng thái trong OpenGL glColor3f(1.0, 0.0, 0.0); // đổi màu vẽ thành màu đỏ glClearColor(1.0,1.0,1.0,0.0); // set white background color glPointSize(4.0); glLineWidth(2.0); VẼ ĐIỂM Một chương trình hoàn chỉnh int main(int argc , char* argv []) { glutInit(&argc , argv ); //initialize the tool kit glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB); //set the display mode glutInitWindowSize(640, 480); //set window size glutInitWindowPosition(100, 150); // set window position on screen glutCreateWindow("My first program"); // open the screen window glutDisplayFunc( myDisplay ); // register redraw funtion myInit (); glutMainLoop (); // go into a perpetual loop return 0; } VẼ ĐIỂM void myInit () { glClearColor(1.0,1.0,1.0,0.0); // set white background color glColor3f(0.0f, 0.0f, 0.0f); // set the drawing color glPointSize(4.0); // a ‘dot’ is 4 x 4 pixels glMatrixMode(GL_PROJECTION ); glLoadIdentity (); gluOrtho2D(0.0, 640.0, 0.0, 480.0); } VẼ ĐIỂM void myDisplay () { glClear(GL_COLOR_BUFFER_BIT ); // clear the screen glBegin(GL_POINTS); glVertex2i(100, 50); // draw three points glVertex2i(100, 130); glVertex2i(150, 130); glEnd (); glFlush (); // send all output to display } MỘT SỐ VÍ DỤ Vẽ chòm sao Đại Hùng : { Dubhe , 289, 190}, { Merak , 320, 128}, { Phecda , 239, 67}, { Megrez , 194, 101}, { Alioth , 129, 83}, { Mizar , 75, 73}, { Alcor , 74, 74}, { Alkaid , 20, 10} MỘT SỐ VÍ DỤ Vẽ Sierpinski gasket P 3 P 2 P 1 T 0 T 2 T 1 MỘT SỐ VÍ DỤ Vẽ Sierpinski gasket 1. Chọn 3 điểm cố định T0 , T1 , T2 để tạo nên một tam giác . Lưu ý rằng chúng ta không vẽ 3 điểm này lên màn hình 2. Chọn điểm khởi đầu p0 . Điểm p0 được chọn ngẫu nhiên trong số 3 điểm T0 , T1 , T2 . Sau đó vẽ p0 . Lặp lại những bước sau cho đến khi đạt được một kết quả vừa ý 3. Chọn một điểm bất kỳ trong số 3 điểm T0 , T1 , T2 . Gọi điểm đó là T. 4. Tạo điểm tiếp theo (pk ) bằng cách lấy điểm trung điểm của đoạn thẳng nối T và điểm trước đó (pk-1 ) . Tức là : pk = điểm giữa của pk-1 và T 5. Dùng hàm drawDot() để vẽ pk . MỘT SỐ VÍ DỤ Vẽ Sierpinski gasket void Sierpinski () { GLintPoint T[3]={{10, 10}, {300, 30}, {200, 300}} ; int index = random(3) ; GLintPoint point = T[index] ; glClear(GL_COLOR_BUFFER_BIT ); drawDot(point.x , point.y ) ; for(int i=0; i<1000;i++) { index = random(3); point.x = (point.x + T[index].x) / 2; point.y = (point.y + T[index].y) / 2; drawDot(point.x , point.y ) ; } glFlush (); } MỘT SỐ VÍ DỤ class GLintPoint{ public : GLint x, y ; } ; int random(int m) { return rand() % m ; } void drawDot(GLint x, GLint y) { //vẽ một điểm ở tọa độ (x, y) glBegin(GL_POINTS ); glVertex2i(x, y); glEnd (); } VẼ ĐOẠN THẲNG glBegin(GL_LINES ); glVertex2i(40, 100); glVertex2i(202, 96); glEnd (); void drawLineInt(GLint x1, GLint y1, GLint x2, GLint y2) { glBegin(GL_LINES ); glVertex2i(x1, y1); glVertex2i(x2, y2); glEnd (); } glBegin(GL_LINES ); glVertex2i(10, 20); // vẽ đoạn thẳng thứ nhất glVertex2i(40, 20); glVertex2i(20, 10); // vẽ đoạn thẳng thứ hai glVertex2i(20, 40); thêm 4 lời gọi hàm glVertex2i() để vẽ hai đoạn thẳng còn lại glEnd (); a) đo ạn thẳng mỏng b) đo ạn thẳng dày c) đo ạn thẳ ng đ ứt nét VẼ ĐƯỜNG GẤP KHÚC p0 = (x0, y0) , p1 = (x1, y1) , ..., pn = (xn, yn) glBegin( GL_LINE_STRIP ); // vẽ đường gấp khúc mở glVertex2i(20, 10); glVertex2i(50, 10); glVertex2i(20, 80); glVertex2i(50, 80); glEnd(); a) b) GL_LINE_LOOP vẽ đường gấp khúc khép kín VÍ DỤ void hardwirededHouse () { glBegin( GL_LINE_LOO P); //vẽ khung ngôi nhà glVertex2i(40, 40); glVertex2i(40, 90); glVertex2i(70, 120); glVertex2i(100, 90); glVertex2i(100, 40); glEnd (); glBegin( GL_LINE_STRIP ); //vẽ ống khói glVertex2i(50, 100); glVertex2i(50, 120); glVertex2i(60, 120); glVertex2i(60, 110); glEnd(); . . . // vẽ cửa ra vào . . . // vẽ cửa sổ } 120 40 120 40 VÍ DỤ void parameterizedHouse(GLintPoint peak,GLint width,GLint height) // tọa độ của nóc nhà là peak, // chiều cao , chiều rộng của ngôi nhà là height và width { glBegin(GL_LINE_LOOP ); glVertex2i(peak.x, peak.y ); glVertex2i(peak.x + width/2,peak.y – 3*height/8); glVertex2i(peak.x + width/2,peak.y – height); glVertex2i(peak.x - width/2,peak.y – height); glVertex2i(peak.x - width/2,peak.y – 3*height/8); glEnd(); vẽ ống khói vẽ cửa ra vào vẽ cửa sổ } VÍ DỤ VẼ ĐƯỜNG GẤP KHÚC class GLintPointArray { const int MAX_NUM = 100; public: int num ; GLintPoint pt[MAX_NUM] ; }; void drawPolyLine(GLintPointArray poly,int closed) { glBegin(closed ? GL_LINE_LOOP : GL_LINE_STRIP); for(int i=0;i< poly.num;i ++) glVertex2i(poly.pt[i].x, poly.pt[i].y); glEnd(); glFlush(); } VẼ ĐOẠN THẲNG DÙNG moveto (), lineto () GLintPoint CP; //global current position void moveto(GLint x, GLint y) { CP.x = x; CP.y = y; //update CP } void lineto(GLint x, GLint y) { glBegin(GL_LINES ); //draw the line glVertex2i(CP.x, CP.y ); glVertex2i(x, y); glEnd (); glFlush (); CP.x = x; CP.y = y; //update CP } VẼ HÌNH CHỮ NHẬT Cú pháp glRecti(GLint x1, GLint y1, GLint x2, GLint y2); // vẽ một hình chữ nhật mà hai góc đối diện có tọa độ là (x1, y1) và (x2, y2) // hình chữ nhật sẽ được tô bằng màu vẽ hiện hành (current color) Ví dụ glClearColor(1.0, 1.0, 1.0, 0.0); // nền màu trắng glClear(GL_COLOR_BUFFER_BIT );// xóa cửa sổ glColor3f(0.6, 0.6, 0.6); // bright gray glRecti(20, 20, 100, 70); glColor3f(0.2, 0.2, 0.2); // dark gray glRecti(20, 20, 100, 70); glFlush (); HỆ SỐ TỶ LỆ CỦA HÌNH CHỮ NHẬT A 11/8.5 landscape B 4/3 tv screen C golden rectangle D 1 square E 8.5/11 portrait F 1/ =1.618034 NHỮNG ĐỐI TƯỢNG ĐỒ HỌA CƠ BẢN KHÁC TRONG OpenGL v 7 v 5 v 3 GL_TRIANGLE_FAN v 1 v 6 v 4 v 2 v 0 v 4 v 3 v 2 v 1 v 0 v 4 v 3 v 2 v 1 v 0 GL_QUAD_STRIP GL_QUADS GL_TRIANGLE_STRIP GL_TRIANGLES GIAO TIẾP VỚI CHUỘT Thao tác bấm chuột glutMouseFunc(myMouse ) void myMouse(int button, int state, int x, int y); button : GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON và GLUT_RIGHT_BUTTON state : GLUT_UP và GLUT_DOWN x, y : tọa độ màn hình , trục x chạy từ trái sang phải , trục y chạy từ trên xuống dưới void myMouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) drawDot(x , screenHeight - y); else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN ) exit(-1); } GIAO TIẾP VỚI CHUỘT Thao tác di chuyển chuột glutMotionFunc(myMovedMouse ) void myMovedMouse(int x, int y) void myMovedMouse(int mouseX, int mouseY) { GLint x = mouseX; GLint y = mouseY; GLint brushSize = 20; glRecti(x, y, x + brushSize, y + brushSize); glFlush(); } GIAO TIẾP VỚI BÀN PHÍM glutKeyboardFunc(myKeyboard ) void myKeyboard(unsigned int key, int x, int y); key: mã ASCII của phím bị nhấn x, y: vị trí chuột void myKeyboard(unsigned char theKey , int mouseX , int mouseY){ GLint x = mouseX ; GLint y = screenHeight – mouseY ; switch(theKey ) { case ‘p’: drawDot(x , y); // vẽ một điểm ở vị trí con chuột break; case GLUT_KEY_LEFT: List [++last].x = x ; List[last ].y = y; //thêm điểm break ; case ‘E’: exit(-1); default : break; } }
File đính kèm:
- bai_giang_do_hoa_may_tinh_chuong_2_buoc_dau_tao_hinh_anh.ppt