Ich schreibe meinen eigenen Klon von Minecraft (auch in Java geschrieben). Es funktioniert gerade großartig. Mit einem Betrachtungsabstand von 40 Metern kann ich mit meinem MacBook Pro 8,1 problemlos 60 FPS erreichen. (Intel i5 + Intel HD Graphics 3000). Wenn ich den Betrachtungsabstand auf 70 Meter stelle, erreiche ich nur 15-25 FPS. In der realen Minecraft kann ich die Sichtweite (= 256m) problemlos einstellen. Meine Frage ist also, was ich tun soll, um mein Spiel zu verbessern?
Die Optimierungen, die ich implementiert habe:
- Lasse nur lokale Chunks im Speicher (abhängig vom Betrachtungsabstand des Players)
- Frustum Culling (Erst auf den Brocken, dann auf den Blöcken)
- Zeichne nur wirklich sichtbare Flächen der Blöcke
- Verwenden von Listen pro Block, die die sichtbaren Blöcke enthalten. Blöcke, die sichtbar werden, fügen sich dieser Liste hinzu. Wenn sie unsichtbar werden, werden sie automatisch aus dieser Liste entfernt. Blöcke werden (in) sichtbar, indem ein Nachbarblock gebaut oder zerstört wird.
- Verwenden von Listen pro Block, die die Aktualisierungsblöcke enthalten. Gleicher Mechanismus wie die sichtbaren Sperrlisten.
- Verwenden Sie fast keine
new
Anweisungen innerhalb der Spielschleife. (Mein Spiel dauert ungefähr 20 Sekunden, bis der Garbage Collector aufgerufen wird.) - Ich verwende derzeit OpenGL-Anruflisten. (
glNewList()
,glEndList()
,glCallList()
) Für jede Seite einer Art von Block.
Momentan benutze ich überhaupt kein Beleuchtungssystem. Ich habe schon von VBO's gehört. Aber ich weiß nicht genau was es ist. Ich werde jedoch einige Nachforschungen anstellen. Verbessern sie die Leistung? Bevor ich VBOs implementiere, möchte ich versuchen, glCallLists()
eine Liste von Anruflisten zu verwenden und zu übergeben. Stattdessen tausendmal verwenden glCallList()
. (Ich möchte dies versuchen, weil ich denke, dass das echte MineCraft keine VBOs verwendet. Richtig?)
Gibt es andere Tricks, um die Leistung zu verbessern?
Die VisualVM-Profilerstellung hat mir dies gezeigt (Profilerstellung für nur 33 Frames mit einem Betrachtungsabstand von 70 Metern):
Profilierung mit 40 Metern (246 Frames):
Hinweis: Ich synchronisiere viele Methoden und Codeblöcke, da ich Blöcke in einem anderen Thread generiere. Ich denke, dass das Erlangen einer Sperre für ein Objekt ein Leistungsproblem ist, wenn man so viel in einer Spieleschleife macht (ich spreche natürlich von der Zeit, in der es nur eine Spieleschleife gibt und keine neuen Blöcke erzeugt werden). Ist das richtig?
Bearbeiten: Nach dem Entfernen einiger synchronised
Blöcke und einiger anderer kleiner Verbesserungen. Die Leistung ist schon viel besser. Hier sind meine neuen Profilierungsergebnisse mit 70 Metern:
Ich denke, es ist ziemlich klar, dass selectVisibleBlocks
hier das Problem ist.
Danke im Voraus!
Martijn
Update : Nach einigen zusätzlichen Verbesserungen (z. B. Verwenden von for-Schleifen anstelle von for-Schleifen, Puffern von Variablen außerhalb von Schleifen usw.) kann ich jetzt die Anzeigedistanz 60 ziemlich gut ausführen.
Ich denke, ich werde VBOs so schnell wie möglich implementieren.
PS: Der gesamte Quellcode ist auf GitHub verfügbar:
https://github.com/mcourteaux/CraftMania