Ich sehe, dass OpenGL-Versionen 3 und höher die Verwendung von clientseitigem Rendering eliminieren. Der Sofortmodus wurde entfernt und Vertex-Arrays scheinen veraltet zu sein. Wenn ich das richtig verstehe, sind VBOs die Hauptmethode zum Rendern von Vertices.
Während ich die Logik dahinter sehe, alles auf einheitliche Weise zu rendern, haben VBOs keine großen Nachteile gegenüber Vertex-Arrays? Ich dachte, VBOs sollten im Allgemeinen große Puffer sein, die mehr als 1 MB Daten enthalten. Was ist, wenn ich eine Szene mit viel kleinerer Geometrie habe? Ich habe ein Szenendiagramm mit einer großen Anzahl von Knoten, von denen jeder eine eigene Transformation usw. benötigt. Jeder Knoten sollte auch separat gelöscht, zu separat hinzugefügt usw. werden können. Ich habe zuvor Vertex-Arrays verwendet. Meine erste Frage ist also, ob beim Umstieg auf VBOs der Aufwand für meine Szenendiagrammobjekte jetzt höher ist, da für jedes Objekt ein VBO zugewiesen werden muss.
Ein weiteres Problem ist, dass die von mir gerenderte Geometrie sehr dynamisch sein kann. Im schlimmsten Fall kann es vorkommen, dass die gesamte Geometrie für einen bestimmten Zeitraum erneut an jeden Frame gesendet werden muss. Haben VBOs in diesem Anwendungsfall eine schlechtere Leistung als Vertex-Arrays, oder funktionieren VBOs im schlimmsten Fall genauso gut wie Vertex-Arrays, jedoch nicht mehr?
In einem präziseren Format lauten meine Fragen also:
1) Ist die Zuweisung / Freigabe von VBOs mit einem erheblichen Aufwand verbunden (ich meine die bloße Einrichtung eines Puffers)?
2) Wenn ich die Daten von der CPU in jedem Frame aktualisiere, kann dies wesentlich schlimmer sein, als wenn ich Vertex-Arrays verwendet hätte?
Und zum Schluss würde ich gerne wissen:
3) Wenn die Antwort auf eine der obigen Fragen "Ja" lautet, warum sollten andere Rendering-Modi, die Vorteile gegenüber VBOs haben könnten, verworfen werden? Fehlt hier etwas, beispielsweise Techniken, mit denen ich einige dieser potenziellen Allokationskosten usw. abmildern soll?
4) Ändern sich die Antworten auf diese Fragen erheblich, je nachdem, welche OpenGL-Version ich verwende? Wenn ich meinen Code so umgestalte, dass er mit OpenGL 3 oder 4 vorwärtskompatibel ist, indem ich VBOs auf performante Weise verwende, werden dieselben Techniken mit OpenGL 2 wahrscheinlich gut funktionieren, oder ist es wahrscheinlich, dass bestimmte Techniken mit OpenGL 3 viel schneller sind + und andere mit OpenGL 2?
Ich habe diese Frage zum Stapelüberlauf gestellt, aber ich poste sie hier erneut, da mir klar wurde, dass diese Site für meine Frage möglicherweise besser geeignet ist.
quelle
Antworten:
Definieren Sie "substantiell". Es ist im Allgemeinen ratsam, sie nicht in der Mitte von Frames zu erstellen. Sie sollten während der Initialisierung oder an einem beliebigen Ort eingerichtet werden. Dies gilt jedoch für die meisten OpenGL-Objekte, z. B. Texturen, Renderbuffer oder Shader.
Kann es? Ja. OpenGL definiert Funktionalität, nicht Leistung . Sie können die Dinge in der Tat viel langsamer machen. Oder Sie können die Dinge schneller machen. Es hängt alles davon ab, wie Sie es verwenden.
Das OpenGL-Wiki bietet einen guten Artikel zum richtigen Streamen von Daten .
Erstens waren sie nicht nur veraltet. Verfall bedeutet, dass in zukünftigen Versionen etwas als "zu entfernen" markiert wird. Sie wurden in 3,0 veraltet und entfernt in 3.1 Kern und darüber.
Zweitens hat die ARB allgemein erklärt, warum sie Inhalte aus OpenGL entfernt haben. Dadurch wird die Spezifikation kleiner und einfacher. Dadurch wird die API kleiner und schlanker. Dadurch ist es einfacher zu wissen, welche APIs Sie verwenden sollten. 2.1 hatte 4 Möglichkeiten, Vertexdaten bereitzustellen; 3.1+ hat 1. Es wird viel Cruft los. Etc.
Mehr oder weniger nein. Nur unter MacOSX ist der Unterschied zwischen 3.1 + Core- und Pre-3.0-Versionen wirklich offensichtlich. Das Kompatibilitätsprofil wird von allen Treibern für Linux und Windows implementiert. Sie können also davon ausgehen, dass das Kernprofil dieser Treiber nur Überprüfungen hinzufügt, um zu verhindern, dass Sie Kompatibilitätsfunktionen aufrufen.
Unter Mac OS X 10.7 ist der GL 3.2 Core verfügbar, nicht jedoch das Kompatibilitätsprofil. Das bedeutet nicht unbedingt etwas für die Aufführungstechniken auf der einen Seite gegen die anderen. Wenn es Unterschiede gibt, ist dies jedoch die Plattform, auf der Sie sie sehen.
quelle
So wie OpenGL funktioniert, muss der Treiber immer dann, wenn Sie Nicht-VBO-Daten verwenden, eine Kopie davon erstellen - in der Praxis wird ein temporärer VBO erstellt -, da nichts Sie daran hindert, die nackten Arrays im Benutzerbereich zwischen Aufrufen von OpenGL zu ändern.
Möglicherweise gibt es einige Tricks auf der Treiberseite, um die Zuweisung der Temperatur zu beschleunigen, aber Sie können nichts tun, um das Kopieren zu verhindern.
Also ja, solange Sie - und die Treiberentwickler - alles richtig machen, sollten VBOs immer nur die Dinge beschleunigen.
quelle
glDrawRangeElements
zum Zeichnen jedes einzelnen Objekts verwenden, oder ist das genauso ineffizient wie Vertex-Arrays?glDrawRangeElements
mehrere Male auf jedem VBO mit ein paar VBOs, anstatt jedem Objekt einen eigenen VBO zuzuweisen?Nicht ganz. Vertex-Arrays bilden die Grundlage für Vertex-Pufferobjekte. Nur der Speicher wurde vom Client auf die Serverseite verschoben.
Zusammenführen kleinerer Geometriesätze zu größeren VBOs. Es ist kein VBO pro Geometriestapel erforderlich. Sie können Teilmengen eines VBO zum Rendern perfekt adressieren. Verwenden Sie einen Nicht-Stereo-Offset für den Parameter Zeigerdaten.
Hierfür gibt es die Pufferverwendungs-Flags GL_DYNAMIC_DRAW und GL_STREAM_DRAW.
Weil es keine Vorteile gibt. Die Geometriedaten müssen in jedem Fall auf die GPU übertragen werden. Die Verwendung eines regulären clientseitigen Vertex-Arrays führt weiterhin zu einer DMA-Übertragung an die GPU, und im unmittelbaren Modus wird ein Stapel erstellt, der ebenfalls zuerst übertragen wird.
Es hat absolut keinen Vorteil, keine VBOs zu verwenden.
quelle