Die richtigste Antwort ist, es hängt davon ab, wie Sie es programmieren, aber das ist eine gute Sache, um die Sie sich sorgen müssen. Obwohl die GPUs unglaublich schnell geworden sind, ist die Bandbreite zum und vom GPU-RAM nicht so hoch und wird Ihr frustrierendster Engpass sein.
Werden seine Daten nur einmal an den GPU-Speicher gesendet und bleiben dort für immer?
Hoffentlich ja. Für die Rendergeschwindigkeit möchten Sie, dass so viele Daten wie möglich auf der GPU gespeichert werden, anstatt sie bei jedem Frame erneut zu senden. VBOs dienen genau diesem Zweck. Es gibt sowohl statische als auch dynamische VBOs, wobei ersteres für statische Modelle und letzteres für Modelle am besten geeignet ist, deren Scheitelpunkte jeden Frame ändern (z. B. ein Partikelsystem). Selbst wenn es um dynamische VBOs geht, möchten Sie nicht alle Scheitelpunkte in jedem Frame erneut senden. nur diejenigen, die sich ändern.
Im Fall Ihres Gebäudes würden die Scheitelpunktdaten nur dort stehen, und das einzige, was sich ändert, sind Ihre Matrizen (Modell / Welt, Projektion und Ansicht).
Im Fall eines Partikelsystems habe ich einen dynamischen VBO erstellt, der groß genug ist, um die maximale Anzahl von Partikeln zu speichern, die jemals für dieses System existieren werden. Jedes Bild, das ich sende, enthält die Daten für die Partikel, die dieses Bild aussenden, sowie ein paar Uniformen, und das ist alles. Beim Zeichnen kann ich in diesem VBO einen Start- und einen Endpunkt angeben, damit ich keine Partikeldaten löschen muss. Ich kann nur sagen, dass ich die nicht zeichne.
Wenn das Modell tatsächlich gerendert wird, müssen GPU-Prozessoren jedes Mal ihre Daten aus dem GPU-Speicher abrufen? Was ich meine ist - wenn ich 2 Modelle jeweils mehrfach gerendert hätte - wäre es wichtig, wenn ich zuerst das erste mehrfach und dann das zweite mehrfach gerendert hätte oder wenn ich das erste nur einmal, das zweite nur einmal und immer wieder so verschachtelt?
Das Senden mehrerer Draw Calls anstelle von nur einem ist ein viel größeres Limit. Schauen Sie sich das instanziierte Rendering an. Es könnte Ihnen sehr helfen und die Antwort auf diese Frage unbrauchbar machen. Ich hatte einige Treiberprobleme, die ich noch nicht gelöst habe, aber wenn Sie es zum Laufen bringen können, ist das Problem gelöst.
Offensichtlich haben Grafikkarten einen begrenzten RAM - wenn sie nicht alle Modelldaten enthalten können, die für das Rendern von 1 Frame erforderlich sind, wird sie vermutlich weiterhin von jedem Frame aus dem CPU-RAM abgerufen. Ist das richtig?
Ihnen soll nicht der GPU-RAM ausgehen. Wenn Sie dies tun, ändern Sie die Dinge, damit Sie dies nicht tun. In dem sehr hypothetischen Szenario, das Ihnen ausgeht, wird es wahrscheinlich irgendwie abstürzen, aber ich habe es nie erlebt, also weiß ich es ehrlich gesagt nicht.
Ich habe vergessen, eine Unterscheidung zu treffen: Es werden die Daten an die GPU gesendet und die Puffer werden als aktuell festgelegt / gebunden. Verursacht letzteres einen Datenfluss?
Kein signifikanter Datenfluss, nein. Das ist mit Kosten verbunden, aber das gilt für jede Codezeile, die Sie schreiben. Finden Sie heraus, wie viel es Sie kostet und wofür Profiling gedacht ist.
Puffererstellung mit Initialisierung
Raxvans Antwort klingt gut, ist aber nicht ganz richtig. In OpenGL, den Puffer zu schaffen nicht jeden Raum reservieren. Wenn Sie Speicherplatz reservieren möchten, ohne Daten zu übergeben, können Sie glBufferData aufrufen und einfach null übergeben. (Siehe den Abschnitt Notizen hier .)
Aktualisierung der Pufferdaten
Ich vermute, Sie meinen glBufferData oder andere Funktionen wie diese, oder? Hier erfolgt die eigentliche Datenübertragung. (Es sei denn, Sie übergeben Null, wie ich gerade im letzten Absatz gesagt habe.)
Binden des Puffers als aktiv (ist dies nur eine Möglichkeit, der API mitzuteilen, dass dieser Puffer beim nächsten Aufruf von draw gerendert werden soll, und dass er selbst nichts tut?)
Ja, aber es kann noch ein bisschen mehr. Wenn Sie beispielsweise ein VAO (Vertex-Array-Objekt) binden und dann ein VBO binden, wird dieses VBO an das VAO gebunden. Wenn Sie das VAO später erneut binden und glDrawArrays aufrufen, weiß es, welches VBO zu zeichnen ist.
Beachten Sie, dass Sie in vielen Tutorials für jeden VBO einen VAO erstellen müssen. Mir wurde jedoch mitgeteilt, dass dies nicht die beabsichtigte Verwendung ist. Angeblich solltest du eine VAO erstellen und diese mit jedem VBO verwenden, der die gleichen Attribute hat. Ich habe das noch nicht ausprobiert, daher kann ich nicht sicher sagen, ob es besser oder schlechter ist.
API-Draw-Aufruf
Was hier passiert, ist aus unserer Sicht ziemlich einfach. Angenommen, Sie binden eine VAO und rufen dann glDrawArrays auf. Sie geben einen Startpunkt und eine Anzahl an, und der Scheitelpunkt-Shader wird für jeden Scheitelpunkt in diesem Bereich ausgeführt, der seine Ausgaben entlang der Linie weitergibt. Dieser ganze Prozess ist jedoch ein weiterer eigener Aufsatz.