Erstellen eines HUD / GUI mit OpenGL (LWJGL)

15

Ich bin in der Phase meiner Spieleentwicklung, in der ich ein HUD oder eine GUI erstellen muss. Ich bin noch nie zu diesem Teil gekommen, also weiß ich nicht, wie es gemacht wird. Ich habe versucht, ein einfaches Quad an einer festen Position auf dem Bildschirm zu rendern, aber es gibt ein Problem. Damit meine Kamera mit Orthographie funktioniert, verwende ich Folgendes:

public void lookThrough()
{
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(position.x, position.x + Display.getDisplayMode().getWidth()/zoom, position.y + Display.getDisplayMode().getHeight()/zoom, position.y, -1, 1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
}

Ich sehe nicht, wie ich mit dieser Methode etwas am Bildschirm reparieren kann. Irgendwie darum herum? Vielen Dank :)

smoth190
quelle
Ich werde nicht antworten, da dies aus einer Direct3D-Perspektive ist, aber wenn Sie die Koordinaten ohne ([0...1], [0...1], 0, 1)Projektion, Ansicht oder Weltmatrix verwenden, landen sie immer im Bildschirmbereich.
Jonathan Dickinson

Antworten:

13

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.widthund m_Setup.heightsind 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.

NAM TRON
quelle
Danke, ich wusste nur nicht, ob das Umschalten zwischen Ortho und Perspektive für die Leistung schlecht ist, denn für mich scheint es eine große Operation zu sein (natürlich weiß ich kaum, wie OpenGL funktioniert ... lerne noch!), Aber ich habe es überall gesehen, und was Sie gesagt haben, schlagen Sie vor, dies zu tun. Also werde ich wohl :)
smoth190
Ich mag diese Antwort, es ist irgendwie das, woran ich dachte. Ich habe mich nur gefragt, ob es besser geht, wenn Sie die Projektionsmatrix auf jeden 2D-Render schieben und sie anschließend platzen lassen. Das würde bedeuten, dass Sie 3D sicher nur einmal einrichten könnten? Dann müssten Sie Ihr 3D-Setup nur noch einmal für Fenstergrößenänderungen aufrufen, wenn Sie damit umgehen.
Glühbirne 1