Это от старого игрового движка на основе OpenGL, который я пытался написать около семи лет назад, написанного на C ++, настолько обнаженного, как я, пытаясь объяснить, как я справляюсь с операциями рендеринга 3D-мира и 2D-интерфейса в нем. В моем классе визуализации OpenGL (OGLRender) я использовал четыре основных метода:
- ready3D () для подготовки OpenGL для рендеринга трехмерной сцены мира.
- ready2D () для подготовки OpenGL для визуализации 2D GUI.
- render3D () для реального трехмерного рисования сцены мира.
render2D () для фактического чертежа 2D GUI.
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
}
Итак, что я делаю, так это сначала рисую свою трехмерную мировую сцену, а затем в последний раз рисую свой графический интерфейс таким образом, чтобы графический интерфейс всегда был на вершине мировой сцены. Метод ready3D () готовит трехмерную проекцию мира к рисованию мировой сцены, а метод ready2D () готовит орто-сцену 2D для рисования в графическом интерфейсе. m_Setup.width
и m_Setup.height
только размеры экрана просмотра порта.
Что особенного в методе ready2D (), так это то, что gluOrtho2D()
функция вызывается с аргументами, которые сообщают ей, когда мы рисуем примитивы GUI, мы рисуем их в координатах экрана, указанных для соответствия Windows, Mac и другим системам координат экрана рабочего стола. Например, верхний левый - (0,0) в формате (X, Y), а нижний правый - (ViewportWidth-1, ViewportHeight-1)
. И glTranslatef()
используется для коррекции точного позиционирования на пиксель. Таким образом, когда мы рисуем линию от (0,0) до (0,9), тогда линия на самом деле будет рисоваться из верхнего левого и прямого вниз десяти пикселей общей длины и одного пикселя шириной.
В целом вам, скорее всего, просто интересно, что делает метод ready2D () . Я предоставил примеры исходного кода других методов, чтобы дать вам общее представление о том, как большинство игр выполняют сцену в 3D мире и порядок отрисовки графического интерфейса.
([0...1], [0...1], 0, 1)
без проекции, вида или матрицы мира, они всегда окажутся в пространстве экрана.