Estoy escribiendo mi propio clon de Minecraft (también escrito en Java). Funciona muy bien en este momento. Con una distancia de visualización de 40 metros, puedo alcanzar fácilmente 60 FPS en mi MacBook Pro 8,1. (Intel i5 + Intel HD Graphics 3000). Pero si pongo la distancia de visión en 70 metros, solo alcanzo 15-25 FPS. En el Minecraft real, puedo poner la distancia de visualización en lejos (= 256 m) sin ningún problema. Entonces, mi pregunta es ¿qué debo hacer para mejorar mi juego?
Las optimizaciones que implementé:
- Solo mantenga fragmentos locales en la memoria (dependiendo de la distancia de visualización del jugador)
- Recolección de Frustum (Primero en los trozos, luego en los bloques)
- Solo dibujar caras realmente visibles de los bloques
- Usar listas por fragmento que contienen los bloques visibles. Los fragmentos que se vuelven visibles se agregarán a esta lista. Si se vuelven invisibles, se eliminan automáticamente de esta lista. Los bloques se hacen (in) visibles al construir o destruir un bloque vecino.
- Uso de listas por fragmento que contienen los bloques de actualización. Mismo mecanismo que las listas de bloqueo visibles.
- Casi no use
new
declaraciones dentro del ciclo del juego. (Mi juego dura unos 20 segundos hasta que se invoca el recolector de basura) - Estoy usando listas de llamadas de OpenGL en este momento. (
glNewList()
,glEndList()
,glCallList()
) Para cada lado de una especie de bloque.
Actualmente ni siquiera estoy usando ningún tipo de sistema de iluminación. Ya escuché sobre VBO's. Pero no sé exactamente qué es. Sin embargo, investigaré un poco sobre ellos. ¿Mejorarán el rendimiento? Antes de implementar VBO, quiero intentar usar glCallLists()
y pasar una lista de listas de llamadas. En lugar de usar mil vecesglCallList()
. (Quiero probar esto, porque creo que el MineCraft real no usa VBO. ¿Correcto?)
¿Hay otros trucos para mejorar el rendimiento?
El perfil de VisualVM me mostró esto (perfil de solo 33 cuadros, con una distancia de visión de 70 metros):
Perfilado con 40 metros (246 cuadros):
Nota: estoy sincronizando muchos métodos y bloques de código, porque estoy generando fragmentos en otro hilo. Creo que adquirir un bloqueo para un objeto es un problema de rendimiento al hacer esto en un bucle del juego (por supuesto, estoy hablando del momento en que solo hay un bucle del juego y no se generan nuevos fragmentos). ¿Es esto correcto?
Editar: después de eliminar algunos synchronised
bloques y algunas otras pequeñas mejoras. El rendimiento ya es mucho mejor. Aquí están mis nuevos resultados de perfil con 70 metros:
Creo que está bastante claro que ese selectVisibleBlocks
es el problema aquí.
¡Gracias por adelantado!
Martijn
Actualización : después de algunas mejoras adicionales (como el uso de bucles for en lugar de para cada uno, almacenamiento de variables fuera de los bucles, etc.), ahora puedo ejecutar la distancia de visualización 60 bastante bien.
Creo que voy a implementar los VBO lo antes posible.
PD: todo el código fuente está disponible en GitHub:
https://github.com/mcourteaux/CraftMania