OpenGL: VBO czy glBegin () + glEnd ()?

16

Niedawno otrzymałem ten link do strony z samouczkiem od kogoś, komu dałem oryginalną książkę OGL Redbook. Trzeci nagłówek mówi wyraźnie, aby zapomnieć o glBegin () i glEnd () jako typowej metodzie renderowania. Nauczyłem się metodą Redbook, ale widzę pewne korzyści w VBO. Czy to naprawdę jest właściwy sposób, a jeśli tak, to czy istnieje sposób na łatwą konwersję kodu renderowania i kolejnych shaderów na VBO i kolejne typy danych?

S. Fitzgerald
źródło

Odpowiedzi:

27

Współczesne VBO OpenGL są na dobrej drodze, rzeczy o ustalonej funkcji (w tym glBegin / glEnd i rzeczy pomiędzy nimi) są przestarzałe od 3.0 i usunięte od 3.1.

Dzięki profilowi ​​OpenGL Core, OpenGL ES 2.0+ i WebGL nie masz nawet dostępu do starych rzeczy.

Niektórzy uważają, że najpierw nauka starych rzeczy jest lepsza, ponieważ jest to trochę łatwiejsze, ale rzeczy, których się uczysz, są w większości bezużyteczne, a następnie rzeczy, których musisz się oduczyć.

Ale to nie tylko VBO, musisz używać shaderów do wszystkiego i samemu przekształcać macierze (lub używać GLM).

Jedynym powodem, aby użyć starych rzeczy, byłoby, gdybyś chciał wycelować w OpenGL przed wersją 2.0. który został wydany ponownie w 2003 roku. Istnieje kilka naprawdę kiepskich wbudowanych chipsetów netbooków, które mają 1,5, ale nawet 1,5 powinno obsługiwać VBO, a nie shadery. Lub OpenGL ES 1.x, który jest oparty na potoku stałej funkcji (na przykład jest używany na starszych iPhone'ach). Lub OpenGL SC (dla systemów krytycznych dla bezpieczeństwa).

Następujące często używane funkcje są przestarzałe:

  • glBegin
  • glEnd
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

opengl-tutorial.org tutoriale mieć co myślę, jest najlepszym sposobem, aby przejść o naukę OpenGL. Opierają się na niektórych starszych kompatybilnych materiałach, ale tak naprawdę nie uczą tego. Na przykład nie powinieneś renderować niczego bez shadera, ale działa. Musisz samodzielnie obsługiwać operacje na macierzach (obracanie, tłumaczenie itp.), Ale domyślnie otrzymasz podstawową płaską rzutnię 2D.

Oprócz unikania przestarzałych rzeczy istnieje wiele funkcji, które sprawiają, że kodowanie OpenGL jest znacznie przyjemniejsze, ale przy wielu z nich musisz zdecydować, czy jesteś w porządku, wymagając nowszych wersji OpenGL 3.x + i kompatybilnego sprzętu.

W poście, który tu napisałem, jest więcej informacji .

Jeśli z jakiegoś powodu potrzebujesz obsługi starszego OpenGL, możesz używać VBO, gdy jest to możliwe, a kiedy nie jest, zapewnij rezerwację, która używa glBegin / glEnd i zapętla dane w wierzchołku.

Z drugiej strony nie ma prawdziwego „łatwego” sposobu na konwersję starego kodu renderowania. Być może możesz zaimplementować własną wersję funkcji, które dodają wierzchołki do tablicy / wektora, który następnie zrzuca go do VBO i rysuje po wywołaniu fałszywego glEnd. ale byłoby to bardzo nieefektywne, ponieważ robiłoby to każdą klatkę (chyba że zaznaczysz pole wyboru, aby zrobić to tylko raz, ale to nie działa dla animowanych obiektów) i prawdopodobnie byłoby więcej pracy niż przejście na VBO. Podejrzewam, że jeśli masz dużo kodu, to podejście może działać.

David C. Bishop
źródło
7

Dzięki VBO generalnie masz dwie główne zalety.

Zaleta 1 dotyczy danych w pełni statycznych i wynika z możliwości przechowywania danych wierzchołków w pamięci, która jest bardziej optymalna dla GPU.

Zaleta 2 dotyczy danych dynamicznych i wynika z możliwości określenia danych wierzchołków w dowolnym momencie przed użyciem ich do renderowania, co może lepiej potokować.

Trzecia korzyść wynika z grupowania połączeń losowanych, ale jest również dzielona z oldschoolowymi tablicami wierzchołków, więc nie nazywam tego specjalnie dla VBO. Wysyłanie danych do GPU (lub używanie danych już na GPU) jest pod wieloma względami podobne do dyskowych operacji we / wy i ruchu sieciowego - jeśli masz kilka dużych partii, jest to bardziej wydajne niż wiele małych partii.

Dobra (nie w 100% dokładna, ale wystarczająca, aby pomóc Ci zrozumieć) analogia jest taka, jeśli jesteś kierowcą autobusu, który musi przewozić 50 osób z jednego miasta do drugiego. Możesz je ładować pojedynczo i wykonywać 50 osobnych podróży - to glBegin / glEnd. Alternatywnie możesz umieścić wszystkie 50 z nich w autobusie i zrobić tylko jedną podróż - to wsadowe z tablicami wierzchołków lub VBO (w przypadku VBO 50 osób już by było w autobusie;)).

Ma to jednak swoją cenę, a tutaj cena polega na tym, że tracisz możliwość określania danych wierzchołków, kiedy i kiedy ich potrzebujesz. Cóż, OK, możesz to zrobić (przy dodatkowej pracy), ale nie uzyskasz pełnej wydajności kodu. Zamiast tego musisz pomyśleć więcej o swoich danych wierzchołków, sposobie ich wykorzystania, sposobie (i jeśli) należy je zaktualizować, czy animacje można wykonać w module cieniującym (dzięki czemu dane pozostają statyczne - VBO naprawdę potrzebują shaderów do wiele przypadków animacji, aby działały dobrze) lub czy trzeba ponownie określać dane wierzchołków w każdej ramce, wydajne strategie aktualizacji, jeśli ta ostatnia itp. Jeśli tego nie zrobisz i po prostu wdrożysz naiwną konwersję, masz bardzo duże ryzyko wprowadzenia w dużo pracy tylko po to, by efekt końcowy działał wolniej!

To może wydawać się okropnie dużo pracy, kiedy ją spotkasz, ale tak naprawdę nie jest. Gdy przejdziesz do takiego sposobu myślenia, w rzeczywistości przekonasz się, że jest to niezwykle łatwe i prawie przychodzi naturalnie. Ale możesz zepsuć kilka pierwszych prób i nie powinieneś się zniechęcać, jeśli tak - zepsucie to okazja, aby dowiedzieć się z tego, co popełniłeś źle.

Kilka ostatnich myśli.

Posiadanie danych modelu w formacie, który można łatwo załadować do VBO, może znacznie ułatwić ci cały proces. Oznacza to, że powinieneś unikać bardziej złożonych lub egzotycznych formatów, przynajmniej na początku (i dopóki nie poczujesz się bardziej komfortowo z tym procesem); staraj się zachować jak najprostszą i podstawową wiedzę podczas nauki, a będzie mniej rzeczy do zrobienia i mniej miejsc do szukania błędów, jeśli (lub kiedy!) coś pójdzie nie tak.

Ludzie są czasem zniechęcani, jeśli widzą implementację VBO używającą więcej pamięci niż zoptymalizowana / skompresowana implementacja glBegin / glEnd (mogą nawet nazywać to „marnotrawstwem”). Nie bądź taki. Z wyjątkiem skrajnych przypadkach zużycie pamięci nie jest to , że ważne. Jest to wyraźny kompromis - akceptujesz potencjalnie wyższe wykorzystanie pamięci w zamian za znacznie wyższą wydajność. Pomaga również rozwinąć sposób myślenia, że ​​pamięć jest tanim i bogatym zasobem, który można wykorzystać; wydajność nie jest.

I wreszcie stary kasztan - jeśli jest już wystarczająco szybki, to twoja praca jest skończona. Jeśli osiągasz docelową liczbę klatek na sekundę, jeśli masz dość miejsca na przejściowe warunki, jest to wystarczająco dobre i możesz przejść do następnego kroku. Możesz zmarnować dużo czasu i energii, wyciskając dodatkowe 10% z czegoś, czego tak naprawdę nie potrzebuje (byłeś tam, zrobiłem to, wciąż wpadam w pułapkę), więc zawsze zastanów się, jakie jest najbardziej optymalne wykorzystanie twojego czasu. - ponieważ czas programisty jest jeszcze mniej tani i mniej obfity niż wydajność!

Maximus Minimus
źródło