Najbardziej poprawna odpowiedź brzmi: zależy to od tego, jak ją zaprogramujesz, ale warto się martwić. Chociaż procesory graficzne stały się niezwykle szybkie, przepustowość do i z RAM GPU nie jest i będzie twoim najbardziej frustrującym wąskim gardłem.
Czy dane są wysyłane do pamięci GPU tylko raz i pozostają tam na zawsze?
Mam nadzieję, że tak. Aby uzyskać szybkość renderowania, chcesz, aby jak najwięcej danych znajdowało się na GPU, zamiast przesyłać je co każdą klatkę. VBO służą właśnie temu celowi. Istnieją zarówno statyczne, jak i dynamiczne VBO, te pierwsze są najlepsze dla modeli statycznych, a drugie są najlepsze dla modeli, których wierzchołki zmienią każdą klatkę (powiedzmy układ cząstek). Jednak nawet jeśli chodzi o dynamiczne VBO, nie chcesz ponownie wysyłać wszystkich wierzchołków każdej klatki; tylko te, które się zmieniają.
W przypadku twojego budynku, dane wierzchołków po prostu by tam siedziały, a jedyną zmianą są twoje macierze (model / świat, rzut i widok).
W przypadku układu cząstek stworzyłem dynamiczne VBO wystarczająco duże, aby pomieścić maksymalną liczbę cząstek, jaka kiedykolwiek istniałaby dla tego układu. Do każdej ramki wysyłam dane dla cząstek emitowanych w tej ramce, wraz z kilkoma mundurami i to wszystko. Kiedy rysuję, mogę określić punkt początkowy i końcowy w tym VBO, więc nie muszę usuwać danych cząstek. Mogę tylko powiedzieć, że nie rysuj.
Kiedy model jest faktycznie renderowany w każdej ramce, czy procesory GPU muszą pobierać dane za każdym razem z pamięci GPU? Chodzi mi o to - gdybym miał 2 modele renderowane wiele razy każdy - czy miałoby to znaczenie, jeśli najpierw renderowałem pierwszy raz wiele razy, a następnie drugi raz wiele razy, czy też pierwszy raz renderowałem jeden raz, drugi raz jeden raz i przeplatałeś to w ten sposób?
Wysyłanie wielu losowań zamiast tylko jednego jest znacznie większym ograniczeniem. Sprawdź renderowanie instancji; może ci bardzo pomóc i uczynić odpowiedź na to pytanie bezużyteczną. Miałem pewne problemy ze sterownikami, których jeszcze nie opracowałem, ale jeśli możesz go uruchomić, problem został rozwiązany.
Oczywiście karty graficzne mają ograniczoną pamięć RAM - jeśli nie może pomieścić wszystkich danych modelu niezbędnych do renderowania 1 klatki, myślę, że pobiera (część) z pamięci RAM procesora każdej klatki, czy to prawda?
Nie chcesz zabraknąć RAM GPU. Jeśli to zrobisz, zmień rzeczy, abyś tego nie zrobił. W bardzo hipotetycznym scenariuszu, w którym się skończysz, prawdopodobnie jakoś się rozbije, ale nigdy tego nie widziałem, więc szczerze mówiąc nie wiem.
Zapomniałem zrobić jedno rozróżnienie: wysyłanie danych do GPU i ustawianie / wiązanie buforów jako bieżących. Czy to ostatnie powoduje przepływ danych?
Nie ma znaczącego przepływu danych, nie. Jest to trochę kosztowne, ale dotyczy to każdego wiersza kodu, który piszesz. Dowiedz się, ile to kosztuje, i po co jest profilowanie.
tworzenie bufora z inicjalizacją
Odpowiedź Raxvana brzmi dobrze, ale nie jest całkiem dokładna. W OpenGL utworzenie bufora nie rezerwuje miejsca. Jeśli chcesz zarezerwować miejsce bez przekazywania żadnych danych, możesz wywołać glBufferData i po prostu przekazać null. (Zobacz sekcję notatek tutaj .)
aktualizacja danych bufora
Zgaduję, że masz na myśli glBufferData lub inne podobne funkcje, prawda? To tam następuje prawdziwy transfer danych. (Chyba, że zdasz zero, jak właśnie powiedziałem w ostatnim akapicie).
powiązanie bufora jako aktywnego (czy to po prostu sposób, aby powiedzieć API, że chcę, aby ten bufor był renderowany w następnym wywołaniu losowania i sam nic nie robi?)
Tak, ale może zrobić coś więcej. Na przykład, jeśli powiążesz VAO (obiekt tablicy wierzchołków), a następnie powiążesz VBO, to VBO zostanie powiązane z VAO. Później, jeśli ponownie powiążesz ten VAO i wywołasz glDrawArrays, będzie wiedział, co VBO narysować.
Pamiętaj, że chociaż w wielu samouczkach utworzysz VAO dla każdego VBO, powiedziano mi, że nie jest to ich zamierzone zastosowanie. Podobno powinieneś stworzyć jedną VAO i używać jej z każdym VBO, który ma te same atrybuty. Jeszcze tego nie próbowałem, więc nie mogę powiedzieć na pewno, czy jest to lepsze czy gorsze.
Wywołanie losowania API
To, co się tutaj dzieje, jest dość proste (z naszej perspektywy). Załóżmy, że wiążesz VAO, a następnie wywołujesz glDrawArrays. Podajesz punkt początkowy i liczbę, a on uruchamia moduł cieniujący wierzchołki dla każdego wierzchołka w tym zakresie, który z kolei przekazuje swoje wyniki wzdłuż linii. Cały ten proces to jednak kolejny esej.