2009-11-13 13 views
9

Chociaż wydaje się, że niewiele jest aktualnych odniesień do samego OpenGL 3.x, faktyczna manipulacja OpenGL na niskim poziomie jest stosunkowo prosta. Mam jednak poważne problemy, próbując nawet konceptualizować, w jaki sposób można manipulować VBO, aby uczynić dynamiczny świat.Jak korzystać z VBO OpenGL 3.x, aby renderować dynamiczny świat?

Oczywiście sposoby dawnego trybu natychmiastowego nie mają zastosowania, ale skąd mam jechać? Czy napisałem jakąś strukturę sceny, a następnie przekonwertowałem ją na zbiór wierzchołków i przesłałem do VBO, w jaki sposób miałbym przechowywać dane z tłumaczenia? Jeśli tak, to jak ten kod wyglądałby mądrze?

Zasadniczo naprawdę nie wiem, jak kontynuować.

Odpowiedz

9

Jeśli cały Twój świat jest naprawdę dynamiczny, można użyć flagi GL_STREAM_DRAW_ARB użytkowania i zresetuj dane w każdej klatce. Nie przejmuj się nim manipulować, po prostu spróbuj streamować tak wydajnie, jak to tylko możliwe.

Przyjmuję jednak, że masz scenę, która składa się z wielu sztywnych obiektów, które poruszają się względem siebie. W takim przypadku użyj jednego VBO dla każdego obiektu i określ flagę użycia GL_STATIC_DRAW_ARB. Następnie można ustawić transformację widoku modelu dla każdej instancji obiektu i wyrenderować je za pomocą jednego wywołania losowania na instancję.

Regułą (na PC) jest wydawanie nie więcej niż jednego połączenia remisowego na MHz procesora. Jest to surowy szacunek, ale jest w tym trochę prawdy. Nie przejmuj się umieszczaniem wielu niezależnych obiektów w jednym VBO lub innych trikach wydajnościowych, jeśli pozostaniesz poniżej tego limitu.

+1

+1 za uznanie grupowania za największy problem z kodowaniem grafiki w dzisiejszych czasach. 1 remis na Mhz wydaje mi się optymistyczny po napisaniu kodu w niektórych programach OpenGL ES iPhone - odkryłem, że jestem ograniczony do 30-40 partii, aby utrzymać przyzwoitą ilość klatek na sekundę! – tsalter

+0

Dobrze, powinienem dodać, że ta zasada może nie dotyczyć bezpośrednio urządzeń mobilnych. Widziałem to pierwszy raz na niektórych slajdach GDC kilka lat temu i dobrze mi to służyło na komputerach z systemem Windows. –

+0

Btw, właśnie znalazłem slajdy tutaj: http://ati.amd.com/developer/gdc/D3DTutorial3_Pipeline_Performance.pdf (głównie D3D9, OpenGL na stronie 28) –

5

Korzystanie z VBO nie oznacza, że ​​musisz renderować całą scenę za pomocą tylko jednego połączenia. Nadal możesz generować wiele wywołań rysowania i konfigurować różne macierze przekształceń po drodze.

Na przykład, jeśli używasz scenegrafu, każdy model w scenegraphie może odpowiadać pojedynczemu losowaniu. W takim przypadku najprostszym sposobem korzystania z VBO jest utworzenie oddzielnego VBO dla każdego modelu.

Optymalizacja może polegać na połączeniu kilku modeli w pojedyncze VBO, a następnie przekazywaniu nie-zerowych przesunięć podczas wykonywania wywołań rysowania; to wyrywa prawidłowy model z VBO. Pożądane jest również łączenie wielu wywołań rysujących w jedno wywołanie typu draw, ale nie jest to możliwe, jeśli muszą mieć niezależne transformacje. (Faktycznie to jest możliwe w pewnych sytuacjach, jeśli używasz Instancing lub wierzchołków mieszanie, ale proponuję uzyskanie podstaw out of the way pierwszy).

9

Krótka odpowiedź:

Zastosowanie glMapBufferRange i tylko zaktualizować podzakresu, który wymaga modyfikacji.

Długa odpowiedź:

Sztuką jest, aby odwzorować już istniejący bufor z glMapBufferRange, a następnie tylko odwzorować zakres trzeba. Biorąc pod uwagę powyższe założenia:

  • Twój geometria wykorzystuje animację per-vertex morfingu
  • The liczbę wierzchołków dla modeli jest stała w trakcie animacji.

Następnie można użyć glMapBufferRange aktualizować tylko wymiany części, a resztę pozostawić danych sam. Przesyłanie pełne przy użyciu glBufferData jest powolne jak żółw, ponieważ usuwa stary magazyn pamięci i przydziela nowy. Oprócz przesyłania nowych danych. glMapBufferRange pozwala tylko na odczyt/zapis istniejących danych, nie przypisuje ani nie rozdziela.

Jeśli jednak korzystasz z animacji szkieletu, przekaż transformacje wierzchołków jako macierze 4x4 na wierzchołek do wierzchołka modułu cieniującego i wykonaj obliczenia. Dane dotyczące poszczególnych wierzchołków są oczywiście określone za pomocą glVertexAttribPointer.

Pamiętaj też, że możesz czytać dane tekstury w module cieniującym wierzchołków i że OpenGL 3.1 wprowadza pewne nowe wywołania rysowania instancji; glDrawArraysInstanced i glDrawElementsInstanced. Te połączone mogą być używane do wyszukiwania specyficznego dla instancji. Można np. Wywoływać wywołania z tymi samymi danymi geometrii, ale wysyłać pozycje lub dowolne dane na temat każdego wierzchołka, które są potrzebne, jako tekstury lub tablice tekstur. To może zaoszczędzić na mieszaniu i dopasowywaniu różnych zestawów danych macierzy wierzchołków.

Wyobraź sobie, że chcesz renderować 100 wystąpień tego samego modelu, ale z różnymi pozycjami lub schematami kolorów. A nawet mapy tekstur.

Powiązane problemy