Zastanawiałem się, jaki stan jest przechowywany w OpenGL VAO. Zrozumiałem, że VAO zawiera stan związany ze specyfikacją wierzchołków buforowanych wierzchołków (jakie atrybuty znajdują się w buforach i jakie bufory są powiązane, ...). Aby lepiej zrozumieć prawidłowe użycie VAO, chciałbym dokładnie wiedzieć, w jakim są stanie.
Jak zakładam, należy użyć VAO
Z prostych przykładów zrozumiałem, że prawidłowe użycie VAO jest następujące:
Ustawiać
Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO
Wykonanie
Bind VAO
---- Draw
Unbind VAO
Na podstawie tego zakładam, że co najmniej powiązania bufora wierzchołków i specyfikacje atrybutów wierzchołków są przechowywane w VAO. Nie jestem jednak pewien, w jaki sposób ten wzorzec użytkowania rozciąga się na sytuacje, w których wchodzą (wiele) tekstur i (wiele) programów do cieniowania. Czy aktywny program cieniujący jest przechowywany w VAO? I czy wiązania tekstur (wraz z ustawieniami próbkowania / zawijania ) są również przechowywane w VAO? To samo dotyczy mundurów ?
Dlatego moje pytania to:
- Jaki dokładnie stan jest przechowywany w OpenGL VAO ? (Powiązania VBO, specyfikacje atrybutów, aktywny program cieniujący, wiązania tekstur, ustawienia próbkowania / zawijania tekstur, mundury ...?)
- Jak poprawnie używać VAO w bardziej złożonej konfiguracji renderowania, w której zaangażowane są (wiele) tekstur z powiązanymi ustawieniami próbkowania / zawijania, (wiele) programów cieniujących i mundurów?
Odpowiedzi:
VAO przechowuje dane o lokalizacjach atrybutów wierzchołków. (I niektóre inne związane z nimi dane.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"
Są całkowicie z tym niezwiązane.Możesz zapytać, dlaczego nie pamięta wiązania VBO. Ponieważ nie musisz wiązać VBO, aby coś narysować, musisz tylko powiązać to podczas tworzenia VAO: Kiedy dzwonisz
glVertexAttribPointer(...)
, VAO pamięta, co VBO jest obecnie związane. I VAO weźmie atrybuty z tych VBO podczas rysowania, nawet jeśli te VBO nie są obecnie powiązane.Ponadto VAO i VBO muszą być używane nieco inaczej:
To nie zadziała
ponieważ musisz powiązać VBO, aby określić lokalizacje atrybutów.
Powinieneś to zrobić w ten sposób:
Możesz zmienić dane VBO w dowolnym momencie, ale musisz je wcześniej powiązać.
A rysunek powinien wyglądać następująco:
Jak zauważyłeś, usunąłem
unbind
połączenia z twoich list. Są prawie całkowicie bezużyteczne i nieco spowalniają twój program, więc nie widzę powodu, aby je wywoływać.źródło
gl{Enable|Disable}VertexAttribArray()
), ich wartości domyślne (glVertexAttrib*()
), ich tryb instancji (glVertexAttribDivisor()
) i prawdopodobnie coś innego.Przechowuje tylko powiązanie wierzchołka i powiązanie bufora indeksu
To są wszystkie parametry
glVertexAttribPointer
plus bufor związany z Vertex_Array_buffer w momencie wywołania doglVertexAttribPointer
i związany Element_Array_buffer.Mundury są częścią bieżącego programu.
Cała reszta to stan globalny.
W razie wątpliwości możesz sprawdzić tabele stanu w specyfikacji używanej wersji.
źródło
Oto proste, ale skuteczne wyjaśnienie, w zasadzie obiekt buforowy zawiera informacje, które można interpretować jako zwykłe fragmenty surowych danych, które same w sobie nic nie znaczą, więc OCZYWIŚCIE to dane, na które można naprawdę spojrzeć w jakikolwiek sposób
a sposób, w jaki OpenGL został zaprojektowany, polega na tym, że musisz OKREŚLIĆ, jak będą wyglądały dane przesyłane do różnych modułów cieniujących
w tym, że musisz również zdefiniować, w jaki sposób będą odczytywać te dane, w jakim formacie i jak z nimi postępować oraz w jaki sposób będą wykorzystywane i do czego, wszystkie te informacje są przechowywane w VAO
na przykład możesz zadeklarować dane przechowywane w takiej tablicy
float vbo = {11.0,2.0,3.0,4.0}
w tym momencie wymagane jest, jak interpretować te dane z VBO w VAO, a to oznacza, co następuje
VAO można ustawić na odczyt 2 liczb zmiennoprzecinkowych na wierzchołek (co dałoby 2 wektory o dwóch wymiarach x, y) lub możesz powiedzieć vao, aby zinterpretowało go jako 1 wektor o 4 wymiarach, tj. x, y, z, w itp
ale także inne atrybuty tych danych są zdefiniowane i przechowywane w VAO, takie jak format danych (pomimo że zadeklarowałeś tablicę zmiennoprzecinkową, możesz nakazać modułowi cieniującemu odczytanie go jako liczbę całkowitą, przy czym system konwertuje nieprzetworzone dane w proces od liczby zmiennoprzecinkowej do liczby całkowitej i ma własny zestaw reguł, co robić w takich okolicznościach)
Zasadniczo VBO to dane, a VAO przechowuje informacje na temat interpretacji tych danych, ponieważ shadery i serwer OpenGL zostały zaprojektowane tak, aby były bardzo wścibskie i muszą wiedzieć wszystko, zanim zdecydują, jak je przetworzyć, co z nimi zrobić i gdzie położyć to
oczywiście nie jest wścibski, naprawdę wygląda na najbardziej wydajny, ponieważ musi przechowywać te dane w pamięci serwera graficznego, aby uzyskać najbardziej wydajne i najszybsze przetwarzanie (chyba że zdecyduje, że nie musi tego robić, jeśli dane nie mogą być przetwarzane w taki sposób i wykorzystywane do niektórych innych informacji, do których często nie ma dostępu), dlatego też szczegóły dotyczące tego, co zrobić z danymi i jak je przetwarzać, muszą być przechowywane w VAO, więc VAO jest jak nagłówek, a VBO jest jak czyste, surowe dane, które nagłówek używa i definiuje (w tym przypadku przekazuje atrybuty wierzchołka modułu cieniującego), z tym wyjątkiem, że VBO nie jest ograniczone tylko do jednego VAO, to mogą być używane i ponownie używane oraz powiązane z wieloma VAO, na przykład:
co możesz zrobić, to możesz powiązać jeden obiekt buforowy z VAO1, a także (osobno) powiązać ten sam obiekt buforowy z VAO2, przy czym każdy interpretuje go inaczej, tak że jeśli twój moduł cieniujący przetwarza dane, w zależności od tego, który VAO jest tym, który jest związany, przetwarzałby te same surowe dane inaczej niż frambuffer (rysowanie pikseli do okna), co skutkowałoby innym wyświetlaniem tych samych danych, które byłyby oparte na tym, jak zdefiniowałeś ich użycie w VAO
źródło