OpenGL ES'de dörtlü çekmenin en hızlı yolu?


22

OpenGL ES 2.0 kullanıyorum. Çizilecek dörtlü bir demetim var, GL_QUADS kullanıyormuşum gibi dörtlü başına 4 köşeyi geçmek zorunda kalmayı çok isterdim, ancak temel olarak sadece bir çizim çizmenin en iyi yolunu bilmek istiyorum. ayrı dörtlü demet.

Şu ana kadar ne bulabildiğimi buldum: -GL_TRIANGLES (dörtte bir 6 köşe) -Genişe GL_TRIANGLE_STRIP (dörtte bir 6 köşe)

Bulduğum Olasılıklar: Dört şeridi sıfırlayan özel bir indeks değerine sahip -GL_TRIANGLE_STRIPS (bu dörtlü başına 5 indeks anlamına gelir, ancak bunun OpenGL ES 2.0 olduğunu sanmıyorum)

Yanıtlar:


33

Sadece indeks tamponu ve GL_TRIANGLES kullanın. Bu durumda, dört köşeye + 4 endeks gerekebilir (6 ek endeks daha geniş olabilir. Ama gerçekte değildir - endeks tamponunuzu oluşturduktan sonra tekrar dokunmanız gerekmez). Daha fazla bilgi için bu sayfaya bakın (glDrawElements için arama yapın)

Basit örnek kod:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Ayrıca, sadece bir dörtlü çiziyorsanız, üçgen şeritler ( wikipedia'da gösterildiği gibi ) çizmek için sadece 4 köşeye ihtiyacınız var ama sanırım bunu zaten biliyordunuz.


Birden fazla üçgen şeridi tek bir şeride birleştirmenin geleneksel hilesi "dejenere üçgenler" dir: Bir şeridin son elemanını ve bir sonraki şeridin ilk elemanını tekrarlamak, sıfır alanlı 2 üçgen yaratır, böylece hiçbir şey çizmez. İkinci dörtlü endeksleri göz önünde bulundurun (4, 5, 6, 7). İki dörtlünün GL_TRIANGLE_STRIP'i için indeks tamponu şunlar olabilir: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Dejenere üçgenler 3,3,4ve 3,4,4. Bunu yapmaya değer mi? Hayır, dörtlüleriniz ortak kenarlara sahip çiftler halinde (veya daha fazla) gelmedikçe. 2. kadran {3, 2, 4, 5} ise, şerit de öyledir {0,1,3,2,5,4}.
ToolmakerSteve

8
Bunu ortaya çıkaran ve bir grup dörtlü çizmesi gerekenlere netleştirmek için: Performans uğruna , yukarıdaki kodu ÇIKARMAYIN ve bir glDrawElements yapmak ONCE FOR EACH QUAD . Bunun yerine, BİR vertices dizisi ve çizmek istediğiniz TÜM dörtlüleri içeren BİR dizin dizisi oluşturun . GL_TRIANGLES kullanarak, iki dörtlü endekslere sahip olabilir {0,1,2, 0,2,3, 4,5,6, 4,6,7}veya eşit derecede iyi olabilir {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Bu yardım etmek iyi sınıftır glText-Android / SpriteBatch
ToolmakerSteve

6

Dizin arabelleklerini kullanmak , Apple belgelerinde belirtildiği gibi, mutlaka zorunlu değildir , "En iyi performans için, modelleriniz glDrawArrays kullanılarak tek bir katlanmamış üçgen şerit olarak gönderilmelidir" .

Bir süre Yani, GL_TRIANGLE_STRIPbir indeks tampon gerek kalmadan 4 köşeler bunu yapacak ve yapabilirsiniz endeks tampon kullanmak, bu tekrarlanan "save" denemek için oldukça topal 2 köşe . Bu nedenle, 2 ayrı çizmenizi GL_TRIANGLESve köşegen üzerindeki 2 köşeyi tekrarlamanızı öneririm .


8
Um, hayır. Bu dokümanın söylediği şey, modellerinizin tek bir INDEXED üçgen şeridi olarak sunulmasıdır. Ve bir sonraki cümle, "Aynı köşe için vertex arabelleğinde defalarca veri belirtmekten kaçınmak için, ayrı bir dizin arabelleği kullanın ve glDrawElements işlevini kullanarak üçgen şeridi çizin". Tam olarak karar verdiğin şey 'topal' dı.
davidf2281

3
Şimdi doc paragrafının glDrawArrays yerine glDrawElements anlamına geldiği göz önüne alındığında, muhtemelen bu cevaptan bu yana yeniden yazılmıştır. Bununla birlikte, doktorun yaptığı nokta, performans için, tek bir şerit sağlamaktı (çoklu şeritler yerine çoklu gl çağrıları). Bu durumda, endeks kullanmanın veya kullanmama arasındaki farkın önemsiz olduğuna inanıyorum ; önemli olan, her şeyi tek bir köşe dizisine (artı isteğe bağlı bir dizin dizisine) almaktır, böylece tek bir gl çağrısı yapabilirsiniz.
ToolmakerSteve

0

Masaüstündeki en büyük kazanç, verileri GL_STATIC_DRAW VBO'lara taşımaktır. Muhtemelen bu, iPhone'un MBX GPU'sunda da geçerlidir.


-2

Kullanımı GL_TRIANGLE_FANbir dörtlü için 4 köşe değil, 6 kullanır.


Evet, fakat GL_TRIANGLE_STRIPdiğer cevapların da işaret ettiği gibi.
Anko

@Bay. Blah - Sorunun noktasını özledin, bu da bir sürü dörtlü verimli bir şekilde nasıl yapılır . Kişi her dörtlü için bir gl çağrısı yapmamalı, aksine çok sayıda dörtlü tek bir dizide tek bir gl çağrısı ile çizilebilmeli. GL_TRIANGLE_FAN bu konuda yardımcı olmaz, bu yüzden yüksek performanslı görüntülemede nadiren kullanışlıdır.
ToolmakerSteve
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.