Ich habe mich gefragt, welcher Status in einem OpenGL VAO gespeichert ist. Ich habe verstanden, dass ein VAO einen Status enthält, der mit den Scheitelpunktspezifikationen von gepufferten Scheitelpunkten zusammenhängt (welche Attribute befinden sich in den Puffern und welche Puffer sind gebunden, ...). Um die korrekte Verwendung von VAOs besser zu verstehen, möchte ich genau wissen, welchen Status sie haben.
Wie ich davon ausgehe, sollten VAOs verwendet werden
Aus einfachen Beispielen habe ich verstanden, dass die korrekte Verwendung von VAOs wie folgt lautet:
Installieren
Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO
Rendern
Bind VAO
---- Draw
Unbind VAO
Ich gehe davon aus, dass zumindest die Vertex-Pufferbindungen und die Vertex-Attributspezifikationen in der VAO gespeichert sind. Ich bin mir jedoch nicht sicher, wie sich dieses Verwendungsmuster auf Situationen erstreckt, in denen (mehrere) Texturen und (mehrere) Shader-Programme ins Spiel kommen. Ist das aktive Shader-Programm in der VAO gespeichert? Und werden die Texturbindungen (mit ihren Sampling- / Wrapping-Einstellungen ) auch im VAO gespeichert? Das Gleiche gilt für Uniformen ?
Daher sind meine Fragen:
- Welcher genaue Status ist in einem OpenGL VAO gespeichert ? (VBO-Bindungen, Attributspezifikationen, Active Shader-Programm, Texturbindungen, Einstellungen für Texturabtastung / -umhüllung, Uniformen ...?)
- Wie verwende ich VAOs korrekt in einem komplexeren Rendering-Setup, in dem (mehrere) Texturen mit zugehörigen Sampling- / Wrapping-Einstellungen, (mehreren) Shader-Programmen und Uniformen beteiligt sind?
Antworten:
VAO speichert Daten über Scheitelpunktattributpositionen. (Und einige andere Daten, die sich auf sie beziehen.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"
Sind völlig unabhängig davon.Sie können fragen, warum es sich nicht an die VBO-Bindung erinnert. Da Sie VBO nicht binden müssen, um etwas zu zeichnen, müssen Sie es nur binden, wenn Sie VAO erstellen:
glVertexAttribPointer(...)
VAO merkt sich beim Aufrufen , an was VBO derzeit gebunden ist. Und VAO übernimmt Attribute von diesen VBOs, wenn Sie sie zeichnen, auch wenn diese VBOs derzeit nicht gebunden sind.VAOs und VBOs müssen auch geringfügig anders verwendet werden:
Das wird nicht funktionieren
weil Sie VBO binden müssen, um Attributspeicherorte anzugeben.
Also solltest du es so machen:
Sie können die Daten von VBO jederzeit ändern, müssen sie jedoch vorher binden.
Und das Zeichnen sollte so aussehen:
Wie Sie vielleicht bemerkt haben, habe ich
unbind
Anrufe von Ihren Listen entfernt. Sie sind fast völlig nutzlos und verlangsamen Ihr Programm ein wenig, daher sehe ich keinen Grund, sie aufzurufen.quelle
gl{Enable|Disable}VertexAttribArray()
), ihre Standardwerte (glVertexAttrib*()
), ihren Instanzierungsmodus (glVertexAttribDivisor()
) und wahrscheinlich noch etwas anderes.Es werden nur die Scheitelpunktbindung und die Indexpufferbindung gespeichert
Das sind alle Parameter von
glVertexAttribPointer
plus dem Puffer, der zum Zeitpunkt des Aufrufs vonglVertexAttribPointer
Vertex_Array_buffer und dem gebundenen Element_Array_buffer an Vertex_Array_buffer gebunden ist.Uniformen sind Teil des aktuellen Programms.
Alles andere ist globaler Staat.
Im Zweifelsfall können Sie die Statustabellen in der Spezifikation der von Ihnen verwendeten Version überprüfen.
quelle
Hier ist eine einfache, aber effektive Erklärung: Grundsätzlich hat ein Pufferobjekt Informationen, die als einfache Rohdaten interpretiert werden können, die für sich genommen nichts bedeuten. Es sind also REIN die Daten, die wirklich in irgendeiner Weise betrachtet werden können
Und die Art und Weise, wie OpenGL entwickelt wurde, ist, dass Sie DEFINIEREN müssen, wie die Daten aussehen sollen, die Sie an die verschiedenen Shader übergeben
Sie müssen auch definieren, wie diese Daten gelesen werden, in welchem Format sie vorliegen und was damit zu tun ist und wie sie verwendet werden und wofür all diese Informationen in der VAO gespeichert werden
Sie können beispielsweise Daten deklarieren, die in einem Array wie diesem gespeichert sind
float vbo = {11.0,2.0,3.0,4.0}
Was an dieser Stelle als Nächstes erforderlich ist, ist, wie diese Daten von der VBO in der VAO zu interpretieren sind, und was dies bedeutet, ist wie folgt
Der VAO kann so eingestellt werden, dass er 2 Floats pro Vertex liest (was 2 Vektoren mit zwei Dimensionen x, y ergeben würde), oder Sie können den vao anweisen, ihn als 1 Vektor mit 4 Dimensionen zu interpretieren, dh x, y, z, w usw
Aber auch andere Attribute dieser Daten werden im VAO definiert und gespeichert, wie zum Beispiel das Datenformat (obwohl Sie ein Array von float deklariert haben, können Sie den Shader anweisen, es als Ganzzahl einzulesen, wobei das System natürlich die Rohdaten konvertiert der Prozess von float zu integer und hat seine eigenen Regeln, was unter solchen Umständen zu tun ist)
Das VBO ist also im Grunde genommen die Daten, und die VAO speichert, wie diese Daten zu interpretieren sind, da die Shader und der OpenGL-Server sehr neugierig sind und alles wissen müssen, bevor sie entscheiden, wie und was sie wo zu verarbeiten sind um es auszudrücken
Natürlich ist es nicht wirklich neugierig, sondern es scheint am effizientesten zu sein, da es diese Daten auf dem Grafikserver speichern muss, damit es die effizienteste und schnellste Verarbeitung erhält (es sei denn, es entscheidet, dass es dies nicht tun muss, wenn Die Daten dürfen nicht auf diese Weise verarbeitet und für andere Informationen verwendet werden, auf die nicht häufig zugegriffen wird. Daher müssen die Details, was mit den Daten geschehen soll und wie sie verarbeitet werden sollen, in der VAO gespeichert werden Der VAO ist wie ein Header und der VBO ist wie die reinen Rohdaten, die der Header verwendet und definiert (in diesem Fall werden sie an die Shader-Vertex-Attribute übergeben), mit der Ausnahme, dass der VBO nicht darauf beschränkt ist, nur von einem VAO verwendet zu werden kann verwendet und wiederverwendet und an viele VAOs gebunden werden, zum Beispiel:
Sie können ein Pufferobjekt an VAO1 binden und (separat) dasselbe Pufferobjekt an VAO2 binden, wobei jedes Objekt unterschiedlich interpretiert wird, sodass Ihr Shader die Daten verarbeitet, je nachdem, welches VAO das richtige ist Bound würde dieselben Rohdaten unterschiedlich zum Frambuffer verarbeiten (Pixel in Fenster zeichnen), was zu einer unterschiedlichen Anzeige derselben Daten führen würde, die davon abhängt, wie Sie ihre Verwendung in der VAO definiert haben
quelle