Sto scrivendo il mio clone di Minecraft (anche scritto in Java). Funziona benissimo in questo momento. Con una distanza di visione di 40 metri posso facilmente raggiungere 60 FPS sul mio MacBook Pro 8,1. (Intel i5 + Intel HD Graphics 3000). Ma se metto la distanza di visione su 70 metri, raggiungo solo 15-25 FPS. Nel vero Minecraft, posso mettere la distanza di visualizzazione lontana (= 256m) senza problemi. Quindi la mia domanda è: cosa devo fare per migliorare il mio gioco?
Le ottimizzazioni che ho implementato:
- Mantieni solo blocchi locali in memoria (a seconda della distanza di visione del giocatore)
- Abbattimento del frustum (prima sui pezzi, poi sui blocchi)
- Disegnando solo facce davvero visibili dei blocchi
- Utilizzo di elenchi per blocco che contengono i blocchi visibili. I pezzi che diventano visibili si aggiungeranno a questo elenco. Se diventano invisibili, vengono automaticamente rimossi da questo elenco. I blocchi diventano (in) visibili costruendo o distruggendo un blocco vicino.
- Utilizzo di elenchi per blocco che contengono i blocchi di aggiornamento. Stesso meccanismo delle liste di blocchi visibili.
- Usa quasi nessuna
new
istruzione all'interno del ciclo di gioco. (Il mio gioco dura circa 20 secondi fino a quando viene richiamato il Garbage Collector) - Al momento sto usando gli elenchi di chiamate OpenGL. (
glNewList()
,glEndList()
,glCallList()
) Per ciascun lato di un tipo di blocco.
Attualmente non sto nemmeno usando alcun tipo di sistema di illuminazione. Ho già sentito parlare dei VBO. Ma non so esattamente di cosa si tratti. Tuttavia, farò alcune ricerche su di loro. Miglioreranno le prestazioni? Prima di implementare i VBO, voglio provare a utilizzare glCallLists()
e passare un elenco di elenchi di chiamate. Invece usando migliaia di volte glCallList()
. (Voglio provare questo, perché penso che il vero MineCraft non usi i VBO. Corretto?)
Ci sono altri trucchi per migliorare le prestazioni?
Il profilo VisualVM mi ha mostrato questo (profilo per soli 33 frame, con una distanza di visione di 70 metri):
Profilatura con 40 metri (246 cornici):
Nota: sto sincronizzando molti metodi e blocchi di codice, perché sto generando blocchi in un altro thread. Penso che acquisire un lucchetto per un oggetto sia un problema di prestazioni quando si fa così tanto in un loop di gioco (ovviamente, sto parlando del tempo in cui c'è solo il loop di gioco e non vengono generati nuovi blocchi). È giusto?
Modifica: dopo aver rimosso alcuni synchronised
blocchi e altri piccoli miglioramenti. Le prestazioni sono già molto migliori. Ecco i miei nuovi risultati di profilazione con 70 metri:
Penso che sia abbastanza chiaro che questo selectVisibleBlocks
è il problema qui.
Grazie in anticipo!
Martijn
Aggiornamento : dopo alcuni miglioramenti extra (come l'utilizzo di loop invece di ciascuno, il buffering delle variabili al di fuori dei loop, ecc ...), ora posso eseguire una distanza di visualizzazione 60 piuttosto buona.
Penso che implementerò i VBO il prima possibile.
PS: tutto il codice sorgente è disponibile su GitHub:
https://github.com/mcourteaux/CraftMania