MỤC LỤC
TỔNG QUAN VỀ ĐỀ TÀI
Chương 1. GIỚI THIỆU THƯ VIỆN OPENGL VÀ CÁCH CÀI ĐẶT . 5
1.1. Giới thiệu . 5
1.2. Cách cài đặt . 6
1.2.1. Môi trường cài đặt . 6
1.2.2. Cài đặt . 6
1.2.3. Sử dụng thư viện openGL 7
Chương 2. CƠ BẢN VỀ OPENGL . 8
2.1. Cấu trúc chương trình openGL đơn giản 8
2.1.1. Khởi tạo 8
2.1.2. Tạo của sổ 9
2.1.3. Chức năng hiển thị 9
2.1.4. Chức năng định lại hình . 10
2.1.5. Vòng lặp chính 10
2.1.6. Mã nguồn 1 chương trình đơn giản 10
2.2. Dữ liệu và thuộc tính . 12
2.2.1. Cú pháp lệnh của OpenGL 12
2.2.2. Máy trạng thái . 13
2.3. Các thư viện liên quan . 14
2.4. Hoạt cảnh (Animation ) . 15
Chương 3. CÁC KỸ THUẬT OPENGL CƠ BẢN 16
3.1. Các đối tượng hình học ( Geometric Objects ) 16
3.1.1. Points, Lines and Polygons . 17
3.1.2. Vẽ các đối tượng không gian ( Drawing 3-D Objects ) . 19
3.1.3. Các phép biến đổi ( Transformations ) 20
3.1.4. Danh sách hiển thị ( Display Lists ) . 21
3.2. Khung hiển thị ( Viewing ) . 23
3.2.1. Màu sắc ( Color ) 23
3.2.2. Độ bóng ( Shading ) 24
3.2.3. Khung hình biến đổi ( Viewing Transformation ) . 24
3.2.4. Phép chiếu ( Projection ) . 25
3.2.5. Thao tác ngăn xếp ma trận ( Manipulating the Matrix Stacks ) 26
3.2.6. Ánh sáng ( Light ) . 27
3.2.7. Khung quan sát biến đổi ( Viewport Transformation ) . 28
Chương 4. CHƯƠNG TRÌNH DEMO . 29
4.1. Các kỹ thuật sử dụng cho chương trình 29
4.2. Mã nguồn 30
4.3. Kết quả chạy . 36
TỔNG QUAN VỀ ĐỀ TÀI
1. Bối cảnh và lý do thực hiện đề tài
Ngày nay đồ họa máy tính đóng một vai trò quan trong, quyết định không nhỏ đến sự thành công hay thất bại của một sản phẩm phần mềm. Sản phẩm làm ra ngoài tính năng đáp ứng được nhu cầu sử dụng thì mẫu giao diện đồ họa phải bắt mắt, than thiện với người sử dụng, có như thế thì sản phẩm mới có thể thành công. Ngoài các sản phẩm phần mềm thì một xu hướng mới nữa đó là các bộ phim hoạt hình 3D cũng đang rất được quan tâm.
Nhận thấy tìm năng vả khả năng phát khiển mạnh của công nghiệp đồ họa, chúng em lựa chọn đề tài: Lập trình đồ họa ứng dụng thư viện OpenGL trên Linux. Đây là một thư viên hỗ trợ các công cụ mạnh mẽ để vẽ và xử lý các đối tượng đồ họa.
2. Mục tiêu đề tài
Tìm hiểu lý thuyết thư viện OpenGLXây dựng chương trình đồ họa demo với OpenGL
38 trang |
Chia sẻ: lvcdongnoi | Lượt xem: 3666 | Lượt tải: 3
Bạn đang xem trước 20 trang tài liệu Đề tài Lập trình đồ họa ứng dụng thư viện opengl trên linux, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ỆN OPENGL TRÊN LINUX
Sinh viên : Lê Phương Tiến 07T2
Hà Phước Việt 07T1
Cán bộ hướng dẫn : Nguyễn Tấn Khôi
Đà Nẵng 2010
NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN
MỤC LỤC
TỔNG QUAN VỀ ĐỀ TÀI
TỔNG QUAN VỀ ĐỀ TÀI
1. Bối cảnh và lý do thực hiện đề tài
Ngày nay đồ họa máy tính đóng một vai trò quan trong, quyết định không nhỏ đến sự thành công hay thất bại của một sản phẩm phần mềm. Sản phẩm làm ra ngoài tính năng đáp ứng được nhu cầu sử dụng thì mẫu giao diện đồ họa phải bắt mắt, than thiện với người sử dụng, có như thế thì sản phẩm mới có thể thành công. Ngoài các sản phẩm phần mềm thì một xu hướng mới nữa đó là các bộ phim hoạt hình 3D cũng đang rất được quan tâm.
Nhận thấy tìm năng vả khả năng phát khiển mạnh của công nghiệp đồ họa, chúng em lựa chọn đề tài: Lập trình đồ họa ứng dụng thư viện OpenGL trên Linux. Đây là một thư viên hỗ trợ các công cụ mạnh mẽ để vẽ và xử lý các đối tượng đồ họa.
2. Mục tiêu đề tài
Tìm hiểu lý thuyết thư viện OpenGL
Xây dựng chương trình đồ họa demo với OpenGL
GIỚI THIỆU THƯ VIỆN OPENGL VÀ CÁCH CÀI ĐẶT
Giới thiệu
OpenGL là một cấp thấp thư viện đồ họa đặc điểm kỹ thuật. Nó làm cho có sẵn cho các lập trình một nhóm nhỏ các hình học cơ bản - điểm, đường, đa giác, hình ảnh, và ảnh bitmap. OpenGL cung cấp một bộ các lệnh cho phép các đặc điểm kỹ thuật của các đối tượng hình học trong hai hoặc ba chiều, sử dụng cơ bản cung cấp, cùng với các lệnh để điều khiển các đối tượng này là kết xuất (GLUT).
Từ bản vẽ lệnh OpenGL được giới hạn bởi các hình học đơn giản (điểm, đường, và đa giác), các OpenGL Utility Toolkit đã được tạo ra để trợ giúp trong việc phát triển phức tạp hơn các đối tượng ba chiều như một quả cầu, một xuyến, và thậm chí một ấm trà. GLUT có thể không được thỏa đáng cho đầy đủ tính năng ứng dụng OpenGL, nhưng nó là một điểm khởi đầu hữu ích cho việc học OpenGL.
GLUT được thiết kế để lấp đầy sự cần thiết cho một hệ thống độc lập lập trình giao diện cửa sổ cho các chương trình OpenGL. Giao diện được thiết kế đơn giản nhưng vẫn đáp ứng các nhu cầu của các chương trình hữu ích OpenGL. Loại bỏ các hoạt động hệ thống cửa sổ từ OpenGL là một quyết định âm thanh bởi vì nó cho phép hệ thống đồ họa OpenGL được retargeted cho các hệ thống khác nhau bao gồm nhưng đắt tiền máy trạm đồ họa mạnh mẽ cũng như sản xuất hàng loạt hệ thống đồ họa như trò chơi video, hộp set-top cho truyền hình tương tác, và máy tính cá nhân.
GLUT đơn giản hóa việc thực hiện các chương trình sử dụng OpenGL rendering. Việc áp dụng dư thừa giao diện lập trình (API) đòi hỏi vài thói quen rất để hiển thị một cảnh kết xuất bằng cách sử dụng đồ họa OpenGL.Việc dư thừa thói quen cũng có thông số tương đối ít.
Cách cài đặt
Môi trường cài đặt
Quá trình tìm hiểu và viết chương trình được thực hiện trên môi trường Linux phiên bản Ubuntu 10.10. OpenGL là một bộ thư viện mở có thể sử dụng ở môi cả môi trường Windows nhưng Ubuntu là một hệ điều hành mở, kho tài liệu phong phú, luôn có một cộng động sẵn sang giúp đỡ khi có vẫn đề khó khăn.
Các gói thư viện của openGL : GLUT,AUX, XLIB…..
Cài đặt
Cài đặt trình biên dịch C/C++ GNU: tại terminal gõ
Sudo apt-get install gcc
Sudo apt-get install g++
Sau khi cài đặt kiểm tra lại thử đã có hay chưa
Cài đặt bộ thư viện Opengl
Administrator->synaptic->search với từ khóa opengl: Lựa chọn và make các file cần thiết và apply
Sử dụng thư viện openGL
Cách biên dịch 1 bài C đơn giản
Cách biên dịch C có sử dụng thư viện OpenGL
Tại terminal gõ: gcc [filenam].c –o [filenam] –lglut –lGLU –lGL
Dùng makefile : vào terminalà đưa về thư mục chứa code và makefile à gõ make là xong
CƠ BẢN VỀ OPENGL
Cấu trúc chương trình openGL đơn giản
Khởi tạo
Điều đầu tiên chúng ta cần làm là gọi glutInit () làm thủ tục khởi tạo. Nó phải được gọi trước khi bất kỳ đối tượng GLUT nào bởi vì nó khởi tạo thư viện GLUT . Các tham số để glutInit () được truyền từ main (), cụ thể (int argv mà, char ** argv) và glutInit & argv mà, (argv) , nơi argcp là một con trỏ đến chương trình của cố định biến argv mà từ chính. Khi trả về, giá trị được trỏ đến bởi argcp sẽ được cập nhật, và argv là argv biến của chương trình chưa sửa đổi từ chính. Giống như argcp, các dữ liệu cho argv sẽ được cập nhật.
Điều tiếp theo chúng tôi cần làm là gọi glutInitDisplayMode () làm thủ tục để xác định chế độ hiển thị cho cửa sổ.Bạn phải quyết định xem bạn muốn sử dụng một RGBA (GLUT_RGBA) hoặc màu chỉ số (GLUT_INDEX) mô hình màu. Các chế độ RGBA cửa hàng các bộ đệm màu sắc của nó là thành phần màu đỏ, xanh lá cây, xanh dương, và alpha. Các thành phần ra màu sắc, alpha, tương ứng với khái niệm mờ(độ sang). Một giá trị alpha là 1.0 có nghĩa opacity hoàn tất, và giá trị alpha của một độ trong suốt hoàn toàn 0.0. Chế độ chỉ số màu sắc, tương phản, màu sắc bộ đệm trong các cửa hàng indicies. Quyết định của bạn về chế độ màu nên được dựa trên phần cứng sẵn có và những gì bạn ứng dụng đòi hỏi màu sắc khác thường có thể được đại diện đồng thời với chế độ RGBA hơn với chế độ chỉ số màu. Và cho các hiệu ứng đặc biệt, như bóng, ánh sáng, và sương mù, RGBA chế độ cung cấp linh hoạt hơn. Nhìn chung, sử dụng chế độ RGBA bất cứ khi nào có thể. RGBA chế độ mặc định.
Khi thiết lập chế độ hiển thị là liệu bạn muốn sử dụng đệm đơn (GLUT_SINGLE) hoặc đệm đôi (GLUT_DOUBLE. Các ứng dụng sử dụng cả hai mặt trước và các bộ đệm màu sắc trở lại là đôi đệm.Sự mền mại hoạt hình được thực hiện bằng cách vẽ vào bộ đệm chỉ trở lại (không hiển thị), sau đó gây ra mặt trước và sau bộ đệm được đổi chỗ. Nếu bạn không sử dụng annimation, gắn bó với đệm duy nhất, đó là mặc định.
Cuối cùng, bạn phải quyết định xem bạn muốn sử dụng một bộ đệm chiều sâu (GLUT_DEPTH), đệm stencil (GLUT_STENCIL) và / hoặc đệm một sự tích lũy (GLUT_ACCUM). Các đệm cửa hàng chuyên sâu một giá trị chuyên sâu cho mỗi điểm ảnh. Bằng cách sử dụng một "bài kiểm tra chiều sâu", bộ đệm độ sâu có thể được sử dụng để hiển thị các đối tượng có giá trị độ sâu nhỏ hơn ở phía trước của các đối tượng có giá trị độ sâu lớn hơn. Các bộ đệm thứ hai, bộ đệm stencil được sử dụng để hạn chế vẽ để phần nào đó của màn hình, chỉ như là một stencil tông có thể được sử dụng với một hộp sơn xịt để làm cho một hình ảnh in. Cuối cùng, bộ đệm tích lũy được sử dụng để tích lũy một loạt các hình ảnh vào một hình ảnh sáng tác cuối cùng. Không ai trong số này là các bộ đệm mặc định.
Cần phải tạo ra các đặc tính của cửa sổ. Một tham số đến glutInitWindowSize () sẽ được sử dụng để xác định kích thước, trong ảnh, trong cửa sổ inital của bạn. Chiều cao và chiều rộng (bằng pixel) của cửa sổ yêu cầu. Tương tự như vậy, glutInitWindowPosition () được sử dụng để xác định vị trí màn hình cho góc trên bên trái của cửa sổ ban đầu. Những giá trị, x và y, cho biết vị trí của các cửa sổ liên quan đến toàn bộ màn hình hiển thị.
Tạo của sổ
Để thực sự tạo ra một cửa sổ, với các thiết lập đặc điểm trước đó (hiển thị chế độ, kích thước, vị trí, vv), sử dụng glutCreateWindow () để khởi tạo. Lệnh này có một chuỗi như một tham số mà có thể xuất hiện trong thanh tiêu đề nếu hệ thống cửa sổ bạn đang sử dụng hỗ trợ nó cửa sổ là không thực sự hiển thị cho đến khi glutMainLoop () được nhập vào.
Chức năng hiển thị
Hàm glutDisplayFunc () làm thủ tục là sự kiện quan trọng đầu tiên của hầu hết các chức năng gọi lại và hiển thị . Một chức năng gọi lại là một trong những nơi hàm đã được định nghĩa ,ứng với mỗi hàm sẽ có một sự kiện phù hợp . Ví dụ, các đối số của glutDisplayFunc () là chức năng được GLUT xác định rằng nội dung của cửa sổ cần phải được hiển thị lại. Vì vậy, bạn nên đặt tất cả các hàm mà bạn cần hiển thị ra một cảnh trong chức năng gọi lại hiển thị.
Chức năng định lại hình
Hàm glutReshapeFunc () là một chức năng gọi lại rằng quy định cụ thể chức năng đó được gọi là bất cứ khi nào cửa sổ được thu nhỏ hoặc di chuyển. Thông thường, các chức năng đó được gọi khi cần thiết cho thay đổi hình dáng chức năng hiển thị cửa sổ với kích thước mới và định nghĩa lại các đặc tính xem như mong muốn. Nếu glutReshapeFunc () là không được gọi, một mặc định chức năng thay đổi hình dáng mà được gọi là bộ giao diện để giảm thiểu sự biến dạng và đặt ra các màn hình hiển thị lên tầm cao mới và chiều rộng.
Vòng lặp chính
Cuối là gọi glutMainLoop (). Tất cả các cửa sổ đã được tạo ra có thể được hiển thị, và vẽ những cửa sổ hiện có hiệu quả. Chương trình sẽ có thể xử lý các sự kiện như chúng xảy ra (click chuột, thay đổi kích thước cửa sổ, vv.). Ngoài ra, các cuộc gọi lại hiển thị (từ glutDisplayFunc () ) được kích hoạt. Sau khi vòng lặp này được nhập vào, nó không bao giờ đã thoát!
Điều quan trọng cần lưu ý rằng các lệnh OpenGL không nhất thiết phải thực hiện ngay khi chúng được phát hành. Nó là cần thiết để gọi lệnh glFlush () để đảm bảo rằng tất cả các lệnh đã ban hành trước đây được thực hiện. glFlush () được gọi chung là ở phần cuối của một chuỗi các bản vẽ lệnh để đảm bảo tất cả các đối tượng trong cảnh được vẽ trước khi bắt đầu chấp nhận của người dùng .
Mã nguồn 1 chương trình đơn giản
Cấu trúc một chương trình
#include
#include
void handleKeypress(unsigned char key, int x, int y) {
}
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
}
void drawScene() {
}
int main(int argc, char** argv) {
//Khoi tao GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400); /
// Tao cua so
glutCreateWindow("Demo");
initRendering(); //Khoi tao cac thuoc tinh lien qua
// cac ham ve, lay ban phim va resize
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutMainLoop(); //vong lap chinh de duy tri su ve
return 0;
}
Ví dụ chương trình đơn giản “Hello.c”
#include
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f (0.25, 0.25, 0.0);
glVertex3f (0.75, 0.2 5, 0.0);
glVertex3f (0.75, 0.75, 0.0);
glVertex3f (0.25, 0.75, 0.0);
glEnd();
glFlush ();
}
void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Dữ liệu và thuộc tính
Cú pháp lệnh của OpenGL
Có thể quan sát được từ chương trình đơn giản trong phần trước, lệnh OpenGL sử dụng các chữ cái và vốn ban đầu gl tiền tố cho mỗi từ tạo thành tên lệnh (gọi lại glClearColor (). Tương tự như vậy, OpenGL xác định hằng số bắt đầu bằng GL_, sử dụng tất cả các chữ in hoa, và sử dụng gạch dưới những từ riêng biệt (như GL_COLOR_BUFFER_BIT).
Bạn cũng có thể đã nhận thấy một số không liên quan thư dường như nối thêm vào một số tên lệnh (các 3f trong glColor3f ()). Sự thật là phần màu của tên lệnh là đủ để xác định các lệnh là một trong những bộ màu sắc hiện hành. Tuy nhiên, nhiều hơn một lệnh như vậy đã được xác định để bạn có thể sử dụng các loại khác nhau của các đối số;. Trong đó, 3 phần của hậu tố chỉ ra rằng ba đối số được đưa ra một phiên bản của lệnh màu có bốn tham số của. F Phần hậu tố cho thấy rằng các đối số là số điểm float. Một số các lệnh OpenGL chấp nhận có đến tám loại dữ liệu khác nhau cho các đối số của họ. Các chữ được sử dụng như là hậu tố để xác định các kiểu dữ liệu cho ANSI C triển khai thực hiện của OpenGL được thể hiện trong Bảng 1-1, cùng với các định nghĩa OpenGL loại tương ứng. Việc thực hiện cụ thể của OpenGL mà bạn đang sử dụng có thể không tuân theo sơ đồ chính xác, một thực hiện trong C + + hay Ada, ví dụ, không cần.
Như vậy, hai lệnh
glVertex2i(1, 3);
glVertex2f(1.0, 3.0);
là tương đương, trừ trường hợp đầu tiên xác định tọa độ của đỉnh là số nguyên 32-bit và lần thứ hai quy định chúng như là một điểm chính xác con số thực.
Máy trạng thái
OpenGL là một máy trạng thái. Bạn đặt nó vào trạng thái khác nhau (hay chế độ) mà sau đó vẫn có hiệu lực cho đến khi thay đổi chúng. Như đã thấy, màu sắc hiện nay là một biến trạng thái. Có thể đặt màu hiện tại để trắng, đỏ, hoặc bất kỳ màu nào khác, và sau đó mỗi đối tượng được vẽ với màu sắc cho đến khi bạn thiết lập màu hiện tại để cái gì khác. Màu sắc hiện tại chỉ là một trong nhiều biến trạng thái OpenGL lưu trữ . Những điều khiển kiểm soát những thứ như xem hiện tại và biến đổi chiếu, đường và các mẫu cách ve từng đốm đa giác, đa giác chế độ vẽ, pixel-đóng gói các công ước, vị trí và đặc điểm sáng,các đối tượng vẽ. Nhiều biến trạng thái tham khảo các chế độ được kích hoạt hay vô hiệu hóa với lệnh glEnable () hoặc glDisable ().
Mỗi biến trạng thái hoặc có một giá trị mặc định, và tại bất kỳ điểm nào bạn có thể truy vấn các hệ thống giá trị hiện tại của mỗi biến. Thông thường, bạn sử dụng một trong bốn lệnh sau đây để làm điều này: glGetBooleanv () glGetDoublev, (), glGetFloatv (), hoặc glGetIntegerv (). Những lệnh này bạn chọn phụ thuộc vào kiểu dữ liệu bạn muốn trả lời được cho in Một số biến trạng thái có lệnh truy vấn cụ thể hơn (như glGetLight * (), glGetError (), hoặc glGetPolygonStipple ()). Ngoài ra, bạn có thể lưu và sau đó khôi phục lại các giá trị của một tập hợp các biến trạng thái trên một thuộc tính stack với glPushAttrib () và glPopAttrib () lệnh. Bất cứ khi nào có thể, bạn nên sử dụng các lệnh này hơn là bất kỳ trong những lệnh truy vấn, vì chúng tôi có thể sẽ hiệu quả hơn.
Danh sách đầy đủ của các biến trạng thái bạn có thể truy vấn được tìm thấy trong Phụ lục B. Đối với mỗi biến, phụ lục này cũng liệt kê các * glGet () lệnh trả về giá trị của biến, lớp thuộc tính mà nó thuộc về, và giá trị mặc định của biến.
Các thư viện liên quan
OpenGL cung cấp một bộ thư viện mạnh mẽ của các lệnh vẽ, và các thư viện hỗ trợ cao hơn cho người lập trình . Do đó, có thể muốn viết thư viện riêng trên đầu trang của OpenGL để đơn giản hóa công việc lập trình. Ngoài ra, có thể muốn viết một số một thủ tục chương trình OpenGL để làm việc dễ dàng với hệ thống cửa sổ của bạn. Trong thực tế, chẳng hạn một số thư viện và thói quen đã được bằng văn bản để cung cấp các tính năng chuyên ngành.
The OpenGL Utility Library (GLU), có chứa một số thủ tục sử dụng các lệnh OpenGL cấp thấp hơn để thực hiện các công việc như thiết lập các ma trận để xem định hướng cụ thể và các dự đoán, thực hiện sự lót đá đa giác, và các bề mặt vẽ. Thư viện này được cung cấp như một phần của OpenGL thực hiện của bạn. Đó là mô tả chi tiết tại Phụ lục C và trong OpenGL Reference Manual. Glu sử dụng tiền tố Glu.
The OpenGL Extension to the X Window System (GLX), cung cấp một phương tiện của việc tạo ra một bối cảnh OpenGL và liên kết nó với một cửa sổ drawable trên một máy có sử dụng X Window System. GLX được cung cấp như là một hỗ trợ cho OpenGL. Đó là mô tả chi tiết hơn trong cả hai D Phụ lục và OpenGL Reference Manual. Một trong những sử dụng GLX (cho framebuffer trao đổi) được mô tả trong "hoạt hình”. GLX sử dụng tiền tố glx.
The OpenGL Programming Guide Auxiliary Library ( AUX ), Thư viện đã được viết riêng cho cuốn sách này để làm ví dụ lập trình đơn giản và chưa hoàn chỉnh hơn. Đó là chủ đề của phần tiếp theo, và đó là mô tả chi tiết tại Phụ lục E, sử dụng thư viện aux tiền tố. "Làm thế nào để Lấy mẫu mã" mô tả làm thế nào để có được những mã nguồn cho các thư viện phụ trợ.
Open Inventor là một bộ công cụ định hướng đối tượng dựa trên OpenGL cung cấp các đối tượng và phương pháp để tạo chiều tương tác đồ họa ba ứng dụng. Có sẵn từ Silicon Graphics và viết bằng C + +, Open Inventor cung cấp xây dựng các đối tượng trước và tích hợp sẵn trong trường hợp mô hình cho tương tác người dùng, cao cấp thành phần ứng dụng cho việc tạo và ba chiều cảnh chỉnh sửa, và khả năng in ấn các đối tượng và trao đổi dữ liệu trong đồ họa khác định dạng.
Hoạt cảnh (Animation )
Một trong những điều thú vị nhất mà bạn có thể làm trên một máy tính đồ họa được vẽ hình ảnh chuyển động. Cho dù bạn là một kỹ sư đang cố gắng để xem tất cả các mặt của một phần cơ khí bạn đang thiết kế, một phi công học tập để bay một máy bay sử dụng một mô phỏng, hay chỉ đơn thuần là trò chơi máy tính một người đam mê, thì rõ ràng rằng hoạt hình là một phần quan trọng trong đồ họa máy tính .
Để tạo ra một sử chuyển động của hình ảnh thì chỉ việc thay đổi các frame và kỹ thuật này được dùng để làm hoạt hình, các đồ họa khác. Nhưng với sự vẽ xóa liên tục các frame sẽ làm cho hệ thống không đáp ứng được và hình ảnh hiển thị không được mượt mà. OpenGL cung cấp bộ thư viện với các phương thước nhắm đưa các frame vào các bộ đệm và kỹ thuật dùng bộ đệm làm cho hình ảnh đưa ra được như ý muốn.
Ví dụ minh họa việc sử dụng các glXSwapBuffers () trong một ví dụ đó rút ra một hình vuông mà quay liên tục, như trong hình.
CÁC KỸ THUẬT OPENGL CƠ BẢN
Các đối tượng hình học ( Geometric Objects )
Tất cả các hình khối được vẽ trong opengl đều được nằm giữa hai dòng lệnh glBegin() và glEnd() (Hơi giống với pascal).Có thể có nhiều cặp dòng lệnh như vậy, tức là có thể viết các hàm vẽ khác nhau và dùng cặp câu lệnh trên trong các hàm đó.Tham số của glBegin() là GL_LINE_LOOP có nghĩa là nó bảo window vẽ một đường khép kín điểm đầu trùng với điểm cuối.
Dưới đây là một số hằng số cơ bản:
Hằng số ý nghĩa
GL_POINT Vẽ điểm
GL_LINE Vẽ đường thẳng nối hai điểm
GL_LINE_STRIP Tập hợp của những đoạn đựơc nối với nhau
GL_LINE_LOOP Đường gấp khúc khép kín
GL_TRIANGLES Vẽ hình tam giác
GL_QUADS Vẽ tứ giác
GL_TRIANGLES_STRIP Vẽ một tập hợp các tam giác liền nhau, chung một cạnh
GL_QUAD_STRIP Vẽ một tập hợp các tứ giác liền nhau, chung một cạnh
GL_TRIANGLE_FAN Vẽ hình quạt
Dưới đây là bức tranh toàn cảnh về các thông số này.
Points, Lines and Polygons
Mỗi đối tượng hình học được mô tả bằng một tập các đỉnh và các loại nguyên thủy được rút ra. Đỉnh A là không nhiều hơn một điểm được xác định trong không gian ba chiều. Hay không và làm thế nào các đỉnh được kết nối được xác định bởi các loại nguyên thủy. Mỗi đối tượng hình học là cuối cùng được mô tả như là một yêu cầu thiết lập các đỉnh. Sử dụng * glVertex () lệnh để xác định một đỉnh. . Các '*' được dùng để chỉ ra rằng có những khác biệt để các lệnh cơ bản glVertex () .
Một số tên lệnh OpenGL có một, hai, hoặc ba chữ cái ở cuối để biểu thị số lượng và kiểu của các tham số cho lệnh. Các ký tự đầu tiên chỉ số giá trị của các loại chỉ ra rằng phải được trình bày cho lệnh. Nhân vật thứ hai cho các loại hình cụ thể của các đối số. Cuối cùng, nếu có, là 'v', cho biết lệnh này có một con trỏ tới một mảng (vector) của giá trị hơn là một loạt các đối số cá nhân.
Ví dụ, trong lệnh glVertex3fv () , '3 'được dùng để chỉ ba đối số,' f 'được dùng để chỉ các đối số là điểm trôi, và' v 'chỉ ra rằng các đối số là ở định dạng vector.
Điểm: điểm A là xác định bởi một đỉnh duy nhất. Đỉnh quy định bởi người sử dụng như là hai chiều (chỉ có x và y-tọa độ). Để điều chỉnh kích thước của một điểm kết xuất, sử dụng glPointSize () và cung cấp các kích thước mong. Mặc định là như 1 điểm ảnh theo điểm pixel 1. Nếu chiều rộng quy định là 2,0, điểm sẽ được một hình vuông của 2 bằng 2 điểm ảnh. glVertex * () được sử dụng để mô tả một điểm, nhưng nó chỉ có hiệu quả giữa một glBegin () và một glEnd () cặp. Các đối số được truyền cho glBegin () xác định những loại hình học nguyên thủy được xây dựng từ các đỉnh.
Ví dụ :
glBegin (GL_POINTS) ;
glVertex2f(0.0, 0.0) ; glVertex2f(0.0, 3.0) ; glVertex2f(4.0, 3.0) ; glVertex2f(6.0, 1.5) ; glVertex2f(4.0, 0.0) ;
glEnd() ;
Lines: Trong OpenGL, dòng ám chỉ đến một đoạn đường, không phải là phiên bản của toán học kéo dài đến vô cực ở cả hai hướng. Cách dễ nhất để xác định một đường là có điểm đầu và điểm cuối. Như với những điểm nêu trên, tham số truyền cho glBegin () bắt đầu thực hiện vẽ. Các tùy chọn cho các dòng bao gồm:
GL_LINES: Vẽ một loạt các đoạn đường chưa được nối rút ra giữa mỗi thiết lập các đỉnh. Một đỉnh không liên quan được bỏ qua.
GL_LINE_STRIP: Vẽ một đoạn thẳng từ đỉnh đầu đến cuối. Đường có thể cắt nhau tùy tiện.
GL_LINE_LOOP: Tương tự như GL_STRIP, ngoại trừ một đoạn đường cuối cùng được rút ra từ các đỉnh cuối cùng trở về đầu tiên.
Với OpenGL, mô tả hình dạng của một đối tượng đang được rút ra là độc lập với mô tả về màu sắc của nó. Khi một đối tượng paraticular hình học được rút ra, đó là rút ra bằng cách sử dụng các chương trình hiện quy định màu. Nói chung, lập trình OpenGL đầu tiên thiết lập màu sắc, bằng cách sử dụng * glColor () và sau đó rút ra các đối tượng. Cho đến khi màu sắc được thay đổi, tất cả các đối tượng được rút ra trong màu sắc hoặc sử dụng có màu sắc.
Ví dụ: glBegin; glColor3f(1.0, 1.0, 0.0); // yellow glVertex2(-1.0, 1,0); glVertex2f(2.0, 2.0); glColor3f(1.0, 0.0, 0.0); // red glVertex2f(0.0, 0.0); glVertex2f(1.0, -1.0); glVertex2f(-2.0, -2.0);
glEnd();
Đa giác: Đa giác là các khu vực được bao bọc bởi một vòng khép kín của các phân đoạn đường, nơi các đoạn đường được quy định bởi các đỉnh tại điểm cuối của họ. Đa giác thường được vẽ với các điểm ảnh trong điền vào, nhưng bạn cũng có thể vẽ chúng như là phác thảo hoặc thiết lập một điểm. Trong OpenGL, có một vài hạn chế về những gì tạo thành một đa giác nguyên thủy. Ví dụ, các cạnh của một đa giác không thể cắt nhau và chúng phải được lồi (không có vết lõm). Có các lệnh đặc biệt cho một (tam giác) ba mặt và bốn mặt (tứ giác) đa giác, glBegin (GL_TRIANGLES) và glBegin (GL_QUADS) .. Tuy nhiên, trường hợp tổng quát của một đa giác có thể được định nghĩa bằng cách sử dụng glBegin (GL_POLYGON) .
Ví dụ : glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 0.0); // yellow glVertex2f(0.0, 0.0)glVertex2f(0.0, 3.0)glVertex2f(4.0, 3.0)glVertex2f(6.0, 1.5)glVertex2f(4.0, 0.0)
glEnd();
Vẽ các đối tượng không gian ( Drawing 3-D Objects )
GLUT có một loạt các bản vẽ thường trình được sử dụng để tạo ra mô hình ba chiều. Điều này có nghĩa không cần phải định nghĩa lại các mã cần thiết để vẽ các mô hình này trong mỗi chương trình. Những các sử dụng làm cho tất cả các đồ họa trong chế độ ngay lập tức. Mỗi đối tượng đền có wire hoặc solid, và chúng được cung cấp sẳn :
· glutWireSphere() hoặc glutSolidSphere()
· glutWireCube() hoặc glutSolidCube()
· glutWireTorus() hoặc glutSolidTorus()
· glutWireIcosahedron() hoặc glutSolidIconsahedron()
· glutWireOctahedron() hoặc glutSolidOctahedron()
· glutWireTetrahedron() hoặc glutSolidTetrahedron()
· glutWireDodecahedron() hoặc glutSolidDodecahedron()
· glutWireCone() hoặc glutSolidCone()
· glutWireTeapot() hoặc glutSolidTeapot()
Các phép biến đổi ( Transformations )
Việc chuyển đổi mô hình được sử dụng để định vị và định hướng mô hình. Ví dụ, bạn có thể xoay, dịch thuật, hoặc quy mô các mô hình - hoặc kết hợp của các hoạt động này. Để làm cho một đối tượng xuất hiện tiếp tục đi từ người xem, hai tùy chọn có sẵn - những người xem có thể di chuyển gần hơn với các đối tượng hoặc đối tượng có thể được di chuyển ra xa cho người xem. Chuyển người xem sẽ được thảo luận sau khi chúng ta nói về xem các phép biến đổi. Đối với ngay bây giờ, chúng tôi sẽ giữ mặc định "máy ảnh" vị trí tại gốc, chỉ tay về phía trục z tiêu cực, mà đi vào màn hình vuông góc với mặt phẳng xem.
Khi chuyển đổi được thực hiện, một loạt các phép nhân ma trận thực sự thực hiện để ảnh hưởng đến vị trí, định hướng, và nhân rộng các mô hình. Tuy nhiên, các phép nhân ma trận diễn ra theo thứ tự ngược lại với cách chúng xuất hiện trong các mã. Trình tự chuyển đổi là rất quan trọng. Nếu bạn thực hiện chuyển đổi A và sau đó thực hiện B chuyển đổi, bạn hầu như luôn luôn có được một cái gì đó khác hơn nếu bạn làm chúng theo thứ tự ngược lại.
Scaling: lệnh glScale () nhân ma trận hiện tại của một ma trận trải dài, co lại, hoặc phản ánh một đối tượng dọc theo các trục. Mỗi x-, y, và z-phối hợp của tất cả các điểm trong đối tượng là nhân với tham số tương ứng với x, y, hoặc z. Các * glScale () là chỉ có một phần sự chuyển đổi mô hình ba thay đổi kích thước rõ ràng của một đối tượng: nhân rộng với giá trị lớn hơn 1,0 trải dài một đối tượng, và giá trị sử dụng ít hơn 1,0 co lại nó. Scaling với một giá trị -1,0 phản ánh một đối tượng trên một trục.
Translation :lệnh dịch glTranslate () nhân ma trận hiện tại của một ma trận chuyển động (dịch) một đối tượng do cho x-, y, và z-giá trị.
Rotation: lệnh quay glRotate () nhân hiện tại ma trận mà quay một đối tượng trong một hướng ngược chiều kim đồng về ray từ nguồn gốc thông qua các điểm (x, y, z). Các thông số góc xác định góc quay ở độ. Một đối tượng nằm xa hơn từ các trục quay được nhiều hơn đáng kể quay (có một quỹ đạo lớn hơn) so với một đối tượng rút ra gần các trục.
Danh sách hiển thị ( Display Lists )
Một danh sách hiển thị là một nhóm các lệnh OpenGL đã được lưu trữ để thực hiện sau đó. Khi một danh sách hiển thị được gọi, các lệnh trong nó được thực hiện theo thứ tự mà ở đó đã được khởi tạo. Hầu hết các lệnh OpenGL có thể là lưu trữ trong một danh sách hiển thị hoặc phát hành ở chế độ ngay lập tức, mà nguyên nhân họ sẽ được thực hiện ngay lập tức. Một danh sách hiển thị phải được bracked với glNewList () và glEndList () lệnh. Đối số cho glNewList () là tên duy nhất mà xác định danh sách.
Một danh sách hiển thị chỉ chứa các lệnh OpenGL. Các giá trị trong danh sách hiển thị không thể thay đổi và nó là không thể, hoặc thêm hoặc loại bỏ các lệnh từ danh sách một khi nó đã được lưu trữ. Bạn có thể xóa toàn bộ danh sách hiển thị, tạo một hình mới, nhưng bạn không thể chỉnh sửa nó.
Lệnh glNewList () xác định sự bắt đầu của một danh sách hiển thị. Các tham số đầu tiên là một số nguyên khác không tích cực xác định duy nhất danh sách hiển thị. Tham số thứ hai chỉ rõ liệu các lệnh OpenGL phải được thực hiện ngay lập tức cũng như được đặt trong danh sách hiển thị (GL_COMPILE_AND_EXECUTE) hoặc chỉ cần thêm vào danh sách hiển thị mà không thực thi chúng (GL_COMPILE). Lệnh glEndList () , rõ ràng, xác định kết thúc của một danh sách hiển thị.
Sau khi đã tạo ra một danh sách hiển thị, có thể thực hiện nó bằng cách gọi glCallList () . Với glCallList () , có thể thực hiện cùng một danh sách hiển thị nhiều lần, gọi một danh sách hiển thị từ một thói quen, hoặc kết hợp để thực hiện cuộc gọi hiển thị danh sách với các cuộc gọi thực hiện ngay lập tức chế độ đồ họa. Mọi thay đổi trong màu sắc hiện tại và hiện tại ma trận thực hiện trong việc thực hiện các danh sách hiển thị vẫn có hiệu lực sau khi đã được gọi. Do đó, thao tác các ma trận stack có thể phải thay đổi trạng thái của các biến trước khi thực hiện một danh sách hiển thị và sau đó khôi phục lại các giá trị này sau khi danh sách đã được thực hiện.
Ví dụ :
glNewList(1,GL_COMPILE);glColor3f(1.0, 0.0, 0.0); // redglBegin(GL_TRIANGLES);
glVertex2f(0.0, 0.0);glVertex2f(1.0, 0.0);glVertex2f(0.0, 1.0);
glEnd();glTranslate(1.5, 0.0, 0.0); // di chuyển đối tượngglEndList();
glNewList(2,GL_COMPILE);glColor3f(0.0, 1.0, 0.0); // blueglBegin(GL_QUAD);
glVertex2f(0.0, 0.0);glVertex2f(1.0, 0.0);glVertex2f(1.0, 1.0);glVertex2f(0.0, 1.0);
glEnd();glTranslate(-1.5, 0.0, 0.0); // di chuyển đối tượngglEndList();
Khung hiển thị ( Viewing )
Màu sắc ( Color )
Vẽ trên một màn hình máy tính khác với bản vẽ giấy ở trong đó giấy bắt đầu ra màu trắng, và tất cả các bạn phải làm là vẽ các bức tranh. Trên máy tính, bộ nhớ giữ hình ảnh thường chứa đầy những hình ảnh cuối cùng bạn đã vẽ, do đó, bạn thường cần phải rõ ràng nó với một số màu nền trước khi bạn bắt đầu để vẽ cảnh mới. Để thay đổi màu nền, chúng tôi gọi glClearColor () và chỉ định màu sắc, đã chọn cho nền. Màu mặc định là (0,0,0,0) mà là màu đen. Một cuộc gọi tiếp theo để glClear () sẽ rõ ràng các vùng đệm được quy định để hiển thị lên. Để xoá bộ đệm màu sắc sử dụng GL_COLOR_BUFFER_BIT đối số.
Để thiết lập một màu sắc, sử dụng lệnh glColor3f () . Nó có ba tham số kiểu thực mà là từ 0.0 đến 1.0. Các tham số được, để, các thành phần màu đỏ, xanh lá cây, và màu xanh dương. Bạn có thể nghĩ trong số này là chỉ định một "hỗn hợp" của màu sắc, nơi 0,0 có nghĩa là không sử dụng bất kỳ màu sắc này và 1,0 có nghĩa là sử dụng tất cả các thành phần đó. Ví dụ, glColor3f (1.0, 0.0, 0,0) làm cho màu đỏ sáng nhất mà hệ thống có thể rút ra, không có thành phần màu xanh lá cây hoặc màu xanh.
Tất cả số không làm cho màu đen (một sự vắng mặt của ánh sáng màu) và những bài làm cho trắng (một sự hiện diện của tất cả các ánh sáng màu). Tám màu commom và các lệnh của họ là:
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óng ( Shading )
Cho đến nay, chúng tôi đã áp dụng chỉ là một màu duy nhất cho mỗi đa giác mà chúng tôi đã rút ra (bằng phẳng bóng). Tuy nhiên, có thể chỉ định một màu duy nhất tại mỗi đỉnh. OpenGL suốt sẽ nội suy các màu sắc giữa các đỉnh. Điều này được biết đến như Gouraud Shading (hoặc trơn bóng). OpenGL sẽ nội suy tuyến tính các giá trị RGB cho các giá trị điểm ảnh dọc theo các cạnh giữa các đỉnh gây ra một sự thay đổi dần dần của màu sắc.
Ví dụ
glBegin(GL_QUADS); // draw 2 shaded polygons
glColor3f(1.0, 0.0, 0.0); // color interpolationglVertex2f(-0.8, -0.8); // the four vertices areglColor3f(0.5, 1.0, 0.0); // red, green, cyan, andglVertex2f(0.5, 1.0, 0.0); // blueglColor3f(0.0, 1.0, 0.5); glVertex2f(-0.1, 0.8);glColor3f(0.0, 0.0, 1.0);glVertex2f(-0.8, 0.8);
glColor3f(1.0, 1.0, 1.0); // intensity interpolationglVertex2f(0.1, -0.8); // the four vertices areglColor3f(0.7, 0.7, 0.7); // 1, 0.7, 0.5, and 0.1glVertex2f(0.8, -0.8);glColor3f(0.5, 0.5, 0.5); glVertex2f(0.8, 0.8);glColor3f(0.1, 0.1, 0.1);glVertex2f(0.1, 0.8);
glEnd();
Khung hình biến đổi ( Viewing Transformation )
Hãy nhớ rằng các thay đổi quan điểm của một đối tượng chúng ta có thể di chuyển hoặc di chuyển đối tượng người xem. Chúng tôi sẽ làm một loạt các biến đổi về "máy ảnh" của người xem tương tự như sự chuyển đổi thực hiện trên một đối tượng. Để bắt đầu, chúng tôi sẽ khởi tạo các ma trận xem bằng cách tải nó với bản sắc ma trận, sử dụng lệnh glLoadIdentity () , và tiếp tục kết hợp nó với những người mới theo nơi mà chúng tôi muốn đặt "máy ảnh”. Các gluLookAt lệnh được sử dụng để chỉ ra nơi người xem được đặt, mà nó là nhằm mục đích, và có cách là lên.
Ví dụ, gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0,0) ; nơi máy ảnh (hoặc mắt vị trí) tại điểm (0,0,5), nhằm mục đích để hướng đến nguồn gốc (0 , 0,0) và xác định véc tơ-up là (0,1,0).
Tại thời điểm này, chúng ta có lẽ nên đề cập đến các khái niệm về loại bỏ mặt ẩn. Đây là quá trình làm cho các đối tượng có trong hàng đầu "ẩn" những người phía sau họ. Hãy nhớ rằng chúng ta có một bộ đệm chiều sâu mà theo dõi những chiều sâu của mỗi điểm ảnh của các đối tượng trong một cảnh. Một giá trị sâu các đối tượng là sự khác biệt giữa các quan điểm và đối tượng . Nếu bạn muốn sử dụng bộ đệm chiều sâu, bạn chỉ cần có để kích hoạt nó bằng cách GL_DEPTH_TEST để glEnable () và nhớ để xoá bộ đệm độ sâu trước khi bạn vẽ lại một khung hình bằng cách sử dụng glClearDepth () . Khi bộ đệm được kích hoạt các điểm ảnh được hiển thị có màu sắc của đối tượng với giá trị z nhỏ nhất (chiều sâu), làm cho đối tượng xuất hiện gần hơn so với các đối tượng khác (s).
Phép chiếu ( Projection )
Xác định việc chuyển đổi chiếu cũng giống như chọn lựa một ống kính cho máy ảnh. Bạn có thể nghĩ đến chuyển đổi này như xác định các lĩnh vực xem và vì thế mà các đối tượng được bên trong nó và, đến một mức độ nào, làm thế nào họ nên xem xét. Có hai loại cơ bản của dự cung cấp cho bạn bằng cách OpenGL, chữ viết và phối cảnh.
Chữ viết ( Orthographic ) :các bản đồ chiếu trực giao các đối tượng trực tiếp lên màn hình mà không ảnh hưởng đến kích thước tương đối của họ. Chiếu này được sử dụng chủ yếu trong các ứng dụng thiết kế kiến trúc và máy tính hỗ trợ, trong đó các phép đo thực tế của các đối tượng quan trọng hơn họ có thể trông như thế nào. Lệnh glFrustum () được sử dụng để thiết lập việc chuyển đổi chiếu. Lệnh glMatrixMode () được sử dụng, với các GL_PROJECTION đối số được sử dụng để thiết lập các ma trận khi mà sự chuyển đổi này chiếu (và sau đó biến đổi) được thực hiện. Lưu ý rằng chúng tôi sử dụng glLoadIdentity () lệnh để khởi tạo ma trận chiếu hiện tại để chỉ việc chuyển đổi dự định (s) có hiệu lực. Cuối cùng, chúng tôi Calle lệnh glOrtho () để tạo ra một khối lượng song song xem chữ viết. Khối lượng xem là một hộp với trái, phải, trên,, gần và xa cạnh đáy quy định tại các glOrtho () chỉ huy.
Khi đó là thời gian để thực hiện các phép biến đổi trên các mô hình mà chúng tôi đã tạo ra, chúng tôi sẽ sử dụng cùng một glMatrixMode () lệnh với GL_MODELVIEW như là đối số. Điều này cho thấy sự chuyển đổi thành công hiện nay ảnh hưởng đến modelview ma trận thay vì chiếu ma trận.
Phối cảnh ( Perspective ) Chúng tôi sẽ sử dụng chiếu quan điểm để có được một thực tế hoàn trả nhiều hơn một đối tượng. Các đối tượng (s) sẽ có các đặc trưng không thể nhầm lẫn rút gọn: các thêm một đối tượng được từ máy chụp, nhỏ hơn nó xuất hiện trong hình ảnh cuối cùng. Điều này là do khối lượng xem chiếu quan điểm là một hình cụt (một kim tự tháp có đầu đã bị cắt bởi một mặt phẳng song song với cơ sở của nó). Đối tượng được gần hơn với các đỉnh của kim tự tháp nhỏ hơn, trong khi đối tượng xuất hiện gần hơn với cơ sở xuất hiện lớn hơn. Các lệnh định nghĩa này frustrum là glFrustum () , trong đó có các giá trị cho trái, phải, trên,gần và dưới. Bạn có thể thực hiện phép quay hoặc dịch vào ma trận chiếu này để thay đổi định hướng của nó, bởi đây là khó khăn và cần phải tránh.
Cùng một bộ các câu lệnh đặt chiếu glMatrixMode (GL_PROJECTION) và glLoadIndentity () nên được sử dụng để thiết lập việc chuyển đổi chiếu, nhưng thay vì sử dụng glOrtho () lệnh glFrustum () lệnh được đưa ra.
Thao tác ngăn xếp ma trận ( Manipulating the Matrix Stacks )
Các matracies modelview và chiếu bạn đã được tạo ra, tải, và nhân đã được chỉ là thủ thuật có thể nhìn thấy của iceburgs tương ứng. Mỗi matracies thực sự là thành viên trên cùng của ngăn xếp modelview hoặc chiếu ma trận, tương ứng.
Giả sử bạn muốn vẽ cùng một đối tượng ở bốn địa điểm khác nhau. Để làm cho simpiler nhiều, chúng ta có thể sử dụng các mô tả cùng một đối tượng và tiếp dịch nó cho mỗi vị trí mong muốn.
Kể từ khi chuyển đổi được lưu trữ như matracies, một ma trận stack cung cấp một cơ chế lý tưởng để làm điều này sắp xếp sao chép tiếp, dịch thuật, và ném đi. Lệnh glPushMatrix () bản sao của ma trận trên đầu của ma trận stack mà lần cuối tham chiếu bởi glMatrixMode () chỉ huy. Nội dung ma trận, do đó, được nhân đôi ở hàng đầu và cả trong matracies thứ hai-to-the-top. Điều này trên ma trận sau đó có thể được dịch và rút ra, như mong muốn, và cuối cùng bị phá hủy bằng cách sử dụng (glPopMatrix) lệnh. Điều này làm bạn phải ông đã ở trước và sẵn sàng lặp lại quá trình cho các phiên bản tiếp theo của đối tượng.
Ánh sáng ( Light )
Hiệu ứng ánh sáng rất quan trọng trong OpenGL, vì nếu không có việc sử dụng đèn chiếu sáng, một đối tượng 3-D vẫn sẽ xem xét 2-chiều. OpenGL cung cấp hai loại nguồn sáng: hướng và vị trí. Một nguồn tin hướng ánh sáng được coi là một khoảng cách vô hạn ra khỏi các đối tượng trong cảnh. Như vậy, tia nắng của ánh sáng được xem là song song do thời gian mà họ đạt được đối tượng. Một vị trí ánh sáng, ngược lại, là gần hoặc trong các cảnh và sự chỉ đạo của các tia của nó được đưa vào tài khoản trong ánh sáng tính toán.
Lệnh glLightfv () được sử dụng để xác định vị trí của ánh sáng, bất kể đó là hướng hoặc vị trí. Nó cũng được dùng để xác định liệu các nguồn sáng có màu sắc xung quanh, màu khuếch tán, màu sắc, gương, hoặc màu lượng phát ra.
Ambient: Ánh sáng đã được phân tán quá nhiều bởi môi trường mà hướng của nó là khó để xác định.
Diffuse: Ánh sáng đến từ một hướng, vì vậy nó sáng hơn nếu nói thẳng xuống trên một bề mặt hơn là nó chỉ nhìn thoáng qua khỏi bề mặt.
Specular: Ánh sáng đến từ một hướng cụ thể, và nó có xu hướng thoát khỏi bề mặt trong một hướng ưu tiên.
Emissive: Ánh sáng có vẻ là orginating từ một đối tượng.
Có thể tạo lên đến tám nguồn ánh sáng. Tất cả đã được nội bộ được xác định là GL_LIGHT0, GL_LIGHT1. Để tạo ra một nguồn ánh sáng, bạn phải chọn ánh sáng bạn muốn sử dụng, theo tên, một vị trí cho các nguồn sáng và các thông số nhất định. Các thông số có sẵn là màu sắc và chất lượng.
Để xác định vị trí, bạn phải cung cấp một vector trong bốn giá trị (x, y, z, w). Nếu giá trị cuối cùng, w, là số không, nguồn ánh sáng tương ứng là một hướng một, và (x, y, z) giá trị mô tả hướng đi của nó. Theo mặc định, vị trí cho GL_POSITION là (0,0,1,0), trong đó xác định một light hướng mà các điểm dọc theo trục z tiêu cực.
Các thành phần màu được chỉ định cho đèn có nghĩa là một cái gì đó khác nhau cho các đối tượng. Đối với ánh sáng, các con số tương ứng với một tỷ lệ phần trăm của cường độ đầy đủ cho mỗi màu. Nếu các giá trị R, G, và B cho màu sắc của ánh sáng là tất cả 1.0, ánh sáng là màu trắng sáng nhất có thể. Tuy nhiên, nếu các giá trị được tất cả 0,5, màu sắc vẫn còn màu trắng, nhưng chỉ một nửa cường độ, và do đó sẽ xuất hiện màu xám. Nếu R = 1, G = 1 và B = 0, ánh sáng có đầy đủ màu xanh đỏ và đầy đủ không có màu xanh, và do đó sẽ xuất hiện màu vàng. Các tham số ra đó là thông qua là một chuyển đổi on-off, nhiều hơn hoặc ít hơn. Giá trị của 1 biến ánh sáng, và giá trị 0 biến ra ánh sáng.
Khung quan sát biến đổi ( Viewport Transformation )
Sử dụng tương tự máy ảnh, khung nhìn chuyển đổi là quá trình quyết định kích thước của in ấn phát triển của chúng tôi. Do chúng tôi muốn có một bức ảnh có kích thước ví tiền hoặc đăng một? Theo mặc định, khung nhìn là để thiết lập các hình chữ nhật pixel toàn bộ cửa sổ được mở ra. Bạn có thể sử dụng glViewport () lệnh, tuy nhiên, để chọn một khu vực vẽ nhỏ hơn. Ví dụ, bạn có thể chia cửa sổ để tạo ra một tách cảnh cho các quan điểm khác nhau trong cùng một cửa sổ.. Lệnh này có các x và y phối hợp của các góc dưới bên trái của khung nhìn và chiều rộng và chiều cao của hình chữ nhật khung nhìn.
CHƯƠNG TRÌNH DEMO
Các kỹ thuật sử dụng cho chương trình
Chương trình Demo sử dụng các kỹ thuật vẽ cơ bản :
Vẽ đa giac
Vẽ đối tượng 3D
Sử dụng màu
Các phép dịch chuyển và quay
Ngoài ra còn sử dụng kỹ thuật tạo hình ảnh bề mặt cho đối tượng được vẽ ra (texture). Với kỹ thuật này thì thay những màu sắc đơn giản bằng các hình ảnh sinh động hơn, nó sẽ phủ lên bề mặt của khối hình học mà chúng ta cần vẽ.
Muốn sử dụng texture thì cần phải có 1 bưc ảnh nguồn, ở các định dạng ảnh đều sử dụng được, nhưng với định dạng ảnh là BMP ( là bitmap ) thì việc sử dụng sẽ dễ dàng hơn rất nhiều. Sử dụng các hàm cần thiết để đưa bức ảnh về thành một mãng như sau ( R1,G1,B1,R2,G2,B2….) các giá trị lần lượt tương ứng là red, green, blue ; đó là các giá trị của 1 màu sắc cho 1 pixel trên ảnh.
Nó khá đơn giản. Chúng tôi tải các hình ảnh, sau đó tải các texture của OpenGL, sau đó xóa các đối tượng hình ảnh, kể từ khi chúng tôi không cần nó nữa.
Bắt đầu sử dụng, bằng cách gọi glEnable (GL_TEXTURE_2D) để cho phép áp dụng kết cấu và glBindTexture (GL_TEXTURE_2D, _textureId) để nói với OpenGL mà chúng tôi muốn sử dụng kết cấu với id _textureId.
Chương trình sẽ khởi tạo OpenGL qua thư viện GLUT và tạo cửa sỗ, sét các chế độ và mở các trạng thái ( vẽ 3D, texture, các chế độ màu, các bộ đệm …..). Sau đó tải file ảnh *.bmp và chuyển nó về dưới dạng một mãng kiểu int để chưa các giá trị màu của các pixel, tiếp theo là chuyển mãng giá trị đó thành texture của OpenGL.
Hàm vẽ sẽ gọi hàm glBindTexture (GL_TEXTURE_2D, _textureId) ( trong đó GL_TEXTURE là texture dạng 2D và _textureId là texture chúng ta vừa tạo ra) để sử dụng texture và texture sẽ hiển thị lên bề mặt của các đối tượng mà OpenGL vẽ ra.
Mã nguồn
File “ITF.c”
#include
#include
#include
#include
#include
#include
#define ESCAPE 27 // ma ascii cua phim escape
int window; // so cua so GLUT
float xrot, yrot, zrot; // gia tri goc quay cua cac truc X,Y,Z
int texture[1]; // mang chua texture
/* Kieu du lieu Image - chieu rong, cao, du lieu */
struct Image {
unsigned long sizeX;
unsigned long sizeY;
char *data;
};
typedef struct Image Image;
// Load mot buc anh len
int ImageLoad(char *filename, Image *image) {
FILE *file;
unsigned long size; // size of the image in bytes.
unsigned long i; // standard counter.
unsigned short int planes;// number of planes in image (must be 1)
unsigned short int bpp; // number of bits per pixel (must be 24)
char temp; // temporary color storage for bgr-rgb conversion.
// mo file
if ((file = fopen(filename, "rb"))==NULL)
{
printf("File Not Found : %s\n",filename);
return 0;
}
// seek through the bmp header, up to the width/height:
fseek(file, 18, SEEK_CUR);
// doc chieu rong
if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
printf("Width of %s: %lu\n", filename, image->sizeX);
// doc chieu cao
if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
printf("Error reading height from %s.\n", filename);
return 0;
}
printf("Height of %s: %lu\n", filename, image->sizeY);
// calculate the size (assuming 24 bits or 3 bytes per pixel).
size = image->sizeX * image->sizeY * 3;
// read the planes
if ((fread(&planes, 2, 1, file)) != 1) {
printf("Error reading planes from %s.\n", filename);
return 0;
}
if (planes != 1) {
printf("Planes from %s is not 1: %u\n", filename, planes);
return 0;
}
// read the bpp
if ((i = fread(&bpp, 2, 1, file)) != 1) {
printf("Error reading bpp from %s.\n", filename);
return 0;
}
if (bpp != 24) {
printf("Bpp from %s is not 24: %u\n", filename, bpp);
return 0;
}
// seek past the rest of the bitmap header.
fseek(file, 24, SEEK_CUR);
// read the data.
image->data = (char *) malloc(size);
if (image->data == NULL) {
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i=0;i rgb)
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
// we're done.
return 1;
}
// Load Bitmaps And Convert To Textures
void LoadGLTextures() {
// Load Texture
Image *image1;
// allocate space for texture
image1 = (Image *) malloc(sizeof(Image));
if (image1 == NULL) {
printf("Error allocating space for image");
exit(0);
}
if (!ImageLoad("Data/ITF.bmp", image1)) {
exit(1);
}
// tao Texture
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);// 2d texture (x and y size)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // tuyen tinh neu kich co lon hon texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // tuyen tinh neu kich co nho hon texture
// 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
};
/* Khoi tao OpenGL */
void InitGL(int Width, int Height) // goi sau khi khoi tao cua so
{
LoadGLTextures(); // tai Texture(s)
glEnable(GL_TEXTURE_2D); // mo trang thai Texture Mapping
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // xoa backgroud ve mau den
glClearDepth(1.0); // mo trang thai Xoa bo dem chieu xau
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // mo trang thai Depth Testing
glShadeModel(GL_SMOOTH); // moi trang thai Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // khoi dong lai ma tran chieu
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
}
/* Ham tu dong tuy chinh khi cua so bi thay doi kich co */
void ReSizeGLScene(int Width, int Height)
{
if (Height==0) // Neu cua so qua nho
Height=1;
glViewport(0, 0, Width, Height);// dai lai Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* Ham ve. */
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // lam sach mang anh va bo dem chieu sau
glLoadIdentity(); // dat lai khung nhin
glTranslatef(0.0f,0.0f,-5.0f); // di chuyen 5 don vi
glRotatef(xrot,1.0f,0.0f,0.0f); // quay tren truc x
glRotatef(yrot,0.0f,1.0f,0.0f); // quay tren truc y
glRotatef(zrot,0.0f,0.0f,1.0f); // quay tren truc z
glBindTexture(GL_TEXTURE_2D, texture[0]);// chon texture de su dung
glBegin(GL_QUADS); // bat dau ve lap phuong
// mat truoc
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// mat sau
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// mat tren
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// mat day
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// ben phai
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// ben trai
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glEnd(); // ket thuc ve cac da giac
xrot+=1.0f; // thay doi tinh tuyen gia tri truc X
yrot+=1.0f; // thay doi tinh tuyen gia tri truc Y
zrot+=1.0f; // thay doi tinh tuyen gia tri truc Z
glutSwapBuffers(); // dung bo dem doi de ve len
}
/* ham su kien nhan phim */
void keyPressed(unsigned char key, int x, int y)
{
/* thoi gian delay */
usleep(100);
/* thoat chuong trinh neu nhan phim ESCAPE */
if (key == ESCAPE)
{
/* tat cua so GLUT */
glutDestroyWindow(window);
/* thoat chuong trinh */
exit(0);
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv); // khoi tao OpenGL voi thu vien GLUT
/* chon kieu mang hinh voi:
bo dem doi
RGBA color
ho tro anh sang
bo dem chieu xau */
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
/* khoi tao cua so voi kich thuoc truyen vao*/
glutInitWindowSize(640, 480);
/* set diem treo cua cua so */
glutInitWindowPosition(0, 0);
/*�� cua so */
window = glutCreateWindow("ITF - cube ");
/* thuc hien ve */
glutDisplayFunc(&DrawGLScene);
/* tuy chon full man hinh */
//glutFullScreen();
/* ve lai */
glutIdleFunc(&DrawGLScene);
/* tu dong tuy chinh neu thay doi kich co cua so */
glutReshapeFunc(&ReSizeGLScene);
/* Su kien nhan phim */
glutKeyboardFunc(&keyPressed);
/* khoi tao cac gia tri cho cua so */
InitGL(640, 480);
/* vong lap chinh */
glutMainLoop();
return 1;
}
Makefile
ITF:
gcc -o ITF ITF.c -lglut -lGLU -lGL
clean:
rm -f ITF.o
Kết quả chạy
Hình ảnh được dùng : file ITF.bmp
Kết quả chạy trên ubuntu 10.10
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
Những kết quả đạt được
OpenGl là thư viện mở, luôn được cộng động theo dõi, phát triển và cập nhật ngay khi có những cái mới hoặc những vấn đề nảy sinh.
Nắm được những kỹ thuật đồ họa cơ bản trong việc đồ họa máy tính và có thể nâng cao hơn để phát triễn nhiều ứng dụng dòi hỏi giao diện cũng như đồ họa cao cấp
Những vấn đề tồn tại
Chưa làm được các đồ họa hoạt hình và đồ họa 3D cấp cao, như :
Terrain
Drawing Text
Animation
Collision Detection
Putting It All Together
Hiệu ứng 3D
Alpha Blending
Particle Systems
Drawing Reflections
Fog
Tốc độ và hiển thị
Backface Culling
Display Lists
Normalizing Normals
Mipmapping
Materials
Hướng phát triển
Kết hợp nhiều thư viện khác của openGL
Lập trình trên các ngôn ngữ khác nhau: VB.VC++,C,java…..
3D
Hoạt hình
Đồ họa máy tính
Quản cáo
Film
Kiến trúc
….
TÀI LIỆU THAM KHẢO
[1] The Red Book,
[2] Video OpenGL tutorial,
[3] Game Development,
[4] OpenGL Programming Guide,
[5] OpenGL Tutorial,
[6] API OpenGL
Các file đính kèm theo tài liệu này:
- Lập trình đồ họa ứng dụng thư viện opengl trên linux.doc