Estou escrevendo meu próprio clone do Minecraft (também escrito em Java). Funciona muito bem agora. Com uma distância de visualização de 40 metros, posso facilmente atingir 60 FPS no meu MacBook Pro 8,1. (Intel i5 + Intel HD Graphics 3000). Mas se eu colocar a distância de visualização em 70 metros, alcanço apenas 15-25 FPS. No Minecraft real, posso colocar a disnância de visualização longe (= 256m) sem nenhum problema. Então, minha pergunta é o que devo fazer para melhorar meu jogo?
As otimizações que implementei:
- Mantenha apenas partes locais na memória (dependendo da distância de visualização do player)
- Seleção de Frustum (primeiro nos pedaços, depois nos blocos)
- Desenhando apenas faces realmente visíveis dos blocos
- Usando listas por pedaço que contêm os blocos visíveis. Os pedaços que ficarem visíveis serão adicionados a esta lista. Se ficarem invisíveis, serão automaticamente removidos desta lista. Os blocos se tornam (in) visíveis construindo ou destruindo um bloco vizinho.
- Usando listas por bloco que contêm os blocos de atualização. Mesmo mecanismo que as listas de bloqueio visíveis.
- Não use quase nenhuma
new
instrução dentro do loop do jogo. (Meu jogo dura cerca de 20 segundos até que o Garbage Collector seja chamado) - Estou usando as listas de chamadas do OpenGL no momento. (
glNewList()
,glEndList()
,glCallList()
) Para cada lado de um tipo de bloco.
Atualmente, nem estou usando nenhum tipo de sistema de iluminação. Já ouvi falar de VBO's. Mas não sei exatamente o que é. No entanto, vou fazer algumas pesquisas sobre eles. Eles melhorarão o desempenho? Antes de implementar as VBOs, quero tentar usar glCallLists()
e passar uma lista de listas de chamadas. Em vez disso, use milhares de vezes glCallList()
. (Eu quero tentar isso, porque acho que o MineCraft real não usa VBOs. Correto?)
Existem outros truques para melhorar o desempenho?
A criação de perfil do VisualVM me mostrou isso (criação de perfil para apenas 33 quadros, com uma distância de visualização de 70 metros):
Criação de perfil com 40 metros (246 quadros):
Nota: Estou sincronizando muitos métodos e blocos de código, porque estou gerando pedaços em outro encadeamento. Eu acho que a aquisição de um bloqueio para um objeto é um problema de desempenho ao fazer isso em um loop do jogo (é claro, estou falando do momento em que existe apenas o loop do jogo e nenhum novo bloco é gerado). Isto está certo?
Edit: Depois de remover alguns synchronised
blocos e outras pequenas melhorias. O desempenho já é muito melhor. Aqui estão meus novos resultados de criação de perfil com 70 metros:
Eu acho que é bem claro que selectVisibleBlocks
é o problema aqui.
Desde já, obrigado!
Martijn
Atualização : Após algumas melhorias extras (como usar loops no lugar de cada um, armazenar em buffer variáveis fora dos loops, etc ...), agora posso executar a distância de visualização 60 muito bem.
Acho que vou implementar o VBO o mais rápido possível.
PS: Todo o código-fonte está disponível no GitHub:
https://github.com/mcourteaux/CraftMania