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();
}
Antworten:
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,
DrawQuad
die beim Aufruf Scheitelpunktkoordinaten und -indizes zu einem Speicherpuffer hinzufügt und einen Zähler inkrementiert. Mit welcher Überraschung können Sie dann zeichnenglDrawArrays/Elements
und 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 .
quelle
intel
Treiber), aber auch NVidia und AMD - Chips als Open-Source - Treiber verwenden (nouveau
undamdgpu
jeweils). Ebenso haben Sie unter MacOS kein Kompatibilitätsprofil mit OpenGL> 2.1.glDrawArrays
. Es ist also alles eingerichtet, was für einen weiteren Aufruf vonglDrawElements
(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?Ich persönlich sehe es nur aus zwei Gründen als schlecht an:
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!
quelle
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)
quelle
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:
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.
quelle