Każdy glDraw * jest sprawdzeniem losowania.
1 glDrawArrays to 1 call draw.
1 glDrawElements to 1 call draw.
Nie ma znaczenia (jeśli chodzi o liczbę wywołań remisowych), ile wierzchołków lub indeksów używasz, 1 glDraw * to 1 call draw.
Proste przypadki rysowania quadów (zakładając, że używana wersja GL nie usunęła quadów) lub trójkątów, nie są dobrym przykładem na ich porównanie, ponieważ listę quadów lub listę trójkątów można narysować za pomocą jednego wywołania i glDrawArrays będą wydawać się bardziej wydajne, ponieważ nie mają dodatkowego obciążenia związanego z indeksowaniem.
Weźmy nieco bardziej złożony przypadek, ale taki, który reprezentuje bardziej realistyczny scenariusz. Wyobraź sobie, że masz model złożony z wielu trójkątnych pasków i wentylatorów:
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
W tym przykładzie użycie glDrawArrays daje w sumie 6 wywołań rysowania dla modelu. Jednak zarówno paski, jak i wentylatory można łatwo przekonwertować na indeksowane trójkąty, więc dodaj indeksy i będzie to:
glDrawElements (GL_TRIANGLES, .....);
To jedno losowanie dla całego modelu.
Zalety glDrawElements w porównaniu z glDrawArrays to coś więcej niż tylko oszczędność pamięci, co jest naiwnym sposobem pomiaru. Istnieje możliwość zaoszczędzenia pamięci, gdy wierzchołki mogą być ponownie użyte, ponieważ indeks jest zwykle mniejszy niż wierzchołek (więc nawet jeśli masz wiele wskaźników w równowadze, będą one mniejsze), ale inne zalety to:
Zmniejszona liczba połączeń losujących. Każde wywołanie losowania wiąże się z pewnym obciążeniem związanym z weryfikowaniem stanu, konfigurowaniem itp., A znaczna część tego obciążenia występuje po stronie procesora. Zmniejszając liczbę sprawdzanych połączeń, unikamy dużej części tego narzutu.
Ponowne użycie wierzchołków. To znacznie więcej niż tylko oszczędzanie pamięci. Twój procesor graficzny prawdopodobnie ma sprzętową pamięć podręczną wierzchołków, w której można przechowywać ostatnio przekształcone wierzchołki; jeśli ten sam wierzchołek pojawi się ponownie, a jeśli jest w pamięci podręcznej, można go ponownie użyć z pamięci podręcznej zamiast konieczności ponownej transformacji. Twój sprzęt sprawdzi pamięć podręczną, porównując indeksy, więc w kategoriach OpenGL jedynym sposobem korzystania z pamięci podręcznej jest użycie glDrawElements.
Aby odpowiedzieć na konkretne pytania:
w jaki sposób glDrawElements może zapisać połączenia losowania ...? W użytym przykładzie tak nie jest. Każdy ma jedno losowanie. Jak dyskutuję powyżej, ten przykład jest bardzo zły do porównania tych dwóch.
jak użycie glDrawElements oszczędza miejsce ...? Ponieważ indeksy są mniejsze niż wierzchołki. Indeks 16-bitowy to dwa bajty, a wierzchołek pozycji / koloru / texcoorda ma 24 bajty. 6 wierzchołków to 144 bajty, 4 wierzchołki plus 6 wskaźników to 108 bajtów.
W przypadku rysowania kwadratu z 2 trójkątów ...? Sam na sam. Wywołanie glDraw * to jedno wywołanie losowania, liczba użytych wierzchołków lub indeksów nie ma znaczenia dla tego pomiaru. Ale muszę ponownie podkreślić, to bardzo zły przykład na porównanie tych dwóch.
Wreszcie, aby nieco skomplikować sprawę, podczas gdy glDrawElements z trójkątami jest optymalną ścieżką na komputerowych procesorach graficznych, na urządzeniach mobilnych może być zupełnie inaczej. Niektóre mobilne układy GPU mogą preferować glDrawArrays z GL_TRIANGLE_STRIP (w tym przypadku dodamy zdegenerowane trójkąty do konkatenacji prymitywów), a nawet nie poruszyłem bardziej zaawansowanych tematów, takich jak prymitywne restartowanie lub wielokrotne losowanie.