J'écris mon propre clone de Minecraft (également écrit en Java). Cela fonctionne très bien en ce moment. Avec une distance de visualisation de 40 mètres, je peux facilement atteindre 60 ips sur mon MacBook Pro 8,1. (Intel i5 + Intel HD Graphics 3000). Mais si je mets la distance de vision sur 70 mètres, je n’atteins que 15-25 FPS. Dans le vrai Minecraft, je peux mettre le désordre de visionnage loin (= 256m) sans problème. Ma question est donc: que dois-je faire pour améliorer mon jeu?
Les optimisations que j'ai mises en place:
- Ne conservez que des morceaux locaux en mémoire (en fonction de la distance de visualisation du lecteur)
- Frustum culling (d'abord sur les morceaux, puis sur les blocs)
- Dessiner seulement les faces vraiment visibles des blocs
- Utilisation de listes par morceau contenant les blocs visibles. Les morceaux qui deviennent visibles s'ajouteront à cette liste. S'ils deviennent invisibles, ils sont automatiquement supprimés de cette liste. Les blocs deviennent (in) visibles en construisant ou en détruisant un bloc voisin.
- Utilisation de listes par morceau contenant les blocs de mise à jour. Même mécanisme que les listes de blocs visibles.
- N'utilisez presque pas d'
new
énoncés dans la boucle de jeu. (Mon jeu dure environ 20 secondes jusqu'à ce que le récupérateur de place soit appelé) - J'utilise les listes d'appels OpenGL pour le moment. (
glNewList()
,glEndList()
,glCallList()
) Pour chaque côté d'un type de bloc.
Actuellement, je n'utilise même pas de système d'éclairage. J'ai déjà entendu parler de VBO. Mais je ne sais pas exactement ce que c'est. Cependant, je vais faire des recherches à leur sujet. Est-ce qu'ils vont améliorer les performances? Avant d'implémenter les VBO, je veux essayer d'utiliser glCallLists()
et de transmettre une liste de listes d'appels. Au lieu d'utiliser mille fois glCallList()
. (Je veux essayer ceci, parce que je pense que le vrai MineCraft n'utilise pas de VBO. Correct?)
Existe-t-il d'autres astuces pour améliorer les performances?
Le profilage VisualVM m'a montré ceci (profilage pour seulement 33 images, avec une distance de visualisation de 70 mètres):
Profiler avec 40 mètres (246 images):
Remarque: Je synchronise beaucoup de méthodes et de blocs de code, car je génère des fragments dans un autre thread. Je pense qu'acquérir un verrou pour un objet est un problème de performance lorsqu'il effectue autant de choses dans une boucle de jeu (bien sûr, je parle du moment où il n'y a que la boucle de jeu et aucun nouveau fragment n'est généré). Est-ce correct?
Edit: Après avoir supprimé quelques synchronised
blocs et quelques autres petites améliorations. La performance est déjà bien meilleure. Voici mes nouveaux résultats de profilage avec 70 mètres:
Je pense qu'il est assez clair que selectVisibleBlocks
c'est le problème ici.
Merci d'avance!
Martijn
Mise à jour : après quelques améliorations supplémentaires (utilisation de boucles for à la place de chacune, mise en mémoire tampon des variables en dehors des boucles, etc.), je peux maintenant parcourir la distance de visualisation 60 plutôt bien.
Je pense que je vais mettre en œuvre les VBO dès que possible.
PS: tout le code source est disponible sur GitHub:
https://github.com/mcourteaux/CraftMania