OpenGL Vertex Array Object'te (VAO) hangi durum saklanır ve VAO'yu doğru olarak nasıl kullanırım?


25

OpenGL VAO'da hangi durumun saklandığını merak ediyordum. Bir VAO'nun, tamponlanmış tepe noktalarının köşe özellikleriyle ilgili bir durum içerdiğini anladım (arabelleklerde hangi nitelikler ve hangi arabelleklerin bağlı olduğu, ...). VAO'ların doğru kullanımını daha iyi anlamak için, tam olarak hangi durumda olduklarını bilmek isterim.


VAO'ların nasıl kullanılması gerektiğini nasıl varsayırım?

Basit örneklerden VAO'ların doğru kullanımının aşağıdaki gibi olduğunu anladım:

Kurmak

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

sıva

Bind VAO
---- Draw
Unbind VAO

Bundan, en azından tepe tamponlarının ve köşe nitelik özelliklerinin VAO'da depolandığını varsayıyorum . Bununla birlikte, bu kullanım modelinin (çoklu) dokuların (çoklu) gölgelendirici programların devreye girdiği durumlara nasıl yayıldığından emin değilim. Mı aktif shader programı VAO saklanan? Ve doku ciltleri ( örnekleme / sarma ayarlarıyla ) VAO'da da saklanıyor mu? Üniformalar için aynen mı?


Dolayısıyla benim sorularım:

  • Bir OpenGL VAO'da hangi kesin durum saklanır ? (VBO ciltleri, özellik özellikleri, aktif gölgelendirici programı, doku ciltleri, doku örnekleme / sarma ayarları, üniformalar ...?)
  • VAO'ları , ilişkili örnekleme / sarma ayarlarıyla (çoklu) gölgelendirici programları ve üniformaları içeren (çok sayıda) doku içeren , daha karmaşık bir oluşturma kurulumunda nasıl doğru kullanabilirim ?

1
VAO, köşe niteliği konumları hakkındaki verileri depolar. Ayrıca, bu niteliklerin bulunduğu VBO'ların kimliklerini de depolar. Bir şey çizerken VBO'yu bağlamak zorunda değilsiniz, VAO'yu oluştururken glVertexAttribPointer () öğesini çağırmadan önce onu bağlamak zorundasınız.
HolyBlackCat

Yanıtlar:


18

VAO, köşe niteliği konumları hakkındaki verileri depolar. (Ve bunlarla ilgili diğer bazı veriler.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"Bununla tamamen alakasız.

Neden VBO bağlamayı hatırlamadığını sorabilirsiniz. Bir şeyi çizmek için VBO'yu bağlamanız gerekmediğinden, yalnızca VAO oluştururken bağlamanız gerekir: Aradığınızda glVertexAttribPointer(...), VAO hangi VBO'nun bağlı olduğunu hatırlar. Ve VAO, bu VBO'lar şu anda bağlı olmasa bile, çizerken bu VBO'lardan özellikler alacak.


Ayrıca, VAO'lar ve VBO'lar hafif farklı olarak kullanılmalıdır:

Bu işe yaramayacak

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

çünkü özellik konumlarını belirlemek için VBO'yu bağlamanız gerekir.

Yani, böyle yapmalısın:

Generate VAO
BindVAO
Generate VBO's
BindVBO's
Specify vertex attributes

VBO verilerini istediğiniz zaman değiştirebilirsiniz, ancak daha önce bağlamanız gerekir.

Ve çizim şöyle görünmeli:

Bind VAO
Draw


Gördüğünüz gibi, unbindçağrıları listenizden kaldırdım . Neredeyse tamamen yararsızdırlar ve programınızı biraz yavaşlatırlar, bu yüzden onları çağırmak için hiçbir neden göremiyorum.


9
"onları aramak için hiçbir neden göremiyorum." yanlışlıkla değiştirmelerini önlemek için. Özellikle 3. parti kütüphaneleri kullanırken bir sorun.
cırcır ucube 11

Harika cevap için teşekkür ederim! Kısacası, VAO yalnızca köşe niteliği konumlarını depolar. Bir VAO bağlanırken VBO'lar geri tepmez, çünkü VAO öznitelikleri bulmak için hangi tamponları bildiğini gösterir. Diğer tüm durumlar ise global OpenGL durumundadır.
Jelle van Campen

@JevevanCampen Evet, doğru. Bilginize, aynı zamanda niteliklerin ( gl{Enable|Disable}VertexAttribArray()) durumunu, varsayılan değerlerini ( glVertexAttrib*()), örnekleme modunu ( glVertexAttribDivisor()) ve muhtemelen başka bir şeyi de saklar .
HolyBlackCat

@HolyBlackCat varsayılan durumun (glVertexAttrib ()) VAO durumunun bir parçası olduğundan emin misiniz? OpenGL wiki içerik bağlamı olduğunu söyleyerek aksi iddia ediyor.
rdb

@ Nb Hayır, emin değilim. Onlardan VAO devletinin bir parçası olmalarını bekledim ve kontrol etmedim.
HolyBlackCat

4

Yalnızca köşe bağlamasını ve dizin tamponu bağlamasını saklar

Tüm parametrelerin yanı glVertexAttribPointersıra çağrı sırasında Vertex_Array_buffer öğesine bağlı tampon ve Element_Array_buffer öğesine glVertexAttribPointerbağlı.

Üniformalar mevcut programın bir parçasıdır.

Geriye kalan her şey küresel devlettir.

Kuşkusuz, kullandığınız sürümün özelliklerinde durum tablolarını kontrol edebilirsiniz.


Cevabınız için teşekkürler! Bu benim için işleri temizler.
Jelle van Campen

4

İşte basit ama etkili bir açıklama, temel olarak bir tampon nesnesi sadece basit ham veri bitleri olarak yorumlanabilen bilgilere sahiptir, bu da kendi başına hiçbir şey ifade etmez, bu yüzden PURELY gerçekten herhangi bir şekilde bakılabilen verilerdir

i.e float vbo[]={1.0,2.0,34.0...}

ve OpenGL'nin çalışması için tasarlanan yol, çeşitli gölgelendiricilere geçmenin gölgelendiricilere benzeyeceği verileri tanımlamanız gerektiğidir.

bu verilerin aynı zamanda nasıl okunacağını, hangi formatta olduğunu ve bununla ne yapılacağını ve bunun nasıl kullanılacağını ve bunun için VAO'da ne saklanacağını tanımlamanız gerekir.

örneğin, böyle bir dizide depolanan verileri bildirebilirsiniz. float vbo = {11.0,2.0,3.0,4.0}

Bu noktada gerekli olan şey, VAO’daki VBO’dan bu verilerin nasıl yorumlanacağı ve bunun ne anlama geldiğidir.

VAO, köşe başına 2 float okuyacak şekilde ayarlanabilir (bu, iki boyutlu x, y ile 2 vektör yapar) veya vao'ya 4 boyutlu yani 1, x, y, z, vb. gibi 1 vektör olarak yorumlamasını söyleyebilirsiniz.

aynı zamanda, veri formatı gibi VAO'da tanımlanmış ve saklanmış diğer nitelikler de vardır (bir float dizisi bildirmiş olmanıza rağmen, gölgelendiriciye bir tam sayı olarak okumasını söyleyebilirsiniz, elbette ki ham verileri dönüştürmek float'tan tamsayıya kadar olan süreç ve bu gibi durumlarda ne yapılacağı konusunda kendi kuralları vardır.

Bu nedenle, temelde VBO veridir ve VAO bu verileri nasıl yorumlayacağını saklar; koymak

Tabii ki aslında meraklı değil, aslında en verimli görünüyor, çünkü bu verileri grafik sunucusu hafızasına kaydetmesi gerekiyor, böylece en verimli ve en hızlı işlemi alıyor (eğer bunu yapması gerekmediğine karar vermediği sürece) Veriler bu şekilde işlenmemeli ve sıklıkla erişilmeyen bazı diğer bilgiler için kullanılmamalıdır) ve bu nedenle verilerle ne yapılacağına ve bunun nasıl işleneceğine ilişkin ayrıntıların VAO'da depolanması gerektiği, VAO bir başlık gibidir ve VBO, başlığın kullandığı ve tanımladığı saf ham veriler gibidir (bu durumda gölgelendirici tepe özelliklerine geçer), ancak VBO'nun yalnızca bir VAO tarafından kullanılması ile sınırlı olmamak koşuluyla, örneğin, birçok VAO'ya kullanılabilir ve yeniden kullanılabilir ve bunlara bağlanabilir:

yapabileceğiniz şey, bir tampon nesnesini VAO1'e bağlayabilir ve ayrıca (ayrı olarak) aynı tampon nesnesini VAO2'ye her biri farklı yorumlayarak bağlayabilir, böylece gölgelendiriciniz verileri nerede işleyeceğinize bağlı olarak buna bağlı olarak aynı ham veriyi çerçeveye göre farklı bir şekilde işleyecekti (pencereye piksel çizerek), aynı verilerin VAO'da kullanımını nasıl tanımladığınıza bağlı olarak farklı gösterilmesine neden olacaktı.


Bu en iyi cevap!
CodingMadeEasy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.