Đây là từ một công cụ trò chơi dựa trên OpenGL cũ mà tôi đã cố gắng viết khoảng bảy năm trước được viết bằng C ++ khi tôi cố gắng giải thích cách tôi xử lý các hoạt động kết xuất đồ họa 3D và 2D trong thế giới 3D. Tôi đã sử dụng bốn phương thức chính trong lớp trình kết xuất OpenGL (OGLRender) của mình, đó là:
- ready3D () để chuẩn bị OpenGL để hiển thị cảnh thế giới 3D.
- ready2D () để chuẩn bị OpenGL để hiển thị GUI 2D.
- render3D () để vẽ cảnh thế giới 3D thực tế.
render2D () cho bản vẽ GUI 2D thực tế.
void OGLRender::ready3D()
{
glViewport(0, 0, m_Setup.width, m_Setup.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (float) m_Setup.width / m_Setup.height, 0.1, 5000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
}
void OGLRender::ready2D()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f, m_Setup.width, m_Setup.height, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375, 0.375, 0.0);
glDisable(GL_DEPTH_TEST);
}
void OGLRender::render3D()
{
this->ready3D();
// ... draw 3D world scene here ...
}
void OGLRender::render2D()
{
this->ready2D();
// ... draw GUI here ...
}
Và sau đó trong vòng lặp luồng chính, về cơ bản tôi sẽ chỉ gọi các phương thức theo thứ tự sau:
while(m_drawFrame)
{
gm_Render->render3D(); // draw 3D scene
gm_Render->render2D(); // draw GUI
SDL_GL_SwapBuffers(); // make drawn frame visible
}
Vì vậy, những gì tôi đang làm là tôi vẽ cảnh thế giới 3D của mình trước và sau đó tôi vẽ GUI của mình theo cách mà GUI luôn ở trên đỉnh của thế giới. Phương thức ready3D () giúp trình chiếu thế giới 3D sẵn sàng để vẽ cảnh thế giới và phương thức ready2D () sẵn sàng cho cảnh trực giao 2D sẵn sàng để vẽ GUI. m_Setup.width
vàm_Setup.height
chỉ là kích thước màn hình cổng xem.
Điều đặc biệt ở phương thức ready2D () là gluOrtho2D()
hàm được gọi với các đối số cho biết khi chúng ta vẽ các nguyên hàm GUI, chúng ta vẽ chúng trong tọa độ màn hình được chỉ định để khớp với Windows, Mac và các hệ tọa độ màn hình máy tính để bàn khác. Chẳng hạn như trên cùng bên trái là (0,0) ở định dạng (X, Y) trong khi dưới cùng bên phải là (ViewportWidth-1, ViewportHeight-1)
. VàglTranslatef()
được sử dụng để sửa cho định vị chính xác trên mỗi pixel. Vì vậy, khi chúng ta vẽ một dòng từ (0,0) đến (0,9) thì dòng đó sẽ thực sự vẽ từ tổng chiều dài bên trái và thẳng xuống mười pixel và chiều rộng một pixel.
Nhìn chung, rất có thể bạn chỉ quan tâm đến phương thức ready2D () đang làm gì. Tôi đã cung cấp các ví dụ mã nguồn của các phương thức khác để cung cấp cho bạn một ý tưởng về cách nói chung hầu hết các trò chơi thực hiện cảnh vẽ thế giới 3D và thứ tự vẽ GUI.
([0...1], [0...1], 0, 1)
KHÔNG chiếu, ma trận hoặc ma trận thế giới, chúng sẽ luôn xuất hiện trong không gian màn hình.