OpenGL gölgelendiricileri için açık ve Otomatik öznitelik konum bağlama


83

Bir OpenGL gölgelendirici programı için öznitelik konumlarını ayarlarken iki seçenekle karşılaşırsınız:

Bir öznitelik konumunu açıkça tanımlamak için bağlanmadan önce glBindAttribLocation () .

veya

Otomatik olarak atanan bir öznitelik konumu elde etmek için bağlandıktan sonra glGetAttribLocation () .

Birini diğerinin üzerinde kullanmak için yardımcı program nedir?

Pratikte varsa hangisi tercih edilir?


6
glBindAttribLocationLinux üzerinde iyi çalışan grafik motorumda kullanmakla uğraşmadım . Pencerelere taşındığımda, normallerimi köşe noktaları olarak kullanıyordu - glBindAttribLocationçalışması için gölgelendiricimdeki değişkenlerin sırasını açıkça söylemem gerekiyordu ...
Jarrett 18'13

Yanıtlar:


93

Açık konum tanımını tercih etmek için iyi bir neden biliyorum .

Geometri verilerinizi Vertex Array Objects içinde tuttuğunuzu düşünün . Belirli bir nesne için, endekslerin karşılık geleceği şekilde bir VAO oluşturursunuz, örneğin:

  • dizin 0 : pozisyonlar,
  • dizin 1 : normaller,
  • dizin 2 : texcoords

Şimdi iki farklı gölgelendiriciyle bir nesne çizmek istediğinizi düşünün . Bir gölgelendirici, girdi olarak konum ve normal verileri gerektirir ; diğerini - konumlar ve doku koordinatları .

Bu gölgelendiricileri derlerseniz, ilk gölgelendiricinin konumları öznitelik endeksi 0'da ve normalleri 1'de bekleyeceğini fark edeceksiniz. Diğeri konumları 0'da ancak doku koordinatları 1'de bekler.

Alıntı https://www.opengl.org/wiki/Vertex_Shader :

Otomatik Atama

Önceki iki yöntemden hiçbiri bir öznitelik indeksine bir girdi atamazsa, o zaman dizin, program bağlandığında OpenGL tarafından otomatik olarak atanır. Atanan dizin tamamen rastgeledir ve aynı köşe gölgelendirici kodunu kullansalar bile bağlantılı farklı programlar için farklı olabilir.

Bu , VAO'nuzu her iki gölgelendiriciyle de kullanamayacağınız anlamına gelir . Örneğin nesne başına bir VAO'ya sahip olmak yerine, en kötü durumda her gölgelendirici için nesne başına ayrı bir VAO'ya ihtiyacınız olacaktır .

Gölgelendiricileri kendi öznitelik numaralandırma kuralınızı kullanmaya zorlamak, glBindAttribLocationbu sorunu kolayca çözebilir - yapmanız gereken tek şey, öznitelikler ve sabitlenmiş kimlikleri arasında tutarlı bir ilişki sürdürmek ve gölgelendiricileri bağlantı sırasında bu kuralı kullanmaya zorlamaktır.

(Ayrı VAO'lar kullanmıyorsanız bu gerçekten büyük bir sorun değil, ancak yine de kodunuzu daha net hale getirebilir.)


BTW:

Bir OpenGL gölgelendirici programı için öznitelik konumlarını ayarlarken iki seçenekle karşılaşırsınız

OpenGL / GLSL 3.3'te üçüncü bir seçenek vardır: Konumu doğrudan gölgelendirici kodunda belirtin . Şöyle görünüyor:

layout(location=0) in vec4 position;

Ancak bu, GLSL ES gölgelendirici dilinde mevcut değildir.


1
Asıl noktayı görmüyorum. VAO gerçekten hafiftir ve genellikle bunları her kare için yeniden oluşturursunuz. Sizin durumunuzda, her gölgelendiriciyi aramadan önce farklı VAO'lar oluşturursunuz, değil mi?
PierreBdR

1
Evet, bunu elbette yapabilirsiniz. Aynı şekilde çalışacak, burada sadece konvansiyonları tartışıyoruz. :)
Kos

4
Üçüncü seçenek aslında GLES2.0'da mevcuttur, ancak biçim biraz farklıdır: layout (location = 0) özelliği vec4 konumu; Buna GLSL dosyanızın en üstünde de ihtiyacınız olacağını unutmayın: #extension GL_EXT_separate_shader_objects: enable
Gavin Maclean

35
"VAO gerçekten hafiftir ve genellikle bunları her çerçeve için yeniden oluşturursunuz. Sizin durumunuzda, her gölgelendiriciyi aramadan önce farklı VAO'lar oluşturursunuz, değil mi?" - Hayır, genellikle bunu yapmazsınız çünkü bu, sonunda VAO'ların tüm amacını tamamen geçersiz kılar. O halde neden bir VAO kullanıyorsunuz?
Christian Rau

2
Sadece bir not. Geometri verilerinizi bir VAO'da tutamazsınız. Bu bir VBO'da olurdu. VAO'ların veri depolama alanı yoktur.
ortalama joe

20

Buradaki başka bir cevap da glGetAttribLocation'ın çağırana veri döndürmesidir, bu da dolaylı olarak bir ardışık düzen temizliği gerektirdiği anlamına gelir. Programınızı derledikten hemen sonra çağırırsanız, esasen zaman uyumsuz derlemeyi eşzamanlı olarak gerçekleşmeye zorluyorsunuz demektir.



Teşekkürler, bu çok önemli bir husustur.
Jing

1
Anladığım kadarıyla, çoğu durumda glGetUniformLocationyine de aramanız gerekecek; bu husus hala geçerli mi?
Mike Weir

@MikeWeir, GL 4.3'ten beri açık tekdüze konum ayarlayabilirsiniz .
Ruslan

1
@Ruslan OpenGL ES kullanıyorlar.
Mike Weir

9

Üçüncü seçenek, yani layout(location=0) in vec4 position;gölgelendirici kodundaki, artık OpenGL ES 3.0 / GLSL 300 es'de mevcuttur. Sadece köşe gölgelendiricisi giriş değişkenleri için.


7
İpucu verdikleri gibi, Intel kartları bunu desteklemeyebilir (anladığım kadarıyla mükemmel 3.0+ uyumlu olsa da), ki bu iğrenç :)
mlvljr
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.