Dies ist von einer alten OpenGL-basierten Spiel-Engine, die ich vor ungefähr sieben Jahren in C ++ zu schreiben versucht habe. Ich habe versucht zu erklären, wie ich mit 3D-Welt- und 2D-GUI-Rendering-Operationen umgegangen bin. Ich habe vier primäre Methoden in meiner OpenGL-Renderer-Klasse (OGLRender) verwendet:
- ready3D () zum Vorbereiten von OpenGL zum Rendern der 3D- Weltszene .
- ready2D () zum Vorbereiten von OpenGL zum Rendern der 2D-GUI.
- render3D () für die aktuelle Zeichnung der 3D- Weltszene .
render2D () für die eigentliche 2D-GUI-Zeichnung.
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 ...
}
Und dann würde ich in der Haupt-Thread-Schleife die Methoden einfach in der folgenden Reihenfolge aufrufen:
while(m_drawFrame)
{
gm_Render->render3D(); // draw 3D scene
gm_Render->render2D(); // draw GUI
SDL_GL_SwapBuffers(); // make drawn frame visible
}
Ich zeichne also zuerst meine 3D-Weltszene und dann zuletzt meine GUI, sodass die GUI immer über der Weltszene liegt. Mit der ready3D () -Methode wird die 3D- Weltprojektion für das Zeichnen von Weltszenen vorbereitet und mit der ready2D () -Methode wird die 2D- Orthoszene für das Zeichnen mit der grafischen Benutzeroberfläche vorbereitet . m_Setup.width
und m_Setup.height
sind nur die Ansichtsfenster-Bildschirmabmessungen.
Das Besondere an der ready2D () -Methode ist, dass die gluOrtho2D()
Funktion mit Argumenten aufgerufen wird, die angeben, dass die GUI- Grundelemente in den Bildschirmkoordinaten gezeichnet werden, die für Windows, Mac und andere Desktop-Bildschirmkoordinatensysteme angegeben sind. So ist beispielsweise links oben (0,0) im Format (X, Y), rechts unten (ViewportWidth-1, ViewportHeight-1)
. Und glTranslatef()
wird verwendet, um die pixelgenaue Positionierung zu korrigieren. Wenn wir also eine Linie von (0,0) bis (0,9) zeichnen, wird die Linie tatsächlich von links oben und gerade nach unten gezogen, und zwar mit einer Gesamtlänge von zehn Pixeln und einer Breite von einem Pixel.
Insgesamt interessiert Sie wahrscheinlich nur, was die ready2D () -Methode leistet. Ich habe die Quellcodebeispiele der anderen Methoden bereitgestellt, um Ihnen eine Vorstellung davon zu geben, wie die meisten Spiele 3D-Weltszene und GUI-Zeichenreihenfolge ausführen.
([0...1], [0...1], 0, 1)
Projektion, Ansicht oder Weltmatrix verwenden, landen sie immer im Bildschirmbereich.