Saya bertanya-tanya keadaan apa yang disimpan dalam OpenGL VAO. Saya mengerti bahwa VAO berisi status yang terkait dengan spesifikasi verteks dari simpul buffer (atribut apa yang ada di buffer, dan buffer apa yang terikat, ...). Untuk lebih memahami penggunaan VAO yang benar, saya ingin tahu persis apa yang mereka miliki.
Bagaimana saya mengasumsikan VAO harus digunakan
Dari contoh sederhana, saya mengerti bahwa penggunaan yang benar dari VAO adalah sebagai berikut:
Mendirikan
Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO
Rendering
Bind VAO
---- Draw
Unbind VAO
Dari ini, saya berasumsi bahwa setidaknya binding buffer vertex dan spesifikasi atribut vertex disimpan dalam VAO. Namun saya tidak yakin bagaimana pola penggunaan ini meluas ke situasi di mana (banyak) tekstur dan (banyak) program shader ikut bermain. Apakah program shader aktif disimpan di VAO? Dan apakah binding tekstur (dengan pengaturan sampling / pembungkus ) disimpan di VAO juga? Ditto untuk seragam ?
Karena itu, pertanyaan saya adalah:
- Keadaan apa tepatnya yang disimpan dalam OpenGL VAO ? (Binding VBO, spesifikasi atribut, program shader aktif, binding tekstur, pengaturan pengambilan sampel / pembungkus tekstur, seragam ...?)
- Bagaimana cara menggunakan VAO dengan benar dalam pengaturan render yang lebih kompleks di mana (banyak) tekstur dengan pengaturan pengambilan sampel / pembungkus terkait, (banyak) program shader dan seragam terlibat?
Jawaban:
VAO menyimpan data tentang lokasi atribut simpul. (Dan beberapa data lain yang terkait dengan mereka.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"
Sama sekali tidak terkait dengan itu.Anda mungkin bertanya mengapa tidak ingat VBO mengikat. Karena Anda tidak perlu mengikat VBO untuk menggambar sesuatu, Anda hanya perlu mengikatnya saat membuat VAO: Ketika Anda menelepon
glVertexAttribPointer(...)
, VAO mengingat apa yang terikat VBO saat ini. Dan VAO akan mengambil atribut dari VBO ini ketika Anda menggambarnya, bahkan jika VBO ini tidak terikat saat ini.Juga, VAO dan VBO harus digunakan sedikit berbeda:
Ini tidak akan berfungsi
karena Anda perlu mengikat VBO untuk menentukan lokasi atribut.
Jadi, Anda harus melakukannya seperti ini:
Anda dapat mengubah data VBO kapan pun Anda mau, tetapi Anda harus mengikatnya sebelumnya.
Dan gambar akan terlihat seperti ini:
Seperti yang Anda perhatikan, saya menghapus
unbind
panggilan dari daftar Anda. Mereka hampir sepenuhnya tidak berguna dan mereka akan sedikit memperlambat program Anda, jadi saya tidak melihat alasan untuk memanggil merekasumber
gl{Enable|Disable}VertexAttribArray()
), nilai default mereka (glVertexAttrib*()
), mode instancing mereka (glVertexAttribDivisor()
) dan mungkin sesuatu yang lain.Ini hanya menyimpan pengikatan simpul dan pengikatan buffer indeks
Itu semua parameter
glVertexAttribPointer
ditambah buffer terikat ke Vertex_Array_buffer pada saat panggilan keglVertexAttribPointer
dan Element_Array_buffer terikat.Seragam adalah bagian dari program saat ini.
Yang lainnya adalah keadaan global.
Dalam keraguan Anda dapat memeriksa tabel status dalam spesifikasi versi yang Anda gunakan.
sumber
Berikut ini adalah penjelasan yang sederhana namun efektif, pada dasarnya objek penyangga memiliki informasi yang dapat diartikan sebagai hanya bit data mentah, yang dengan sendirinya tidak berarti apa-apa, sehingga MURNI data yang dapat dilihat dengan cara apa pun
dan cara OpenGL dirancang untuk bekerja adalah bahwa Anda harus MENGEMBANGKAN data apa yang akan Anda sampaikan ke berbagai shader terlihat seperti ke shader
di mana Anda juga harus menentukan bagaimana ia akan membaca data itu, apa formatnya, dan apa yang harus dilakukan dengannya dan bagaimana itu akan digunakan dan untuk apa, semua informasi ini disimpan dalam VAO
misalnya Anda dapat mendeklarasikan data yang disimpan dalam array seperti ini
float vbo = {11.0,2.0,3.0,4.0}
apa yang diperlukan selanjutnya pada titik ini adalah bagaimana menafsirkan data itu dari VBO di VAO, dan apa artinya itu sebagai berikut
VAO dapat diatur untuk membaca 2 float per vertex (yang akan membuatnya 2 vektor dengan dua dimensi x, y) atau Anda dapat memberitahu vao untuk menafsirkannya sebagai 1 vektor dengan 4 dimensi yaitu x, y, z, w dll
tetapi juga atribut lain dari data yang didefinisikan dan disimpan dalam VAO seperti format data (meskipun Anda mendeklarasikan array float, Anda dapat memberi tahu shader untuk membacanya sebagai integer, dengan tentu saja sistem mengubah data mentah di proses dari float ke integer dan memiliki seperangkat aturan sendiri apa yang harus dilakukan dalam keadaan seperti itu)
Jadi pada dasarnya VBO adalah datanya, dan VAO menyimpan cara menginterpretasikan data itu, karena shader dan server OpenGL dirancang untuk menjadi sangat usil dan perlu tahu segalanya sebelum memutuskan bagaimana memprosesnya dan apa yang harus dilakukan dengan itu dan di mana untuk meletakkannya
tentu saja itu tidak benar-benar usil, itu sebenarnya terlihat paling efisien karena perlu menyimpan data itu pada memori server grafis sehingga mendapatkan pemrosesan yang paling efisien dan tercepat (kecuali ia memutuskan bahwa itu tidak perlu melakukan ini jika data tidak akan diproses sedemikian rupa dan digunakan untuk beberapa informasi lain yang tidak sering diakses), dan karenanya mengapa perincian tentang apa yang harus dilakukan dengan data dan bagaimana memprosesnya diperlukan untuk disimpan dalam VAO, jadi VAO seperti header dan VBO seperti data mentah murni yang digunakan dan didefinisikan header (dalam hal ini beralih ke atribut vertex shader) dengan pengecualian bahwa VBO tidak terbatas hanya untuk digunakan oleh satu VAO, itu dapat digunakan dan digunakan kembali dan terikat pada banyak VAO misalnya:
apa yang dapat Anda lakukan adalah Anda dapat mengikat satu objek buffer ke VAO1 dan juga (secara terpisah) mengikat objek buffer yang sama ke VAO2 dengan masing-masing menginterpretasikannya secara berbeda sehingga jika shader Anda di mana memproses data, tergantung pada VAO mana yang terikat itu akan memproses data mentah yang sama secara berbeda ke frambuffer (menggambar piksel ke jendela) menghasilkan tampilan yang berbeda dari data yang sama yang akan didasarkan pada bagaimana Anda mendefinisikan penggunaannya dalam VAO
sumber