Najszybszy sposób rysowania quadów w OpenGL ES?

22

Korzystam z OpenGL ES 2.0 Mam kilka quadów do narysowania, chciałbym móc przejść tylko 4 wierzchołki na quad, tak jakbym korzystał z GL_QUADS, ale w zasadzie chcę po prostu poznać najlepszy sposób rysowania kilka osobnych quadów.

Do tej pory mogłem to zrobić: -GL_TRIANGLES (6 wierzchołków na quad) -Degeneracja GL_TRIANGLE_STRIP (6 wierzchołków na quad)

Znalazłem możliwości: -GL_TRIANGLE_STRIPS ze specjalną wartością indeksu, która resetuje pasek quad (oznaczałoby to 5 indeksów na quad, ale nie sądzę, że jest to możliwe, OpenGL ES 2.0)

Jonathan
źródło

Odpowiedzi:

33

Wystarczy użyć bufora indeksu i GL_TRIANGLES. W takim przypadku potrzebujesz 4 wierzchołków + 6 indeksów na quad (6 dodatkowych indeksów może brzmieć z dużym nakładem, ale w rzeczywistości tak nie jest - po zbudowaniu bufora indeksu nie musisz go ponownie dotykać). Zobacz tę stronę, aby uzyskać więcej informacji (wyszukaj glDrawElements)

Prosty przykładowy 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);

Ponadto, jeśli rysujesz tylko jeden quad, potrzebujesz tylko 4 wierzchołków, aby narysować go trójkątnymi paskami ( jak pokazano na wikipedii ), ale chyba już o tym wiedziałeś.

użytkownik4241
źródło
Tradycyjna sztuczka polegająca na łączeniu wielu pasków trójkąta w jeden pasek to „zdegenerowane trójkąty”: Powtarzanie ostatniego elementu jednego paska i pierwszego elementu następnego paska tworzy 2 trójkąty o zerowym obszarze, które w ten sposób niczego nie rysują. Rozważ wskaźniki drugiego kwadratu (4, 5, 6, 7). Bufor indeksu dla GL_TRIANGLE_STRIP dwóch quadów może wynosić: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Zdegenerowane trójkąty to 3,3,4i 3,4,4. Czy warto to robić? Nie, chyba że twoje quady mają tendencję do parowania (lub więcej) ze wspólnymi krawędziami. Jeśli 2-ty kwadrant to {3, 2, 4, 5}, to pasek jest {0,1,3,2,5,4}.
ToolmakerSteve
8
I aby było to jasne dla każdego, kto przyjdzie i musi narysować kilka quadów: Ze względu na wydajność NIE kopiuj powyższego kodu i spraw, aby glDrawElements zadzwonił RAZ NA KAŻDY KWADRAT . Zamiast tego zbuduj JEDNĄ tablicę wierzchołków i JEDNĄ tablicę indeksów, która zawiera WSZYSTKIE quady, które chcesz narysować. Używając GL_TRIANGLES, dwa kwadraty mogą mieć indeksy {0,1,2, 0,2,3, 4,5,6, 4,6,7}lub równie dobry jest {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Dobra klasa, która może to pomóc, to glText-Android / SpriteBatch
ToolmakerSteve
6

Korzystanie z buforów indeksu niekoniecznie jest szybsze, jak wskazano w dokumentach Apple: „Aby uzyskać najlepszą wydajność, modele należy przesyłać jako pojedynczy nieindeksowany pasek trójkąta za pomocą glDrawArrays” .

Tak więc, podczas gdy a GL_TRIANGLE_STRIPzrobi to w 4 wierzchołkach bez potrzeby buforowania indeksu, a ty możesz użyć bufora indeksu, dość kiepskie jest próbowanie „zapisania” powtarzania 2 wierzchołków . Z tego powodu sugeruję narysowanie 2 osobnych GL_TRIANGLESi powtórzenie 2 wierzchołków na przekątnej .

Bobobobo
źródło
8
Yyy ... nie. Dokument ten mówi, że twoje modele należy przesłać jako pojedynczy pasek trójkąta INDEKSOWANEGO. Kolejne zdanie brzmi: „Aby uniknąć wielokrotnego podawania danych dla tego samego wierzchołka w buforze wierzchołków, użyj osobnego bufora indeksu i narysuj pasek trójkąta za pomocą funkcji glDrawElements”. Dokładnie to, co postanowiłeś, było „kulawe”.
davidf2281
3
Biorąc pod uwagę, że akapit doc odnosi się teraz do glDrawElements zamiast glDrawArrays, prawdopodobnie został przepisany od tej odpowiedzi. Niemniej dokument miał na myśli to, że w celu zapewnienia wydajności należy dostarczyć jeden pasek (zamiast wielu pasków, stąd wiele wywołań gl). W tej sytuacji uważam, że różnica między używaniem indeksów lub nie jest nieznaczna ; ważne jest umieszczenie wszystkiego w jednej tablicy wierzchołków (plus opcjonalnej tablicy indeksów), aby można było wykonać pojedyncze wywołanie gl.
ToolmakerSteve
0

Dużym zyskiem na pulpicie jest przeniesienie danych do VBO GL_STATIC_DRAW. Przypuszczalnie dotyczy to również GPU MBX iPhone'a.

Wola
źródło
-2

Korzystanie GL_TRIANGLE_FANz quada używa 4 wierzchołków, a nie 6.

Pan Blah
źródło
Tak, ale tak jest GL_TRIANGLE_STRIP, jak już wskazały inne odpowiedzi.
Anko
@Pan. Blah - Nie trafiłeś w sedno pytania, które polega na tym, jak skutecznie wykonać kilka quadów. Nie należy wykonywać wywołania gl dla każdego kwadratu, ale raczej połączyć wiele quadów w jedną tablicę, którą można narysować za pomocą pojedynczego wywołania gl. GL_TRIANGLE_FAN nie pomoże w tym, dlatego rzadko jest przydatny w renderowaniu o wysokiej wydajności.
ToolmakerSteve