Büyük köşe arabelleği ve çoklu çizim aramaları


14

OpenGL ile yeni başlıyorum ve bunu 2D oyun oluşturmak için kullanmaya çalışıyorum. Bu oyunda, çok çeşitli farklı renkli altıgenlerden oluşan altıgen bir ızgaram var. Yeni başlayan bir OpenGL programcısı olarak, bu tabloyu çizmenin iki yolunu görüyorum:

  1. Tek bir altıgen için verilerle bir köşe tamponu kullanarak, tekdüze bir ofset değeri kullanarak ve bir ızgara olana kadar aynı programı birçok kez çizmek için CPU üzerinde yineleme.
  2. Tüm altıgenleri tek bir çağrıda çizen, çok büyük, önceden hesaplanmış bir köşe tamponu oluşturma.

En etkili yöntem nedir? Bunu yapmanın daha iyi bir yolu var mı?


Önceden hesaplanmış köşe arabelleğinizin ekranı yalnızca bir altıgen kadar uzatması yeterlidir, daha sonra tam bir altıgene gidene kadar düzgün bir şekilde kaydırarak ve ardından "senaryodaki" renkler için olduğu gibi, GPU'daki 2B doku, tepe gölgelendiricisinde okuyun ve parça gölgelendiriciye düz olarak enterpolate edin.
MickLH

Geçişler genellikle bir işleme işleminin önceki bir işlemin sonuçlarına dayandığı bir duruma işaret eder. Bu soruda sorduğunuz şey aslında tek bir geçişteki çekiliş çağrılarının sayısını azaltmakla ilgilidir. Bilgiçlik duyduğunu biliyorum, ancak farkı anlamak çok önemlidir, aksi takdirde çok geçişli algoritmalar çok mantıklı olmaz;)
Andon M. Coleman

@ AndonM.Coleman Hmm, teşekkürler, grafik terminolojisine aşina değilim. Peki, bu durumda, bunu nasıl tarif ederdim? Birden fazla gölgelendirici / program çağrısı?
Alexis King

Sipariş bağımlılığı olmadığı için bunun tek geçişli bir algoritma olduğunu hemen söyleyebilirsiniz; bu altıgenleri istediğiniz sırayla çizebilir ve yine de aynı sonucu alabilirsiniz. OpenGL'ye bunları oluşturmak için gerekli verileri sağlamak için birden fazla çizim çağrısı alabilirsiniz , ancak hiçbir bağımlılık olmadığı için OpenGL hepsini paralel olarak çekmekte etkin bir şekilde serbesttir. Çok geçişli olsaydı , altıgen B çizilmeden önce altıgen A'nın sonucunu gerektirebilir ya da aynı altıgeni birden çok kez çizmeniz ve sonucu birleştirmeniz gerekebilir.
Andon M. Coleman

Yanıtlar:


9

Gerçekten böyle bir ızgara yapmanın birkaç yolu vardır.

En etkili yol örnekleme olacaktır. Bu şekilde altıgeninizi bir VBO'da sadece bir kez yaparsınız ve bunu yüz, bin veya milyon kez yaparsınız. Nokta 1'de söylediğin gibi üniformalı gölgelendiricileri kullanarak manuel olarak yapabilirsiniz, ancak bunun için yerleşik bir OpenGL işlevi de vardır. Bunun için glDrawElementsInstanced adresine bir göz atın .

Belirli bir miktarda örneklenmiş nesneden daha fazla çizim yaparsanız örnek oluşturmanın yalnızca diğer yöntemlerden daha hızlı olduğunu unutmayın. Örneğin, 300 çizim 1 büyük VBO kullanarak daha hızlı olabilir, ancak anlık oluşturma kullanırsanız 2 milyon çizim daha hızlı olabilir.

Anlık görüntü oluşturmayı kullanıyorsanız, Özellik Bölücüler'i kullanarak nesne başına veri gönderebilirsiniz . Sizin durumunuzda, konumu ve rengi göndermek istersiniz.

Anında oluşturma hakkında iyi bir öğretici: tıklayın

Gerçekten en iyi yol, her iki yöntemi de denemek ve 1 kare çizmek için gereken milisaniye miktarını kontrol etmektir. Bu şekilde her iki yolu da öğrenirsiniz, ki bu her zaman iyidir.

Ayrıca, anında oluşturmanın modern bir OpenGL işlevi olduğunu ve bunu kullanmak için gölgelendiriciler kullanmanız gerektiğini unutmayın. Ancak her zaman en baştan doğru şekilde öğrenmek en iyisidir.


2
Örnekleme her zaman en etkili olmak zorunda değildir; profillerini gördüğüm birçok uygulamada, örnekleme desteği uyumluluk için ele alındı, ancak birçok nesneyi tek tek çizmekten daha yavaştı (aslında, sürücüyü o şeyi yapan muhtemelen zayıf uygulanmış bir döngüdü). Bu bir seçenek ve iyi bir seçenek, ancak "en verimli" ile ilgili herhangi bir varsayımda bulunmadan önce hedef OS / donanım üzerinde profil oluşturmaya ve test etmeye dikkat edilmelidir.
Sean Middleditch

Kabul. Örneğin Windows / Linux ve Ati / nVidia'da farklı performanslar gördüm. Eklediğiniz için teşekkürler.
Basaa

1
Aslında. Tek bir vbo içinde (aynı alanı paylaşan) birden çok birleşik kafes çizerseniz. Hiçbir şekilde örnekleme daha hızlı olamazdı. Örnekleme ile ilgili sorun: köşeler paralel hesaplanmış çapraz örnek değildir. Sadece gpu / cpu / gpu senkronizasyonu / çizim çağrısını ortadan kaldırır. Bu nedenle, 1000 küre içeren bir tepe tamponu çizmek, donanım örneği ile 1000 küre çizmekten daha hızlıdır. (frustum kaldırma / nesne mesafesi detay optimizasyonu dahil değildir)
Jeroen van Langen

3

Yöntem 1 kodlamak daha basittir ve aynı anda çok fazla altıgen yanınızda olmadığı sürece iyi olacaktır. Tabağınıza aynı anda çok fazla karmaşıklık koymaktan kaçınmak için OpenGL'de yeni olduğunuz için buna bağlı kalmak isteyebilirsiniz.

Aynı anda çok sayıda altıgen (birkaç yüz veya binden fazla) görüntüleniyorsa, CPU'nun çok fazla bireysel çekiş yapmasını önlemek için daha düşük bir genel yöntem gerekir. Yöntem 2 bunun için işe yarayabilir veya daha da iyisi örneklemeyi kullanır. Örneklemenin yöntem 2'den daha hızlı olmasını veya kesinlikle daha kötü olmasını beklerim, çünkü yalnızca tüm örnekler için köşe verilerinin (çok daha büyük) arabelleğini değil, örnek başına veri arabelleğini güncellemeniz gerekir.

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.