Ich benutze OpenGL jetzt schon seit kurzer Zeit - und ich möchte einige Erläuterungen zu VBOs . Nach meinem Verständnis ist ein VBO ein im VRAM gespeichertes Objekt. Um eine Textur anzuwenden, binden wir sie im Sofortmodus einfach und geben die Texturkoordinaten vor den Scheitelpunktkoordinaten an. Bei VBOs scheint dies jedoch nicht der Fall zu sein.
Frage 1: Kann ich Texturdaten in einem VBO angeben? Welcher Teil der Daten?
Wenn ich ein Spiel in 2d mache, speichere ich normalerweise alle meine Objekte in Instanzen verschiedener Klassen. Wenn dann meine Zeichenroutine auftaucht, zeichne einfach die Objekte, die auf dem Bildschirm angezeigt werden. In einer 3D-Umgebung wäre es etwas schwieriger, nur die Objekte auf dem Bildschirm zu zeichnen, aber mit etwas Mathematik bin ich sicher, dass dies machbar ist.
Frage 2: Wenn wir herausgefunden haben, welche Objekte gerendert werden müssen, wäre es akzeptabel schnell, diesen entsprechenden Objekten eine "Anwenden" -Anforderung zu senden und sie selbst anwenden zu lassen? Oder gibt es einen besseren Weg?
Frage 3: Wenn ich eine vollständig dynamische Karte habe, aber Objekte, die sich nicht sehr oft ändern, gibt es Richtlinien für die Leistungsunterschiede zwischen GL_STATIC_DRAW
und GL_DYNAMIC_DRAW
?
Letzte Frage: Sollte ich überhaupt in Betracht ziehen, Scheitelpunktlisten zu verwenden? Oder sind VBOs nur eine bessere Option?
glDrawElements
jedes Objekt aufrufen wollen - oder sollte ich alles als Dreiecke speichern und nur eines habenglDrawElements
? Ist so oder so machbar?Antworten:
Antwort 1:
Natürlich können Sie ohne Texturierungsfunktionen Vertex-Puffer so gut wie unbrauchbar machen. Ein VBO ist nur ein Teil der Binärdaten mit dem von Ihnen angegebenen Format (Positionskanal, normaler Kanal, Texcoord-Kanal usw.), die von einem Shader interpretiert werden. Wenn Sie ein Objekt zeichnen, weisen Sie die GPU an, diesen Datenstapel abzurufen und die im Shader angegebenen Operationen anzuwenden (Scheitelpunkttransformation, Lichtberechnung, Texturabruf usw.).
Nehmen wir zum Beispiel, Sie haben einen VBO mit einem darin gespeicherten Quad. Das VBO speichert die Positions- und Texturkoordinateninformationen der vier Eckpunkte. Jetzt müssen Sie nur noch das VBO binden, ein IBO binden, um die Dreiecke anzugeben, aus denen Ihr Quad besteht, Ihren Shader anweisen, eine Textur Ihrer Wahl zu verwenden und das Ganze zu zeichnen. Und jetzt, da Sie VBO und IBO aktiviert haben, müssen Sie nur noch den Texturparameter des Shaders ändern und die Zeichenfunktion erneut aufrufen, um Ihr Quad in einem anderen Objekt wiederzuverwenden.
Antwort 2:
Wie in Antwort 1 angegeben, müssen Sie beim Erstellen und Speichern Ihres VBO im VRAM nur Ihre Shader-Variablen aktualisieren und
glDrawElements
erneut aufrufen , um das Objekt neu zu zeichnen.Antwort 3:
Nun, Sie können sich
GL_DYNAMIC_DRAW
auf die gesamte Karte anwenden , wenn Sie dies möchten. Der Unterschied zwischen diesen beiden Optionen besteht darin, dass der Treiber dynamische Puffer im schnellsten Teil des VRAM speichert, den er finden kann. Wenn Sie ihn also für Objekte verwenden, deren Geometrie nicht wiederholt geändert wird, verschwenden Sie ihn. Die OpenGL-Referenz für glBufferData gibt Ihnen einen Hinweis darauf, welche Verwendung für Ihren Puffer am besten ist.Endgültige Antwort:
glDrawArrays
ist nur eine primitive Version von VBOs, bei der die Daten in Kanäle unterteilt, aber bei jedem Anruf erneut auf die GPU hochgeladen werden. Halten Sie sich einfach an VBOs, wenn Sie die beste Leistung erzielen möchten.quelle
Obwohl ich mit der Antwort von r2d2rigo vollkommen zufrieden bin, möchte ich erklären, wie ich VBOs visualisieren werde: D.
Erstens, obwohl VBO Vertex-Pufferobjekt bedeutet, bedeutet dies nicht, dass es nur Vextex-Koordinaten enthält.
Hier müssen Sie also ein VBO wie "Es kann in der Lage sein, die gesamten Scheitelpunktattribute zu speichern" verstehen. Grundsätzlich ist ein VBO ein "Puffer", den Sie an jede der Vertex-Informationen binden können.
Antwort 1: Ja (siehe obige Beschreibung)
Antwort 2: VBOs sind normalerweise "schneller" als übliche Scheitelpunktlisten, da die Scheitelpunktinformationen nicht in jedem Frame verschoben werden müssen (wenn die Daten statisch sind). Selbst wenn es sich bei der zugrunde liegenden Architektur um eine einheitliche Speicherarchitektur handelt, hat dies Vorteile, da Daten nicht unnötig überschrieben werden.
Antwort 3: STATIC_DRAW / DYNAMIC_DRAW sind nur Flags, die der zugrunde liegenden GPU mitteilen, wo die Puffer aufbewahrt werden sollen. Die zugrunde liegende GPU entscheidet anhand der von Ihnen angegebenen Flags, wo die Puffer aufbewahrt werden sollen. Dies sollte für einen besseren Durchsatz berücksichtigt werden. Aber in Unified Die Speicherarchitektur (bei der die GPU den Hauptspeicher gemeinsam nutzt) wird meiner Meinung nach keinen wesentlichen Unterschied machen.
quelle