Це зі старого ігрового двигуна на основі OpenGL, про який я намагався писати близько семи років тому, написаного на C ++, так що голий зі мною, коли я намагаюся пояснити, як я обробляв операції 3D-рендерінгу та 2D GUI-рендерінгу в ньому. Я використовував чотири основні методи в моєму класі OpenGL-рендерів (OGLRender), з яких:
- ready3D () для підготовки OpenGL до візуалізації світової сцени 3D.
- ready2D () для підготовки OpenGL до візуалізації 2D GUI.
- render3D () для фактичного малювання 3D сцени світу.
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
}
Отже, те, що я роблю, це те, що я малюю спочатку свою світову сцену 3D, а потім я малюю свій графічний інтерфейс останнім, таким чином, щоб графічний інтерфейс завжди був на вершині світової сцени. Метод ready3D () отримує 3D-проекцію світу готовий до малювання на світовій сцені, а метод 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)
без проекції, перегляду чи світової матриці, вони завжди опиняться в просторі екрану.