这来自大约七年前我试图用C ++编写的基于OpenGL的旧游戏引擎,当我试图解释如何处理其中的3D世界和2D GUI渲染操作时,对我几乎一无所知。我在OpenGL渲染器类(OGLRender)中使用了四种主要方法,它们是:
- ready3D(),用于准备OpenGL以渲染3D世界场景。
- ready2D(),用于准备OpenGL以渲染2D GUI。
- 实际3D世界场景绘制的render3D()。
实际2D GUI绘图的render2D()。
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 ...
}
然后在主线程循环中,我基本上只会按以下顺序调用方法:
while(m_drawFrame)
{
gm_Render->render3D(); // draw 3D scene
gm_Render->render2D(); // draw GUI
SDL_GL_SwapBuffers(); // make drawn frame visible
}
因此,我要做的是先绘制3D世界场景,然后最后绘制GUI,以使GUI始终位于世界场景的顶部。ready3D()方法获取准备好用于世界场景绘制的3D世界投影,ready2D()方法获取准备好用于GUI绘制的2D正交场景。m_Setup.width
而m_Setup.height
仅仅是视口的屏幕尺寸。
ready2D()方法的特殊之处gluOrtho2D()
在于调用了带有参数的函数,这些参数告诉我们绘制GUI基元时,将它们绘制在指定的屏幕坐标中以匹配Windows,Mac和其他桌面屏幕坐标系。例如,左上角是(X,Y)格式的(0,0)而右下角是(ViewportWidth-1, ViewportHeight-1)
。并glTranslatef()
用于校正每个像素的精确定位。因此,当我们从(0,0)到(0,9)绘制一条线时,该线实际上将从左上角开始绘制,并向下垂直向下绘制总长度为10个像素和一个像素为1个像素的宽度。
总的来说,您最有可能只是对ready2D()方法的作用感兴趣。我提供了其他方法的源代码示例,以使您大致了解大多数游戏如何执行3D世界场景和GUI绘制顺序。
([0...1], [0...1], 0, 1)
带投影,视图或世界矩阵的坐标,它们将始终落在屏幕空间中。