2014-10-03 9 views
6

Załóżmy, że mam 5 obiektów (obiektów) przy użyciu metody Render(). Każda jednostka musi ustawić własne wierzchołki w buforze do renderowania.Jeden duży bufor wierzchołkowy OpenGL, lub wiele małych?

Która z dwóch poniższych opcji jest lepsza?

  1. Zastosowanie jeden wielki wstępnie przyznane bufor stworzony z glGenBuffer, które każdy podmiot będzie stosowanie (ID bufora przekazanego jako argument Render metody), pisząc swoje wierzchołki do bufora z glBufferSubData.
  2. Każda jednostka tworzy i używa własnego bufora.

Jeśli jeden duży bufor jest lepszy, w jaki sposób mogę poprawnie renderować wszystkie wierzchołki w tym buforze (ze wszystkich elementów) za pomocą odpowiednich shaderów i wszystkiego?

Odpowiedz

1

Łatwiej jest użyć jednego VBO (Vertex Buffer Object) z glGenBuffer dla każdej istoty, którą posiadasz, ale nie zawsze jest to najlepsze rozwiązanie, zależy to od użycia. Jednak w większości przypadków nie ma problemu z 1 VBO dla każdej jednostki, a renderowanie jest rzadko dotknięte.

Dobry informacji znajduje się pod adresem: OpenGL Vertex Specification Best Practices

8

Posiadanie wielu VBOs jest w porządku tak długo, jak mają pewną wielkość. To, czego chcesz uniknąć, to mieć dużo małych przyciągań i często wiązać różne bufory.

To, jak duże muszą być bufory, aby uniknąć nadmiernego obciążenia, zależy od tak wielu czynników, że prawie niemożliwe jest nawet podanie reguły. Czynniki, które wchodzą w grę obejmują:

  • Charakterystyka wydajności sprzętu.
  • Efektywność kierowcy.
  • Liczba wierzchołków w stosunku do liczby fragmentów (rozmiar trójkąta).
  • Złożoność modułów cieniujących.

Ogólnie rzecz biorąc, sensowne może być utrzymywanie podobnych/powiązanych obiektów, które zwykle rysujesz w tym samym czasie w pojedynczym buforze wierzchołków.

Umieszczenie wszystkiego w jednym buforze wydaje się ekstremalne i może w rzeczywistości mieć negatywne skutki. Załóżmy, że masz duży "świat", w którym renderujesz tylko mały podzbiór w dowolnej ramce. Jeśli przejdziesz do skrajności, a wszystkie wierzchołki znajdują się w jednym gigantycznym buforze, bufor musi być dostępny dla GPU dla każdego wywołania losowania. W zależności od architektury, jak i bufor jest alokowana, może to oznaczać:

  • Próbując zachować bufor pamięci w dedykowanym GPU (np VRAM), co może być problematyczne, jeśli jest zbyt duża.
  • Mapowanie pamięci w przestrzeni adresowej GPU.
  • Przypinanie/podłączanie pamięci.

Jeśli którykolwiek z powyższych musi być zastosowany do bardzo dużego bufora, ale kończy się używanie tylko niewielkiej jego części do renderowania ramki, to w tych operacjach występuje znaczny odpad. W systemie z pamięcią VRAM może to również uniemożliwić inne przydziały, takie jak tekstury, aby pasowały do ​​VRAM.

Jeśli renderowanie jest wykonywane z połączeniami, które mają dostęp tylko do podzbioru bufora określonego przez argumenty, np. glDrawArrays() lub glDrawRangeElements(), możliwe, że sterownik nie będzie mógł udostępnić całego GPU bufora. Ale nie koniecznie liczyłbym na to.

+0

W porządku, utworzę małe bufory dla różnych rzeczy na scenie, takich jak: środowisko, obiekty statyczne, obiekty dynamiczne. Używając uboju załaduję do buforów tylko wymagane obiekty. Ale jak mogę go narysować za pomocą odpowiednich shaderów? Muszę narysować te obiekty jeden po drugim (sprawdzić, czy obiekt jest widoczny, załadować obiekt do bufora, sprawdzić, czy coś się zmieniło/zmienić dane w buforze, powiązać bufor, użyć shaderów, narysować zakres z bufora, odłączyć), czy też jest sposób czy mogę narysować wszystko na raz? – nullable

Powiązane problemy