Cơ bản về OpenGL

OpenGL là gì ?

Được phát triển đầu tiên bởi Silicon Graphic, Inc., là một giao diện phần phần mềm hướng thủ tục theo chuẩn công nghiệp hộ trợ đồ họa 3 chiều. Cung cấp khoảng 120 tác vụ để vẽ các primitive trong nhiều mode khác nhau. Với OpenGL, bạn có thể tạo ra ảnh 3 chiều cả tĩnh và động với chất lượng cao.

Là một giao diện phần mềm độc lập với phần cứng (hardware – independent software interface) hộ trợ cho lập trình đồ họa. Để làm được điều này, OpenGL không thực hiện các tác vụ thuộc về hệ điều hành cũng như không nhận dữ liệu nhập của người dùng (người dùng giao tiếp với OpenGL thông qua OpenGL API). Nó là lớp trung gian giữa người dùng và phần cứng. Nghĩa là nó giao tiếp trực tiếp với driver của thiết bị đồ họa.

GLUT (pronounced like the glut in gluttony) is the OpenGL Utility Toolkit, a window system independent toolkit for writing OpenGL programs. It implements a simple windowing application programming interface (API) for OpenGL. GLUT makes it considerably easier to learn about and explore OpenGL programming. GLUT provides a portable API so you can write a single OpenGL program that works across all PC and workstation OS platforms.

Download phiên bản mới nhất của glut ở đây.
Giải nén và đặt các file vào đúng vị trí:

– glut32.dll vào C:\WINDOWS\system32\
– glut.lib vào C:\Program Files\Microsoft Visual Studio 9.0 \ VC \ lib
– glut.h vào C:\Program Files\Microsoft Visual Studio 9.0 \ VC \ Include \ GL \

Tất nhiên GLUT là thư viện phụ thuộc OpenGL cho nên cần có gl.h, glu.h,glu32.dll, opengl32.dll, opengl32.lib, glu32.lib nữa. Tải tại đây. Giải nén và đặt vào các vị trí giống như trên.

Add dòng sau đây vào trước hàm main()
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

Xong, bây giờ tui sẽ hướng dẫn bạn vẽ một hình tam giác với GLUT

#include <GL/glut.h>
#pragma comment( linker, “/subsystem:\”windows\” /entry:\”mainCRTStartup\”” )
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glFlush();
}void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow(“Ve hinh tam giac!!!!”);
glutDisplayFunc(renderScene);
glutMainLoop();
}

Một số quy ước (convention) về tên hàm OpenGL:

Tên hàm thư viện OpenGL có hình thức như sau:

Gl{tên hàm}[{số tham số}{loại tham số}]

Ví dụ: glClearColor(), glColor3f()

Phần tên hàm được viết hoa cho những chữ cái đứng đầu 1 từ trong tên hàm và ít nhiều nói lean được chức năng của hàm. Phần số tham số và loại tham số xuất hiện tùy theo hàm. Số tham số cho ta biết số lượng tham số sẽ đưa vào khi gọi hàm.

Giải thích các hàm:

void glutInit(int *argc, char **argv); –> //Khởi động GLUT , argc, argv là 2 đối số dòng lệnh của hàm main

void glutInitWindowPosition(int x, int y); —> //Khởi tạo vị trí bắt đầu cửa sổ, x là left of the screen, y là top of the screen, nói chung đây là điểm bên trái, phía trên của cửa sổ, từ đây ta kéo xuống phía dưới, bên phải là đc 1 cửa sổ . Đơn vị của x, y là pixel.

void glutInitWindowSize(int width, int height); –-> //Khởi tạo kích thước cửa sổ. với chiều dài và chiều rộng, cộng thêm 1 điểm bắt đầu mới nói ở trên nữa, bạn đã tưởng tượng ra đc 1 cái cửa sổ chưa

void glutInitDisplayMode(unsigned int mode) –> //định nghĩa mode hiển thị, chỉ ra màu của mode và số + kiểu của buffer
+ GLUT_RGBA or GLUT_RGB : cửa sổ màu RGBA, đây là mode mặc định
+ GLUT_SINGLE : cửa sổ buffer đơn
+ GLUT_DOUBLE : cửa sổ buffer đôi
+ GLUT_DEPTH : cửa sổ buffer sâu

int glutCreateWindow(char *title); –> tạo cửa sổ có tiêu đề title

Bây giờ ta cần tạo một hàm để trình diễn. Hàm này là do người dùng tạo ra.

void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT); //xóa màn hình
glBegin(GL_TRIANGLES); //vẽ tam giác
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd(); //kết thúc
glFlush();
}

void glutDisplayFunc(void (*func)(void)); –> Hàm này báo cho GLUT biết phải trình diễn theo hàm nào , đối số của nó là một con trỏ hàm trả về kiểu void

void glutMainLoop(void) –> cuối cùng ta phải lặp lại hàm main liên tục để “trình diễn hình tam giác”. Giống như người ta làm phim hoạt hình đó, các frame nối tiếp nhau trên một màn ảnh.

Hic, mấy cái này dịch từ english sang, ko hiểu lắm, cứ tạm biết vậy đã.

*********************************************************************************************

THAM KHẢO THÊM

*********************************************************************************************
Các lệnh glClearColor(), glClear(),glFush() là những lệnh cơ bản của Opengl.glClearColor() có nhiệm vụ chọn màu để xoá window, bạn dễ dàng nhận ra là nó có 4 tham số, 4 tham số đó là RGBA( red green blue alpha).Không giống với hàm RGB() trong Win32 API , 4 tham số này có giá trị trong khoảng 0.0f đến 1.0f(kiểu float).
Các giá trị R,G,B trong OpenGL thì >=0.0 (không có) và <=1.0 (độ sáng cực đại). Ba tham số đầu là màu đỏ xanh lá cây và xanh da trời, còn tham số thứ 4 là độ sáng tối của window.Bây giờ hãy thay đổi các giá trị của màu xem thử!Hàm glClear() mới thực sự xoá window, nó có những hằng số xác định.Có trường hợp có những hàm chưa được chạy đến khi kết thúc chương trình, để tránh trường hợp này hàm glFlush()được gọi, nó sẽ thực hiện tất cả các hàm chưa được chạy và kết thúc chương trình.

Dùng glClear*() để định màu xóa cho các buffer.
Sau đó glClear(GLbitfied mask) để xóa buffer tương ứng với mask
Tham số param của hàm glClear() có thể nhận từ 1 đến 4 giá trị sau:

Buffer Name
Color buffer GL_COLOR_BUFFER_BIT
Depth buffer GL_DEPTH_BUFFER_BIT
Accumulation buffer GL_ACCUM_BUFFER_BIT
Stencil buffer GL_STENCIL_BUFFER_BIT

Mỗi giá trị trên chỉ đến một buffer tương ứng như trên bảng. Các giá trị có thể kết hợp thông qua toán tử ‘|’ (bitwise-OR). Khi muốn xóa nhiều bộ đệm đồng thời, nên dùng bitwise-OR hơn là gọi tách riêng từng lệnh glClear() một tham số vì hàm glClear() có thể thực sự xóa đồng thời nhiều buffer (chức năng này tùy thuộc phần cứng).
Để định màu xóa cho mỗi buffer, ta dùng các hàm glClear*() như sau: glClearColor(), glClearDepth(), glClearAccum(), glClearStencil().

Buộc việc vẽ hoàn tất

Đối với các ứng dụng đồ họa chạy qua mạng, trong đó client chạy phần chương trình chính và hiển thị kết quả đến server, thường thì client sẽ gom nhiều lệnh vẽ vào một packet, sau đó mới gửi đến server. Nhưng làm sao để client biết được khi nào thì ảnh trên server đã vẽ xong và gửi tiếp packet khác? Do đó nó sẽ đợi đến khi nào packet đầy mới gửi tiếp. Nhưng packet có thể không bao giờ đầy vì việc vẽ bên client đã hoàn tất và như vậy server không thấy được trọn vein kết quả vẽ OpenGL cung cấp hàm glFlush() để chúng ta giải quyết vấn đề này. Lệnh này buộc client gửi packet ngay cả khi packet chưa đầy. Lệnh này không đợi cho việc vẽ hoàn tất, nó buộc việc vẽ phải bắt đầu thực hiện và do đó đảm bảo tất cả các lệnh trước đó thực hiện trong một thời gian giới hạn. Nếu máy chạy local thì ta không cần dùng lệnh này.

Một lệnh khác cũng gần giống là lệnh glFinish(), nó thực hiện chức năng giống glFlush() nhưng nó đợi phản hồi từ phần cứng đang vẽ hoặc mạng để khẳng định việc vẽ đã hoàn tất. Lệnh này hữu dụng khi ta muốn đồng bộ hóa các phần vẽ. Ví dụ ta muốn một phần nào đó vẽ hoàn tất xong thì mới thực hiện các phần khác. Nhưng lạm dụng lệnh này sẽ làm chậm chương trình vì nó phải đợi phản hồi.

Cấu trúc vertex
Trong OpenGL, mọi đối tượng hình học đều được mô tả cơ bản từ các vertex. Cấu trúc này bao gồm bộ 4 số thực chỉ tọa độ trong không gian. Để chỉ định một vertex, ta dùng:

glVertex{234}{sifd}[v](TYPEcoords);

Vì sao có số 4? Vì OpenGL dùng tọa độ tương đối theo một số thứ tư. Khi ta ghi tọa độ dạng (x,y,z,w) thì sự thực là tọa độ 3 chiều (x/w,y/w,z/w). Mặc định w=1.0, z=0.

Ví dụ:

glVertex2s(2, 3);                               // khai báo vertex có tọa độ (2,3,0)
glVertex3d(0.0, 0.0, 3.1415926535898);  // toạ độ như tham số
glVertex4f(2.3, 1.0, -2.2, 2.0);                // tọa độ (1.15,0.5,1.1)
GLdouble dvect[3] = {5.0, 9.0, 1992.0}; //khai báo 1 vecteor
glVertex3dv(dvect);                             //khai báo vertex thông qua vector nêu trên

Trong một số máy tính, việc truyền tham số bằng vector sẽ hiệu quả hơn truyền bộ 3 số riêng lẻ (tùy thuộc phần cứng).

Để tạo một đối tượng hình học từ các vertex, ta bao khối khai báo vertex bằng hai hàm glBegin(param) và glEnd(). Tham số param đưa vào cho hàm glBegin() sẽ giúp OpenGL quyết định vẽ gì từ các vertex khai báo bên trong.

Ví dụ:

glBegin(GL_POLYGON);
glVertex2f(0.0, 0.0);
glVertex2f(0.0, 1.0);
glVertex2f(0.5, 1.0);
glVertex2f(1.0, 0.5);
glVertex2f(0.5, 0.0);
glEnd();

Các tham số có thể đưa vào hàm glBegin(Glenum mode)

Giá trị Ý nghĩa
GL_POINTS Từng vertex được vẽ riêng
GL_LINES Mỗi cặp vertex được coi như 2 đầu một đoạn thẳng
GL_POLYGON Các vertex được xem như biên của một đa giác lồi
GL_TRIANGLES Bộ 3 vertex được xem các đỉnh một tam giác (không lặp)
GL_QUADS Bộ 4 vertex được xem như 4 đỉnh 1 đa giác (không lặp).
GL_LINE_STRIP Một loạt các đoạn được nối với nhau (có lặp)
GL_LINE_LOOP Như trên nhưng vertex đầu và cuối được nối với nhau (lặp vòng)
GL_TRIANGLE_STRIP Bộ 3 vertex xem như các đỉnh tam giác (có lặp)
GL_TRIANGLE_FAN Vertex 0 là đỉnh chung kết hợp cặp đỉnh bất kỳ tạo tam giác

Về vdhungbg
Tin tuc cap nhat - moi luc - moi noi

7 Responses to Cơ bản về OpenGL

  1. buon167 nói:

    Bạn có thể hướng dẫn thêm cho mình về cách “Giải nén và đặt vào các vị trí giống như trên” rõ ra được không?vì mình làm sao không được.giúp mình nhé!thanks bạn

  2. “The way I figure it, that thorn was a pretty fair deal,” he said.
    You will understand your ex better, be able to avoid
    arguments and conflict and when disagreements do arise, you will know
    how to handle them so things don. It’s a lot easier to get your lover back when you have a plan.

  3. Hey there! Do you use Twitter? I’d like to follow you if that would be okay.
    I’m absolutely enjoying your blog and look forward to new posts.

  4. An interesting discussion is definitely worth comment. There’s no
    doubt that that you should publish more about this issue, it
    might not be a taboo matter but generally people do not discuss these subjects.
    To the next! Best wishes!!

  5. biscuit home nói:

    Good information. Lucky me I ran across your website by accident (stumbleupon).
    I have bookmarked it for later!

  6. .VCmCUfl_t1w nói:

    It’s not my first time to go to see this web site, i am visiting this site dailly and obtain fastidious
    facts from here all the time.

  7. You have made some decent points there. I looked on the internet to find out more
    about the issue and found most individuals will go along
    with your views on this web site.

Gửi phản hồi

Please log in using one of these methods to post your comment:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

%d bloggers like this: