Piszę własny klon Minecrafta (również napisany w Javie). Teraz działa świetnie. Dzięki odległości oglądania wynoszącej 40 metrów mogę z łatwością osiągnąć 60 FPS na moim MacBooku 8,1. (Intel i5 + Intel HD Graphics 3000). Ale jeśli ustawię odległość oglądania na 70 metrów, osiągnę tylko 15-25 FPS. W prawdziwym Minecrafcie mogę bez problemu ustawić odległość oglądania na odległość (= 256 m). Więc moje pytanie brzmi: co powinienem zrobić, aby moja gra była lepsza?
Optymalizacje, które wdrożyłem:
- Przechowuj tylko lokalne fragmenty w pamięci (w zależności od odległości oglądania gracza)
- Ubijanie Frustum (najpierw na kawałki, a następnie na bloki)
- Rysowanie tylko widocznych powierzchni bloków
- Używanie list na porcję, które zawierają widoczne bloki. Fragmenty, które staną się widoczne, dodadzą się do tej listy. Jeśli staną się niewidoczne, zostaną automatycznie usunięte z tej listy. Bloki stają się (nie) widoczne przez zbudowanie lub zniszczenie sąsiedniego bloku.
- Używanie list na porcję, które zawierają bloki aktualizacji. Ten sam mechanizm, co widoczne listy bloków.
- Nie używaj prawie żadnych
new
instrukcji w pętli gry. (Moja gra działa około 20 sekund do momentu wywołania Garbage Collector) - Obecnie korzystam z list połączeń OpenGL. (
glNewList()
,glEndList()
,glCallList()
) Dla każdej strony w rodzaju bloku.
Obecnie nawet nie używam żadnego systemu oświetlenia. Słyszałem już o VBO. Ale nie wiem dokładnie, co to jest. Jednak zrobię o nich trochę badań. Czy poprawią wydajność? Przed wdrożeniem VBO chcę spróbować użyć glCallLists()
i przekazać listę list połączeń. Zamiast tego tysiąc razy glCallList()
. (Chcę tego spróbować, ponieważ uważam, że prawdziwy MineCraft nie używa VBO. Prawda?)
Czy istnieją inne sztuczki mające na celu poprawę wydajności?
Profilowanie VisualVM pokazało mi to (profilowanie tylko 33 klatek, z odległości oglądania 70 metrów):
Profilowanie za pomocą 40 metrów (246 ramek):
Uwaga: synchronizuję wiele metod i bloków kodu, ponieważ generuję porcje w innym wątku. Myślę, że uzyskanie blokady dla obiektu jest problemem z wydajnością podczas robienia tak dużo w pętli gry (oczywiście mówię o czasie, w którym jest tylko pętla gry i nie są generowane żadne nowe fragmenty). Czy to jest poprawne?
Edycja: Po usunięciu niektórych synchronised
bloków i innych drobnych usprawnień. Wydajność jest już znacznie lepsza. Oto moje nowe wyniki profilowania z 70 metrami:
Myślę, że jest to całkiem jasne, o selectVisibleBlocks
to tutaj chodzi.
Z góry dziękuję!
Martijn
Aktualizacja : Po kilku dodatkowych ulepszeniach (takich jak użycie pętli zamiast dla każdego, buforowanie zmiennych poza pętlami itp.), Mogę teraz całkiem dobrze wyświetlać odległość 60.
Myślę, że zamierzam jak najszybciej wdrożyć VBO.
PS: Cały kod źródłowy jest dostępny na GitHub:
https://github.com/mcourteaux/CraftMania