Her glDraw * bir çizim çağrısıdır.
1 glDrawArrays 1 çizim çağrısıdır.
1 glDrawElements 1 çizim çağrısıdır.
Kaç tane köşe veya indeks kullandığınız önemli değil (çizim çağrısı sayısı söz konusu olduğunda), 1 glDraw * 1 çizim çağrısıdır.
Dörtlü çizim basit örnekleri (kullandığınız GL sürümünün dörtlü kaldırılmadığını varsayarak) veya üçgenler bunları karşılaştırmak için iyi bir örnek değildir, çünkü dörtlü bir liste veya üçgen listesi tek bir çağrı ile de çizilebilir, ve glDrawArrays ek dizine ek yükü olmadığından daha verimli görünecektir.
Biraz daha karmaşık bir durumu ele alalım, ancak daha gerçek bir dünya senaryosunu temsil eden bir davaya bakalım. Birden çok üçgen şerit ve fandan oluşan bir modeliniz olduğunu düşünün:
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
Bu örnekte glDrawArrays kullanmak, model için toplam 6 çizim çağrısı verir. Bununla birlikte, hem şeritler hem de fanlar kolayca dizinlenmiş üçgenlere dönüştürülebilir, bu nedenle indeksler ekleyin ve olur:
glDrawElements (GL_TRIANGLES, .....);
Bu, tüm model için bir beraberlik çağrısı.
GlDrawElements'in glDrawArrays'e göre avantajları, bellek tasarrufundan daha fazlasıdır, bu da onu ölçmenin naif yoludur. Köşelerin yeniden kullanılabileceği yerlerde bellek tasarrufu potansiyeli vardır , çünkü bir dizin tipik olarak bir tepe noktasından daha küçüktür (bu nedenle dengede çok sayıda endeksiniz olsa bile bunlar daha küçük olacaktır), ancak diğer avantajlar şunları içerir:
Azaltılmış çekiliş sayısı. Her çizim çağrısı, durumun doğrulanması, bir şeylerin ayarlanması vb. Gibi bazı ek yüklere neden olur ve bu ek yükün çoğu CPU tarafında olur. Çekiliş çağrılarının sayısını azaltarak bu ek yükün çoğunu önleriz.
Köşe yeniden kullanımı. Bu sadece bellek tasarrufundan çok daha fazlası. GPU'nuzun muhtemelen yakın zamanda dönüştürülmüş köşelerin depolanabileceği bir donanım tepe önbelleği vardır; aynı tepe noktası tekrar gelirse ve önbellekte bulunuyorsa, yeniden dönüştürmek yerine önbellekten yeniden kullanılabilir. Donanımınız dizinleri karşılaştırarak önbelleği kontrol edecektir, bu nedenle OpenGL terimlerinde önbelleği kullanmanın tek yolu glDrawElements kullanmaktır.
Belirli sorularınızı cevaplamak için:
glDrawElements beraberlik çağrılarını nasıl kaydedebilir ...? Kullandığınız örnekte öyle değil. Her birinin bir çizim çağrısı vardır. Yukarıda tartıştığım gibi, bu örnek ikisini karşılaştırmak için çok kötü bir örnek.
glDrawElements kullanmak nasıl yer tasarrufu sağlar? Çünkü endeksler köşe noktalarından daha küçüktür. 16 bitlik bir dizin iki bayttır, bir konum / renk / texcoord tepe noktası 24 bayttır. 6 köşe 144 bayt, 4 köşe artı 6 endeks 108 bayttır.
2 üçgenden bir kare çizilmesi durumunda ...? Bir ve bir. GlDraw * çağrısı bir çizim çağrısıdır, kullanılan köşe veya dizin sayısı bu ölçüm için önemsizdir. Ama yeniden vurgulamalıyım, bu ikisini karşılaştırmak için çok kötü bir örnek.
Son olarak, ve sadece sorunları biraz karmaşıklaştırmak için, üçgenli glDrawElements masaüstü GPU'larında en uygun yoldur, mobilde ise çok farklı olabilir. Bazı mobil GPU'lar GL_TRIANGLE_STRIP ile glDrawArrays'i tercih edebilir (bu durumda ilkelleri birleştirmek için dejenere üçgenler eklersiniz) ve ilkel yeniden başlatma veya çoklu çizim gibi daha gelişmiş konulara bile dokunmadım.