Ist es in OpenGL eine schlechte Idee, den Sofortmodus und den Beibehaltungsmodus für GUIs zu kombinieren?

8

Angenommen, ich habe eine 3D-Szene, mit der gezeichnet wird, glDrawArrays(...)und möchte etwas Einfaches wie eine 2D-Überlagerung rendern. Wäre es eine schlechte Idee, für so etwas den Sofortmodus zu verwenden, anstatt einen 2D-Renderer mit beibehaltenem Modus einzurichten?

Beispiel:

void Draw()
{
    // Draw the 3D scene:
    // *does stuff*
    glDrawArrays(...);
    // *some other stuff*

    // Setup a quad with immediate mode (for something like a vignette overlay)
    glBegin(GL_QUADS);
    glTexCoord2f(...); glVertex2f(...);
    glEnd();
}
KK Slider
quelle
Minecraft macht das. Es funktioniert einwandfrei, außer um Ihre OpenGL-Version (auf <3.1 oder ein Kompatibilitätsprofil) zu beschränken und Ihre GUI weniger schnell zu machen.
user253751
Hinweis Minecraft verfügt auch über eigene Funktionen, die den Sofortmodus mithilfe von Vertex-Arrays simulieren - das Schreiben ist nicht schwierig. Ich bin mir nicht sicher, ob sie sie noch für die GUI verwenden.
user253751

Antworten:

7

Es ist eine schlechte Idee, sofern es unsinnig ist. Es gibt nichts zu "einrichten", was Sie noch nicht getan haben, außer einer ortho-Projektionsmatrix (die Sie auf jeden Fall tun müssen).

Portabilität ist wahrscheinlich kein Problem, obwohl es sein sollte. IHVs scheinen auf absehbare Zeit sehr zurückhaltend zu sein, die Unterstützung für den Sofortmodus einzustellen (es scheint sogar in Kernprofilen "gut zu funktionieren"). Obwohl der Sofortmodus längst ausgestorben sein sollte, wird er wahrscheinlich für immer bleiben. Leistung ist eine andere Geschichte. Möchten Sie wirklich, dass etwas, das 0,1% der Szenenkomplexität ausmacht, 15 bis 20% der CPU-Zeit beansprucht - GL-Aufrufe sind im Vergleich zu z. B. DX relativ leicht, aber nicht kostenlos - und 15 bis 20% reale Frame-Zeit aufgrund des Stillstands der Pipeline? Können Sie sich das mit Ihrem Zeitbudget überhaupt leisten? Die meisten Spiele können nicht.

Und dann natürlich die Macken. Oh die Macken. Die offensichtliche Schönheit des Sofortmodus besteht darin, dass es (scheinbar) einfach und unkompliziert ist, schnell ein paar Quads zu zeichnen. In Wirklichkeit kann der Sofortmodus ein derartiger Schmerz im Heck sein, dass er so voller nicht offensichtlicher Fallstricke ist.
Auf der anderen Seite ist es genauso einfach (und einfacher, wenn Sie mich fragen!), Nur eine kleine 5-LOC-Funktion zu schreiben, DrawQuaddie beim Aufruf Scheitelpunktkoordinaten und -indizes zu einem Speicherpuffer hinzufügt und einen Zähler inkrementiert. Mit welcher Überraschung können Sie dann zeichnen glDrawArrays/Elementsund welche Sie wiederverwenden können (die GPU-Kopie, nicht nur die Userland-Kopie!), Ist der nächste Frame so wie er ist, solange nichts geändert wird.
Der Sofortmodus muss, es gibt keine andere Möglichkeit, jedes Mal einen Puffer zuweisen und eine PCIe-Übertragung durchführen. Oder eine äquivalente Latenz (GPU liest den Hauptspeicher über den Bus, was auch immer). Der Treiber kann möglicherweise nicht wissen (oder annehmen), dass die Daten genau die gleichen wie im vorherigen Frame sind.

Das Abrufen von Daten an die GPU ist eine Operation mit hoher Geschwindigkeit, aber auch hoher Latenz . Nicht nur ist der Bus - Transfer per se eine komplizierte, hohe Latenz - Protokoll (mehrere Protokollschichten, Paketieren, Bestätigungen etc.), aber auch nicht alle GPUs sind sogar in der Lage gleichzeitig zu übertragen und zu zeichnen, oder wenn sie es tun können Sie sind möglicherweise nicht immer in der Lage, frei zwischen neuen Operationen zu wechseln oder diese zu initiieren, während sie etwas anderes tun. Lesen Sie als: Du sollst nicht umsonst übertragen .

Damon
quelle
"Es gibt nichts zu" einrichten ", was Sie noch nicht getan haben" Batch-Rendering?
HolyBlackCat
2
Obwohl IHVs den Sofortmodus nur ungern löschen, gibt es unter Linux auch Videotreiber, die keine höhere OpenGL-Version unterstützen, es sei denn, Sie fordern Core Profile an. Dies insbesondere mittels Intel HD - Grafik ( intelTreiber), aber auch NVidia und AMD - Chips als Open-Source - Treiber verwenden ( nouveauund amdgpujeweils). Ebenso haben Sie unter MacOS kein Kompatibilitätsprofil mit OpenGL> 2.1.
Ruslan
@HolyBlackCat: Ich bin nicht sicher, was du meinst? OP-Zustände mit einer funktionierenden 3D-Pipeline basierend auf glDrawArrays. Es ist also alles eingerichtet, was für einen weiteren Aufruf von glDrawElements(oder Array, je nachdem) erforderlich ist, um alle Quads für die GUI zu zeichnen (nachdem die Scheitelpunkte in einen Puffer geschrieben wurden). Funktionen werden geladen, Sie haben ein Framework zum Zuweisen von Puffern usw. Eigentlich nichts Besonderes, um die GUI zu stapeln. Binden Sie einfach die GUI-Textur (oder nicht, wenn Sie noch genügend TUs haben, um sie gebunden zu lassen), legen Sie die Ortho-Matrix fest und führen Sie einen zusätzlichen Zeichenaufruf aus . Wie wollen Sie besser stapeln?
Damon
(Natürlich stimme ich zu, dass der Sofortmodus schlecht ist.) Entschuldigung, wenn ich nicht klar war. Ich meine den Prozess des Füllens des Scheitelpunktpuffers. Das ist einfach, aber es ist etwas mehr Arbeit als im Sofortmodus.
HolyBlackCat
12

Ich persönlich sehe es nur aus zwei Gründen als schlecht an:

  1. Es ist sehr veraltet und veraltet. Und,
  2. Es ist viel langsamer als die modernen Zeichenmethoden mit OpenGL.

Aber wenn es funktioniert und die Leistung kein Problem darstellt und es für Sie kein Problem ist, veraltete OpenGL-Funktionen in Ihrem Programm zu verwenden, können Sie dies meiner Meinung nach tun. Es wird langsamer sein, Tonnen und Tonnen von GUIs zu haben, aber wenn es nicht so viele sind, versuchen Sie es erneut.

Verstehe das aber. Dass OpenGL am Ende des Tages dasselbe tut; Zeichnen auf den Bildschirm. Der Sofortmodus ist nur viel langsamer, wenn viele Dinge verarbeitet werden. Sie sollten also auswählen, was für die Aufgabe, die Sie vorhaben, am nützlichsten ist. Hoffe das hilft dir weiter!

dev9999
quelle
1

Ein weiterer Nachteil ist, dass Ihr Code dadurch weniger portabel wird. Bestimmte OpenGL-Varianten unterstützen den Sofortmodus überhaupt nicht, z. B. OpenGL ES. (und wenn Android-basierte Geräte wie Tablets mit größerem Kaliber mehr Zugkraft gewinnen, könnte dies wichtig werden)

Anzeigename
quelle
0

Die Verwendung des Sofortmodus ist für Arbeiten im Zusammenhang mit GUI völlig unnötig.

Um ein einfaches GUI-Element zu erstellen, sagen wir eine Schaltfläche:

  1. Sie benötigen ein Quad / Dreieck-Streifennetz,
  2. Eine Textur für das Netz
  3. Eine orthographische Projektionstransformation

Auf diese Weise können Sie einfach einen einfachen Pass-Through-Shader schreiben, der Beleuchtungsaspekte ignoriert, das GUI-Element auf eine Pixelskala oder einen bestimmten Prozentsatz des Fensters skalieren und dann einen Maleralgorithmus zum Rendern ausführen.

Auf diese Weise können Sie ein vollständiges UI-System mit allen Leistungsvorteilen des beibehaltenen Modus erstellen.

Ian Young
quelle