Я пишу свой собственный клон Minecraft (также написан на Java). Это прекрасно работает прямо сейчас. При расстоянии просмотра 40 метров я могу легко набрать 60 кадров в секунду на своем MacBook Pro 8,1. (Intel i5 + Intel HD Graphics 3000). Но если я поставлю расстояние просмотра на 70 метров, я достигну только 15-25 FPS. В реальном Minecraft, я могу поставить расстояние просмотра далеко (= 256 м) без проблем. Итак, мой вопрос: что я должен сделать, чтобы улучшить мою игру?
Оптимизации, которые я реализовал:
- Храните в памяти только локальные фрагменты (в зависимости от расстояния просмотра игрока)
- Отбор Frustum (сначала на куски, затем на блоки)
- Только рисование реально видимых граней блоков
- Использование списков на блок, которые содержат видимые блоки. Куски, которые становятся видимыми, добавят себя в этот список. Если они становятся невидимыми, они автоматически удаляются из этого списка. Блоки становятся (не) видимыми при строительстве или уничтожении соседнего блока.
- Использование списков на блок, которые содержат блоки обновления. Тот же механизм, что и в видимых списках блоков.
- Не используйте почти никаких
new
утверждений внутри игрового цикла. (Моя игра длится около 20 секунд, пока не будет вызван сборщик мусора) - Я использую списки вызовов OpenGL на данный момент. (
glNewList()
,glEndList()
,glCallList()
) Для каждой стороны своего рода блока.
В настоящее время я даже не использую какую-либо систему освещения. Я уже слышал о VBO. Но я не знаю точно, что это. Тем не менее, я сделаю некоторые исследования о них. Будут ли они улучшить производительность? Перед реализацией VBO, я хочу попытаться использовать glCallLists()
и передать список списков вызовов. Вместо этого, используя тысячу разglCallList()
. (Я хочу попробовать это, потому что я думаю, что настоящий MineCraft не использует VBO. Верно?)
Существуют ли другие приемы для повышения производительности?
Профилирование VisualVM показало мне это (профилирование только для 33 кадров при расстоянии просмотра 70 метров):
Профилирование с 40 метров (246 кадров):
Заметка: я синхронизирую много методов и блоков кода, потому что я генерирую куски в другом потоке. Я думаю, что получение блокировки для объекта - это проблема производительности, когда вы делаете это в игровом цикле (конечно, я говорю о том времени, когда есть только игровой цикл и новые порции не генерируются). Это правильно?
Редактировать: после удаления некоторых synchronised
блоков и некоторых других небольших улучшений. Производительность уже намного лучше. Вот мои новые результаты профилирования с 70 метров:
Я думаю, что довольно ясно, что selectVisibleBlocks
проблема здесь.
Заранее спасибо!
Мартейн
Обновление : после некоторых дополнительных улучшений (таких как использование циклов for вместо каждого, буферизация переменных вне циклов и т. Д.), Я теперь могу довольно хорошо пробежать расстояние просмотра 60.
Я думаю, что я собираюсь реализовать VBO как можно скорее.
PS: Весь исходный код доступен на GitHub:
https://github.com/mcourteaux/CraftMania