Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 84 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
84
Dung lượng
2,38 MB
Nội dung
OpenGL Programming Guide Lớp: Đồ họa máy tính - INT3403 21 Nhóm: Thành viên: Nguyễn Quốc An Nguyễn Đỗ Dương Dương Quốc Hưng Hồng Phương Linh Trần Cơng Minh Lâm Hà Thái Chủ đề: State management and Drawing geometric objects (Quản lý trạng thái vẽ vật thể hình học) Phân cơng cơng việc: Thành viên Cơng việc Nguyễn Quốc An Lên ý tưởng slide thuyết trình Quản lý tiến độ Chuẩn bị slide thuyết trình Soạn lý thuyết tập phần A Drawing Survival Kit Nguyễn Đỗ Dương Chuẩn bị slide thuyết trình Soạn lý thuyết tập phần Vertex Arrays Soạn lý thuyết tập phần Vertex Objects Dương Quốc Hưng Chuẩn bị tài liệu Soạn lý thuyết tập phần Basic State Management Soạn lý thuyết tập phần Normal Vectors Soạn lý thuyết tập phần Attribute Groups Soạn phần Bài tập ứng dụng Hoàng Phương Linh Chuẩn bị slide thuyết trình Soạn lý thuyết tập phần Buffer Objects Trần Công Minh Chuẩn bị slide thuyết trình Soạn lý thuyết tập phần Describing Points, Lines, and Polygons Lâm Hà Thái Chuẩn bị slide thuyết trình Soạn lý thuyết tập phần Displaying Points, Lines, and Polygons Chương 2: Quản lý trạng thái vẽ vật thể hình học Mục lục 2.1 Quản lý trạng thái vẽ vật thể hình học (State management and Drawing geometric objects) 2.1.1 A drawing survival kit 4 2.1.1.1 Xoá cửa sổ (Cleaning the window) 2.1.1.2 Đặc tả màu (Specify a color) 2.1.1.3 Ép việc vẽ hoàn thành (Forcing completion of drawing) 2.1.1.4 Bộ công cụ hệ tọa độ (Coordinate system survival kit) 2.1.2 Mô tả điểm, đường thẳng, đa giác (Describing points, lines polygons) 10 2.1.2.1 Điểm, đường thẳng, đa giác (What are points, lines and polygons) 10 13 2.1.2.2 Đặc tả đỉnh (Specifying vertices) 2.1.2.3 Vẽ hình học sở OpenGL (OpenGL geometric drawing primitives) 14 19 2.1.3 Quản lý trạng thái (Basic state management) 20 2.1.4 Hiển thị điểm, đường thẳng đa giác (Displaying points, lines and polygons) 2.1.4.1 Hiển thị điểm (Point details) 20 21 2.1.4.2 Hiển thị đường thẳng (Line details) 2.1.4.2.1 Độ rộng đường thẳng 21 2.1.4.2.2 Đường thẳng hoa văn (Striped lines) 22 22 2.1.4.3 Hiển thị đa giác (Polygon details) 2.1.4.3.1 Đa giác dạng điểm, đường viền tơ kín 22 2.1.4.3.2 Đảo ngược hủy bỏ mặt đa giác 23 2.1.4.3.3 Đa giác hoa văn (Stipping Polygons) 24 2.1.5 Vectơ pháp tuyến (Normal vectors) 24 25 2.1.6 Mảng đỉnh (Vertex arrays) 26 2.1.6.1 Bước 1: Kích hoạt mảng 2.1.6.2 Bước 2: Đưa liệu vào mảng 27 29 2.1.6.3 Bước 3: Vẽ hình với liệu 2.1.6.4 Chạy lại đối tượng sở 35 2.1.6.5 Vẽ đối tượng 38 39 2.1.6.6 Mảng xen kẽ 2.1.7 Đối tượng đệm (Buffer Objects) 41 2.1.7.1 Tạo Đối tượng đệm (Creating buffer objects) 42 43 2.1.7.2 Làm cho đối tượng đệm hoạt động (Making a buffer object active) 2.1.7.3 Phân bổ khởi tạo đối tượng đệm với liệu (Allocating and initializing buffer objects with data) 43 2.1.7.4 Cập nhật liệu đối tượng đệm (Updating data values in buffer objects)46 2.1.7.5 Sao chép liệu đối tượng đệm (Copying data between buffer objects) 49 2.1.7.6 Xóa đối tượng đệm (Cleaning up buffer objects) 50 Chương 2: Quản lý trạng thái vẽ vật thể hình học 2.1.7.7 Sử dụng đối tượng đệm với liệu mảng đỉnh (Using buffer objects with vertex-array data) 50 2.1.8 Đối tượng mảng đỉnh (Vertex-array objects) 52 2.1.9 Nhóm thuộc tính (Attribute groups) 57 60 2.2 Bài tập 2.2.1 Bài tập 60 2.2.1.1 A drawing survival kit 60 60 2.2.1.2 Mô tả điểm, đường thẳng, đa giác (Describing points, lines polygons) 2.2.1.3 Quản lý trạng thái (Basic state management) 60 2.2.1.4 Hiển thị điểm, đường thẳng đa giác (Displaying points, lines and polygons) 61 61 2.2.1.5 Vectơ pháp tuyến (Normal vectors) 2.2.1.6 Mảng đỉnh (Vertex arrays) 61 62 2.2.1.7 Đối tượng đệm (Buffer Objects) 2.2.1.8 Đối tượng mảng đỉnh (Vertex-array objects) 62 2.2.1.9 Nhóm thuộc tính (Attribute groups) 62 2.2.2 Đáp án 63 2.2.2.1 A drawing survival kit 63 2.2.2.2 Mô tả điểm, đường thẳng, đa giác (Describing points, lines polygons) 63 64 2.2.2.3 Quản lý trạng thái (Basic state management) 2.2.2.4 Hiển thị điểm, đường thẳng đa giác (Displaying points, lines and polygons) 65 2.2.2.5 Vectơ pháp tuyến (Normal vectors) 65 66 2.2.2.6 Mảng đỉnh (Vertex arrays) 2.2.2.7 Đối tượng đệm (Buffer Objects) 67 2.2.2.8 Đối tượng mảng đỉnh (Vertex-array objects) 69 69 2.2.2.9 Nhóm thuộc tính (Attribute groups) 2.3 Sản phẩm ứng dụng (xây dựng mơ hình đa giác bề mặt vật thể) 71 2.3.1 Xóa hình 71 72 2.3.2 Vẽ đoạn thẳng 2.3.3 Vẽ hình chữ nhật 73 2.3.4 Vẽ nét đứt 74 76 2.3.5 Vẽ polygon 2.3.6 Xây dựng bề mặt đa giác vật thể 77 77 2.3.6.1 Những lưu ý xây dựng mơ hình đa giác bề mặt vật thể 2.3.6.2 Xây dựng bề mặt đa giác Icosahedron 79 Chương 2: Quản lý trạng thái vẽ vật thể hình học Chương 2: State management and Drawing geometric objects (Quản lý trạng thái vẽ vật thể hình học) 2.1 Quản lý trạng thái vẽ vật thể hình học Chương có phần sau: ● A Drawing Survival Kit giải thích cách xóa cửa sổ bắt buộc việc vẽ phải hồn thành Nó cung cấp cho bạn thơng tin kiểm sốt màu sắc đối tượng hình học mơ tả hệ tọa độ ● Mô tả điểm, đường đa giác cho bạn biết tập hợp đối tượng hình học sở để vẽ chúng ● Quản lý trạng thái mô tả cách bật tắt số trạng thái (chế độ) truy vấn biến trạng thái ● Hiển thị điểm, đường đa giác giải thích điều khiển chi tiết việc vẽ đối tượng sở – ví dụ, đường kính cho điểm, đường thẳng hay nét đứt liệu đa giác outlined hay filled ● Vectơ pháp tuyến thảo luận cách đặc tả vectơ pháp tuyến cho đối tượng hình học (một cách vắn tắt) vectơ cho ● Mảng đỉnh (Vertex Arrays) cho bạn cách bỏ nhiều liệu hình học vào vài mảng làm sao, với vài hàm gọi, hiển thị hình dạng mơ tả Việc giảm lời gọi hàm làm tăng hiệu hiệu suất việc vẽ ● Các nhóm thuộc tính (Attribute Groups) cho thấy cách truy vấn giá trị biến trạng thái cách lưu khôi phục số giá trị trạng thái có liên quan lúc ● Một số gợi ý để xây dựng mô hình đa giác bề mặt khám phá vấn đề kỹ thuật liên quan đến việc xây dựng xấp xỉ đa giác cho bề mặt 2.1.1 A drawing survival kit Phần giải thích cách xóa cửa sổ để chuẩn bị vẽ, thiết lập màu sắc đối tượng cần vẽ buộc vẽ hồn thành Những việc khơng có liên quan trực tiếp đến đối tượng hình học, chương trình vẽ đối tượng hình học phải giải vấn đề 2.1.1.1 Xố cửa sổ (Cleaning the window) Vẽ hình máy tính khác với vẽ giấy, giấy bắt đầu màu trắng tất bạn phải làm vẽ hình ảnh Trên máy tính, nhớ thường giữ ảnh cuối bạn vẽ, bạn cần xóa thành màu trước bắt đầu vẽ cảnh Màu bạn sử dụng cho phụ thuộc vào ứng dụng Đối với trình xử lý văn bản, bạn xóa với màu trắng (màu tờ giấy) trước bắt đầu vẽ chữ Nếu bạn vẽ khung cảnh từ tàu vũ trụ, bạn xóa với màu đen không gian trước bắt đầu vẽ sao, hành tinh, phi thuyền Đơi bạn khơng cần phải xóa hình; ví dụ, hình ảnh bên phịng, tồn cửa sổ đồ họa bị che phủ bạn vẽ lên tất tường Lúc này, bạn tự hỏi tiếp tục nói việc xóa cửa sổ – khơng vẽ hình chữ nhật có màu thích hợp đủ lớn để che toàn cửa sổ? Đầu tiên, lệnh để xóa Chương 2: Quản lý trạng thái vẽ vật thể hình học cửa sổ hiệu nhiều so với lệnh vẽ Ngoài ra, bạn thấy Chương 3, OpenGL cho phép bạn thiết lập hệ tọa độ, vị trí xem hướng xem tùy ý, khó tìm kích thước vị trí thích hợp cho hình chữ nhật xóa cửa sổ Cuối cùng, nhiều máy, phần cứng đồ họa bao gồm nhiều đệm khác đệm chứa màu pixel hiển thị Những đệm khác phải xóa theo thời gian, thuận tiện có lệnh xóa xóa kết hợp chúng (Xem Chương 10 để thảo luận tất đệm.) Bạn phải biết cách màu pixel lưu trữ phần cứng đồ họa gọi bitplanes Có hai phương pháp lưu trữ Giá trị màu đỏ, lục, lam alpha (RGBA) pixel lưu trữ trực tiếp bitplanes giá trị mục (single index value) tham chiếu đến bảng tra cứu màu (color lookup table) lưu trữ Chế độ hiển thị màu RGBA thường sử dụng, hầu hết ví dụ sách sử dụng (Xem Chương để biết thêm thông tin hai chế độ hiển thị.) Bạn bỏ qua tất tham chiếu đến giá trị alpha Chương Ví dụ dịng mã xóa cửa sổ chế độ RGBA thành màu đen: glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); Dòng thiết lập màu xóa thành màu đen dịng xóa tồn cửa sổ sang màu xóa hành Tham số hàm glClear() cho biết đệm bị xóa Trong trường hợp này, chương trình xóa đệm màu, nơi ảnh hiển thị hình giữ Thơng thường, bạn thiết lập màu xóa lần, bắt đầu ứng dụng, sau bạn xóa đệm thường xuyên cần thiết OpenGL giữ màu xóa hành dạng biến trạng thái thay yêu cầu bạn thiết lập đệm bị xóa Chương Chương 10 nói cách sử dụng đệm khác Hiện giờ, tất bạn cần biết việc xóa chúng đơn giản Ví dụ, để xóa đệm màu đệm độ sâu (depth buffer), bạn sử dụng câu lệnh sau: glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Trong trường hợp này, lệnh gọi glClearColor() giống trước, lệnh glClearDepth() định giá trị mà pixel đệm độ sâu đặt tham số lệnh glClear() bao gồm logic OR theo bit tất đệm xóa Bản tóm tắt sau glClear() bao gồm bảng liệt kê đệm xóa, tên chúng chương thảo luận loại đệm void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) ; Đặt màu xóa hành để sử dụng việc xóa đệm màu chế độ RGBA (Xem Chương để biết thêm thông tin chế độ RGBA.) Các giá trị màu đỏ, lục, lam alpha nằm khoảng [0,1] Màu xóa mặc định (0, 0, 0, 0), tức màu đen void glClear(GLbitfield mask); Xóa đệm định giá trị xóa chúng Mặt nạ đối số tổ hợp logic OR theo bit giá trị liệt kê Bảng 2.1.1.1 Chương 2: Quản lý trạng thái vẽ vật thể hình học Buffer Name Reference Color buffer GL_COLOR_BUFFER_BIT Chapter Depth buffer GL_DEPTH_BUFFER_BIT Chapter 10 Accumulation buffer GL_ACCUM_BUFFER_BIT Chapter 10 Stencil buffer GL_STENCIL_BUFFER_BIT Chapter 10 Bảng 2.1.1.1: Clearing Buffers Trước phát lệnh glClear() để xóa đệm, bạn phải thiết lập giá trị mà đệm bị xóa bạn muốn khác với giá trị mặc định ● glClearColor() : thiết lập giá trị để xóa đệm màu (RGBA color) ● glClearDepth() : thiết lập giá trị để xóa đệm độ sâu (depth buffer) ● glClearIndex() : thiết lập giá trị color index ● glClearAccum() : thiết lập giá trị accumulation color ● glClearStencil() : thiết lập giá trị stencil sử dụng để xóa đệm tương ứng (Xem Chương Chương 10 để biết mô tả đệm cách sử dụng chúng) OpenGL cho phép bạn định nhiều đệm việc xóa thường nhiều thời gian, pixel cửa sổ (có thể hàng triệu) đụng đến vài phần cứng đồ họa cho phép đệm xóa đồng thời Phần cứng mà khơng hỗ trợ xóa đồng thời thực xóa Sự khác biệt giữa: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT); là, hai có kết đầu chạy nhanh nhiều máy Chắc chắn khơng chạy chậm 2.1.1.2 Đặc tả màu (Specify a color) Với OpenGL, miêu tả hình dạng đối tượng vẽ độc lập với miêu tả màu sắc Bất đối tượng vẽ, vẽ lược đồ màu đặc tả hành Lược đồ màu đơn giản “vẽ thứ đỏ máy bơm nước cứu hỏa” phức tạp “giả sử đối tượng làm nhựa màu xanh lam, có ánh đèn màu vàng hướng đó, hướng đó, có ánh sáng màu đỏ nâu chung chung nơi khác.” Nói chung, lập trình viên OpenGL đặt màu lược đồ màu, sau vẽ đối tượng Cho đến lược đồ màu màu thay đổi, tất đối tượng vẽ màu sử dụng lược đồ màu Phương pháp giúp OpenGL đạt hiệu suất vẽ cao so với kết khơng lưu vết màu Ví dụ: set_current_color(red); Chương 2: Quản lý trạng thái vẽ vật thể hình học draw_object(A); draw_object(B); set_current_color(green); set_current_color(blue); draw_object(C); vẽ đối tượng A B màu đỏ đối tượng C có màu xanh lam Lệnh dòng thứ tư đặt màu thành màu xanh vơ ích Tơ màu (coloring), chiếu sáng (lighting) đổ bóng (shading) chủ đề lớn mà phải dành toàn chương sections l ớn dành cho Để vẽ đối tượng hình học sở nhìn thấy được, nhiên, bạn cần số kiến thức cách thiết lập màu hành; thông tin cung cấp đoạn (Xem Chương Chương để biết chi tiết chủ đề này.) Để thiết lập màu, sử dụng lệnh glColor3f() Nó lấy ba tham số, tất số chấm động nằm khoảng từ 0.0 đến 1.0 Các tham số, theo thứ tự, thành phần (component) màu đỏ, lục lam màu Bạn nghĩ ba giá trị đặc tả “kết hợp” màu sắc: 0.0 có nghĩa không sử dụng thành phần nào, 1.0 có nghĩa sử dụng tất thành phần Vì vậy, lệnh glColor3f(1.0, 0.0, 0.0) làm cho màu đỏ sáng mà hệ thống vẽ, khơng có thành phần màu lục màu lam Nếu tất số tạo thành màu đen; ngược lại, tất làm thành màu trắng Đặt tất ba thành phần thành 0,5 thành màu xám (ở màu đen màu trắng) Dưới tám lệnh màu sắc mà chúng thiết lập glColor3f(0.0, 0.0, 0.0); /* black */ glColor3f(1.0, 0.0, 0.0); /* red */ glColor3f(0.0, 1.0, 0.0); /* green */ glColor3f(1.0, 1.0, 0.0); /* yellow */ glColor3f(0.0, 0.0, 1.0); /* blue */ glColor3f(1.0, 0.0, 1.0); /* magenta */ glColor3f(0.0, 1.0, 1.0); /* cyan */ glColor3f(1.0, 1.0, 1.0); /* white */ Bạn nhận thấy trước lệnh để thiết lập màu xóa, glClearColor(), có bốn tham số, ba tham số ứng với tham số cho glColor3f() Tham số thứ tư giá trị alpha; đề cập chi tiết “Blending” Chương Hiện tại, thiết lập tham số thứ tư glClearColor() thành 0.0, giá trị mặc định 2.1.1.3 Ép việc vẽ hồn thành (Forcing completion of drawing) Như bạn thấy “OpenGL Rendering Pipeline” Chương 1, hầu hết hệ thống đồ họa đại coi pipeline Bộ xử lý trung tâm (CPU) đưa lệnh vẽ Có lẽ phần cứng khác thực chuyển đổi hình học Clipping đ ược thực hiện, tơ bóng và/hoặc texturing Cuối cùng, giá trị ghi vào bitplanes để hiển thị Trong kiến trúc cao cấp, hoạt động thực phần cứng khác thiết kế để thực nhiệm vụ cụ thể cách nhanh chóng Trong kiến trúc vậy, không cần CPU phải đợi cho lệnh vẽ để hoàn tất trước phát hành lệnh Trong CPU gửi vertex Chương 2: Quản lý trạng thái vẽ vật thể hình học xuống pipeline, phần cứng chuyển đổi làm việc vertex cuối gửi đi, trước bị cắt bớt, Trong hệ thống vậy, CPU chờ cho lệnh hoàn thành trước phát lệnh tiếp theo, làm ảnh hưởng hiệu suất lớn Ngồi ra, ứng dụng chạy nhiều máy Ví dụ: giả sử chương trình chạy nơi khác (trên máy gọi máy khách) bạn xem kết vẽ máy trạm thiết bị đầu cuối (máy chủ), kết nối mạng với máy khách Trong trường hợp đó, việc gửi lệnh qua mạng lúc khơng hiệu chi phí đáng kể thường liên quan đến lần truyền mạng Thông thường, máy khách tập hợp tập hợp lệnh thành gói mạng trước gửi Thật không may, mã mạng máy khách thường khơng có cách để biết chương trình đồ họa vẽ xong khung cảnh Trong trường hợp xấu nhất, đợi cho đủ lệnh vẽ bổ sung để lấp đầy gói bạn khơng nhìn thấy vẽ hồn chỉnh Vì lý này, OpenGL cung cấp lệnh glFlush(), buộc máy khách gửi gói mạng khơng đầy Khi khơng có mạng tất lệnh thực thi máy chủ, glFlush() khơng có tác dụng Tuy nhiên, bạn viết chương trình mà bạn muốn hoạt động bình thường có khơng có mạng, thêm lệnh gọi hàm glFlush() cuối khung hình cảnh Lưu ý glFlush() khơng đợi vẽ hồn thành – buộc việc vẽ bắt đầu thực thi, đảm bảo tất lệnh trước thực thi thời gian hữu hạn khơng có lệnh vẽ thực Có tình khác mà glFlush() hữu ích: ● Software renderers tạo hình ảnh nhớ hệ thống không muốn cập nhật liên tục hình ● Triển khai tập hợp lệnh kết xuất để khấu hao chi phí khởi động Ví dụ truyền mạng nói ví dụ điều Lệnh void glFlush(void) buộc lệnh OpenGL phát hành trước để bắt đầu thực hiện, đảm bảo chúng hồn thành thời gian hữu hạn Một vài lệnh — ví dụ, lệnh hoán đổi đệm chế độ đệm kép — tự động chuyển lệnh chờ xử lý vào mạng trước chúng xảy Nếu glFlush() không đủ cho bạn, thử glFinish() Lệnh xóa mạng glFlush() thực sau đợi thông báo từ phần cứng đồ họa mạng cho biết vẽ hoàn tất đệm khung Bạn cần sử dụng glFinish() bạn muốn đồng hóa tác vụ ví dụ: để đảm bảo kết xuất ba chiều bạn hiển thị hình trước bạn sử dụng Display PostScript để vẽ nhãn đầu hiển thị Một ví dụ khác đảm bảo vẽ hồn thành trước bắt đầu chấp nhận đầu vào người dùng Sau bạn đưa lệnh glFinish(), tiến trình đồ họa bạn bị chặn nhận thơng báo từ phần cứng đồ họa vẽ hoàn tất Hãy nhớ việc sử dụng nhiều glFinish() làm giảm hiệu suất ứng dụng, đặc biệt bạn chạy qua mạng, u cầu liên lạc Nếu glFlush() đủ cho nhu cầu bạn, sử dụng thay glFinish() void glFinish(void); Chương 2: Quản lý trạng thái vẽ vật thể hình học Bắt buộc hồn thành tất lệnh OpenGL phát hành trước Lệnh không trở lại tất hiệu ứng từ lệnh trước thực đầy đủ 2.1.1.4 Bộ công cụ hệ tọa độ (Coordinate system survival kit) Bất bạn mở cửa sổ ban đầu sau di chuyển thay đổi kích thước cửa sổ đó, hệ thống cửa sổ gửi kiện để thông báo cho bạn Nếu bạn sử dụng GLUT, thông báo tự động; quy trình đăng ký với glutReshapeFunc() gọi Bạn phải đăng ký chức gọi lại mà: ● Thiết lập lại vùng hình chữ nhật mà khung để vẽ ● Xác định hệ tọa độ mà đối tượng vẽ Trong Chương 3, bạn thấy cách xác định tọa độ ba chiều cần tạo hai chiều đơn giản, hệ tọa độ mà bạn vẽ vài đối tượng Gọi glutReshapeFunc(reshape), reshape() hàm hiển thị ví dụ void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); } ernel của GLUT truyền cho hàm hai đối số: chiều rộng chiều cao, tính pixel, K cửa sổ mới, di chuyển thay đổi kích thước glViewport() điều chỉnh hình chữ nhật pixel để vẽ thành tồn cửa sổ Ba quy trình điều chỉnh hệ tọa độ để vẽ cho góc bên trái (0, 0) góc bên phải (w, h) (xem Hình 2-1) Để giải thích theo cách khác, nghĩ mảnh giấy vẽ đồ thị Các giá trị w h reshape() b iểu thị số lượng cột hàng hình vng giấy vẽ đồ thị bạn Sau đó, bạn phải đặt trục giấy kẻ ô vuông Quy trình gluOrtho2D() đặt gốc, (0, 0), hình vng thấp nhất, ngồi bên trái làm cho hình vng đại diện cho đơn vị Bây giờ, bạn hiển thị điểm, đường thẳng đa giác phần lại chương này, chúng xuất trang giấy dạng hình vng dễ đốn (Hiện tại, giữ cho tất đối tượng bạn giống nhau.) Chương 2: Quản lý trạng thái vẽ vật thể hình học Hình 2.1.1.1: Hệ thống tọa độ với w = 50, h = 50 2.1.2 Mô tả điểm, đường thẳng, đa giác (Describing points, lines polygons) Giải thích cách mơ tả hình học OpenGL Tất hình học cuối mô tả dạng đỉnh tọa độ xác định điểm , điểm cuối đoạn thẳng góc đa giác Phần thảo luận cách thứ hiển thị bạn có quyền kiểm sốt hình chúng 2.1.2.1 Điểm, đường thẳng, đa giác (What are points, lines and polygons) Bạn có ý tưởng tốt ý nghĩa nhà toán học điều kiện điểm, đường thẳng đa giác Các ý nghĩa OpenGL tương tự nhau, không giống Một khác biệt đến từ hạn chế tính tốn dựa máy tính.Trong triển khai OpenGL nào, phép tính dấu phẩy động hữu hạn độ xác, chúng có sai số hồn chỉnh Do đó, tọa độ Các điểm, đường đa giác OpenGL gặp phải vấn đề tương tự Một khác biệt quan trọng phát sinh từ hạn chế đồ họa raster trưng bày Trên vậy, đơn vị nhỏ hiển thị pixel pixel rộng 1/100 inch chúng lớn nhiều so với khái niệm nhà toán học vô hạn nhỏ (đối với điểm) mỏng vô hạn (đối với đường) Khi OpenGL thực phép tính, giả định điểm biểu diễn dạng vectơ số dấu phẩy động Tuy nhiên, điểm thường (nhưng luôn) vẽ dạng pixel nhiều điểm khác với tọa độ khác vẽ OpenGL pixel ● Điểm (Points) Một điểm biểu diễn tập hợp số dấu phẩy động gọi đỉnh Tất tính tốn bên thực thể đỉnh ba chiều Dọc người dùng định hai chiều (nghĩa có tọa độ x y) OpenGL gán tọa độ z ● Đường thẳng (Lines) Trong OpenGL, thuật ngữ đường đề cập đến đoạn thẳng, phiên nhà tốn học mở rộng đến vơ theo hai hướng Có nhiều cách dễ dàng để định chuỗi đoạn thẳng kết nối, chí chuỗi đoạn khép kín, kết nối 10 Chương 2: Quản lý trạng thái vẽ vật thể hình học Dùng lệnh glGetIntegerv(GL_MAX_ CLIENT_ATTRIB_STACK_DEPTH, params) ngăn xếp thuộc tính khách Kết trả giá trị số nguyên không âm lưu params[0] d Chương trình báo lỗi khơng ngăn xếp rỗng, khơng thể thực lệnh phục hồi ngăn xếp trước Câu 2: Bitmask nhóm thuộc tính tổ hợp thuộc tính, bit bitmask đại diện cho thuộc tính, tổ hợp biến trạng thái khác Ví dụ bitmask: ● GL_LINE_BIT: nằm nhóm thuộc tính line, biến trạng thái bao gồm: GL_LINE_SMOOTH, GL_LINE_STIPPLE, Line stipple pattern and repeat counter, Line width ● GL_VIEWPORT_BIT: nằm nhóm thuộc tính viewport, biến trạng thái bao gồm: Depth range (near and far), Viewport origin and extent ● GL_POINT_BIT: nằm nhóm thuộc tính point, biến trạng thái bao gồm: GL_POINT_SMOOTH, Point size 70 Chương 2: Quản lý trạng thái vẽ vật thể hình học 2.3 Sản phẩm ứng dụng Trực quan hóa câu lệnh Thao tác với hình khởi tạo: ● Nhấn chuột trái để vào hình vẽ trực quan ● Nhấn chuột phải để thoát 2.3.1 Xóa hình Trong phần này, học cách xóa hình với màu khác ● Xố hình màu đỏ: void CleaningTheWindow::cleaningRed() { glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); } 71 Chương 2: Quản lý trạng thái vẽ vật thể hình học Giải thích: Đặt màu xóa đỏ với câu lệnh glClearColor(1.0, 0.0, 0.0, 0.0); xóa đệm màu với câu lệnh glClear(GL_COLOR_BUFFER_BIT); ● Xố hình màu hồng: void CleaningTheWindow::cleaningMagenta() { glClearColor(1.0,0.0,1.0,0.0); glClear(GL_COLOR_BUFFER_BIT); } Giải thích: Đặt màu xóa hồng với câu lệnh glClearColor(1.0,0.0,1.0,0.0); xóa đệm màu với câu lệnh glClear(GL_COLOR_BUFFER_BIT); 2.3.2 Vẽ đoạn thẳng Trong phần này, học cách để tạo đoạn thẳng nối hai điểm 72 Chương 2: Quản lý trạng thái vẽ vật thể hình học void DrawLine::draw() { glOrtho(0.0, 200.0, 0.0, 200.0, -1.0, 1.0); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex2f(50.0, 125.0); glVertex2f(150.0, 125.0); glEnd(); } Giải thích: Đặt màu với câu lệnh glColor3f(1.0, 1.0, 1.0); vẽ đoạn thẳng nối điểm (50.0; 125.0) (150.0; 125.0) 2.3.3 Vẽ hình chữ nhật Trong phần này, học cách để tạo hình chữ nhật cách khác nhau: void DrawRectangle::drawDefault() { glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); glColor3f (1.0, 1.0, 1.0); glBegin(GL_POLYGON); glVertex3f (0.25, 0.25, 0.0); glVertex3f (0.75, 0.25, 0.0); glVertex3f (0.75, 0.75, 0.0); glVertex3f (0.25, 0.75, 0.0); glEnd(); } Giải thích: Ta coi hình chữ nhật polygon, ta đặt tọa độ điểm polygon cặp glBegin() và glEnd() với tham số truyền vào glBegin() GL_POLYGON 73 Chương 2: Quản lý trạng thái vẽ vật thể hình học void DrawRectangle::drawAuto() { glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); glColor3f(1.0, 0.0f, 0.0f); glRectf(0.25f ,0.75f, 0.75f, 0.25f); glutSwapBuffers(); } Giải thích: Ta sử dụng hàm vẽ hình chữ nhật có sẵn mà openGL hỗ trợ glRectf() 2.3.4 Vẽ nét đứt Trong phần này, học cách vẽ hai loại nét đứt: Ví dụ 1: Chấm 74 Chương 2: Quản lý trạng thái vẽ vật thể hình học void Dotted::draw() { glOrtho(0.0, 200.0, 0.0, 200.0, -1.0, 1.0); glShadeModel (GL_FLAT); glColor3f (1.0, 1.0, 1.0); glEnable (GL_LINE_STIPPLE); // enable stipple pattern glLineStipple (1, 0x0101); /* dotted line */ glBegin(GL_LINES); glVertex2f (50.0,125.0); glVertex2f (150.0,125.0); glEnd(); glDisable (GL_LINE_STIPPLE); // disable stipple pattern } Giải thích: Thiết lập phép chiếu trực giao với toạ độ trái, phải, dưới, trên, gần, xa Sử dụng hàm glShadeModel(GL_FLAT) đ ể đặt đoạn thẳng tơ màu đồng (chế độ GL_FLAT) Đặt màu với câu lệnh glColor3f(1.0, 1.0, 1.0); Thiết lập kiểu vẽ chấm cách hàm glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x0101); đoạn thẳng nối điểm (50.0;125.0) (150.0;125.0) Ví dụ 2: Gạch void Dash::draw() { glColor3f (1.0, 1.0, 1.0); glEnable (GL_LINE_STIPPLE); glOrtho(0.0, 300.0, 0.0, 300.0, -1.0, 1.0); glLineStipple (1, 0x00FF); glBegin(GL_LINES); glVertex2f(50,125); 75 Chương 2: Quản lý trạng thái vẽ vật thể hình học glVertex2f(250,125); glEnd(); } Giải thích: Thiết lập phép chiếu trực giao với toạ độ trái, phải, dưới, trên, gần, xa Sử dụng hàm glShadeModel(GL_FLAT) để đặt đoạn thẳng tô màu đồng (chế độ GL_FLAT) Đặt màu với câu lệnh glColor3f(1.0, 1.0, 1.0); Thiết lập kiểu vẽ gạch cách hàm glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x00FF); đoạn thẳng nối điểm (50.0;125.0) (150.0;125.0) 2.3.5 Vẽ polygon void DrawPolygon::draw() { GLubyte fly[] = { 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x04, 0x60, 0x06, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x06, 0x60, 0x20, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66, 0x19, 0x81, 0x81, 0x98, 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x31, 0x8c, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x18, 0xcc, 0x33, 0x18, 0x10, 0x63, 0xC6, 0x08, 0x00, 0x06, 0x04, 0x04, 0x44, 0x44, 0x44, 0x44, 0x33, 0x0C, 0x03, 0x03, 0x0c, 0x10, 0x10, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x01, 0x01, 0x01, 0x01, 0xC1, 0x3f, 0x33, 0xcc, 0xc4, 0x30, 0x00, 0x03, 0x0C, 0x30, 0xC0, 0x80, 0x80, 0x80, 0x80, 0x83, 0xfc, 0xcc, 0x33, 0x23, 0x0c, 0x00, 0x60, 0x20, 0x20, 0x22, 0x22, 0x22, 0x22, 0xCC, 0x30, 0xc0, 0xc0, 0x30, 0x08, 0x08, 76 Chương 2: Quản lý trạng thái vẽ vật thể hình học 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08}; GLubyte halftone[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55}; glShadeModel(GL_FLAT); glOrtho(-50.0, 400.0, -200.0, 400.0, -1.0, 1.0); glColor3f(1.0, 1.0, 1.0); /* draw one solid, unstippled rectangle, */ /* then two stippled rectangles */ glRectf(25.0, 25.0, 125.0, 125.0); glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(fly); glRectf(125.0, 25.0, 225.0, 125.0); glPolygonStipple(halftone); glRectf(225.0, 25.0, 325.0, 125.0); glDisable(GL_POLYGON_STIPPLE); } Giải thích: Ta sử dụng hàm vẽ hình chữ nhật glRectf() để vẽ hình chữ nhật sát nhau, hình chữ nhật sau ta vẽ theo tham số chuyền vào qua mảng fly và halftone b ằng cách kích hoạt GL_POLYGON_STIPPLE với glEnable(GL_POLYGON_STIPPLE) sau vẽ xong ta tắt với glDisable(GL_POLYGON_STIPPLE) 2.3.6 Xây dựng bề mặt đa giác vật thể 2.3.6.1 Những lưu ý xây dựng mơ hình đa giác bề mặt vật thể 77 Chương 2: Quản lý trạng thái vẽ vật thể hình học Trong phần này, học cách để tạo bề mặt vật thể từ khối đa giác Nếu chưa có kinh nghiệm, việc bắt đầu gặp khơng khó khăn Sau số điểm cần lưu ý để dễ tiếp cận vấn đề hơn: ● Giữ cho hướng đa giác quán Đảm bảo nhìn đa giác từ bên ngoài, đa giác tạo nên bề mặt vật thể có hướng (cùng theo chiều kim đồng hồ theo ngược chiều kim đồng hồ) Định hướng quán vô quan trọng việc thực phép chiếu với đa giác điều chỉnh ánh sáng khác phụ thuộc vào mặt hay đa giác Việc định hướng nhiều thời gian, nhiên giảm chi phí sửa lỗi điều chỉnh công đoạn sau (khi sử dụng hàm glScale*() để thực phép đối xứng hình học qua trục tọa độ, thay đổi hướng hàm glFrontFace() để giữ cho hướng đa giác quán) ● Khi chia nhỏ bề mặt, cần lưu ý với đa giác tam giác Tam giác đảm bảo việc ba điểm nằm mặt phẳng, đa giác với điểm trở lên khơng đảm bảo điều Các đa giác khơng phẳng khơng OpenGL tạo cách chuẩn xác ● Luôn có đánh đổi tốc độ hiển thị chất lượng hình ảnh Nếu chia bề mặt thành vài đa giác, tốc độ hiển thị nhanh bề mặt không đủ mượt Nếu chia bề mặt thành nhiều đa giác nhỏ, bề mặt mượt tốc độ hiển thị lâu Mục tiêu tìm tham số thích hợp mục đích hiển thị khác Ví dụ vật thể xa với tầm mắt, hiển thị dạng thô so với vật thể gần với tầm mắt vật thể có bề mặt phẳng, việc chia nhỏ thành đa giác nhỏ không cần thiết ● Đối với hình ảnh chất lượng cao, việc phân tách cạnh đa giác tốt so với việc phân tách bề mặt ● Tránh trường hợp tạo cạnh hình chữ T (T-intersection) chia cắt đa giác Xem hình bên dưới, khơng thể đảm bảo hai đoạn thẳng AB BC nằm đoạn thẳng AC thực biến đổi đa giác Điều khắc phục cách phân tách đa giác Hình 2.6.1.1: Tránh trường hợp cạnh hình chữ T (T-intersection) ● Nếu xây dựng bề mặt nhỏ, cần phải tăng độ xác tọa độ số thực bề mặt Dưới ví khơng tốt để sinh hình trịn /* don't use this code */ 78 Chương 2: Quản lý trạng thái vẽ vật thể hình học #define PI 3.14159265 #define EDGES 30 /* draw a circle */ glBegin(GL_LINE_STRIP); for (i = 0; i