2014-01-16 5 views
5

In einem 3D Scrabble-ähnlichen Spiel habe ich ein Leistungsproblem von nur 8 FPS bekommen. Es wurde auf die Buchstabenkacheln eingegrenzt. Es gibt 100 von ihnen und eine Verringerung ihrer Anzahl verbessert die Leistung schnell. Ich habe die Texturbindung ausgeschlossen, da sich die Geschwindigkeit nicht verbessert, selbst wenn alle Kacheln die gleiche Textur wie auf dem Screenshot haben.Erstellen einer Box mit Textur auf einer Seite in libgdx - Leistung

screenshot

Dies ist, wie ich jedes Feld zu erstellen:

public static void createModel() { 
    matWhite = new Material(ColorAttribute.createDiffuse(Color.WHITE)); 
    ModelBuilder modelBuilder = new ModelBuilder(); 
    modelBuilder.begin(); 
    MeshPartBuilder tileBuilder; 
    tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matWhite); 
    tileBuilder.rect(-0.45f, 0.1f, 0.45f, 0.45f, 0.1f, 0.45f, 0.45f, 0.1f, -0.45f, -0.45f, 0.1f, -0.45f, 0f, 1f, 0f); 
    tileBuilder = modelBuilder.part("bottom", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite); 
    tileBuilder.rect(-0.45f, 0f, -0.45f, 0.45f, 0f, -0.45f,  0.45f, 0f, 0.45f,  -0.45f, 0f, 0.45f, 0f, -1f, 0f); 
    tileBuilder = modelBuilder.part("front", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite); 
    tileBuilder.rect(-0.45f, 0.1f, 0.45f, -0.45f, 0f, 0.45f,  0.45f, 0f, 0.45f,  0.45f, 0.1f, 0.45f, 0f, 0f, 1f); 
    tileBuilder = modelBuilder.part("left", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite); 
    tileBuilder.rect(-0.45f, 0.1f, 0.45f, -0.45f, 0.1f, -0.45f, -0.45f, 0f, -0.45f, -0.45f, 0f, 0.45f, -1f, 0f, 0f); 
    tileBuilder = modelBuilder.part("right", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite); 
    tileBuilder.rect(0.45f, 0.1f, 0.45f, 0.45f, 0f, 0.45f,  0.45f, 0f, -0.45f,  0.45f, 0.1f, -0.45f, 0f, 0f, 1f); 
    tileBuilder = modelBuilder.part("back", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite); 
    tileBuilder.rect(-0.45f, 0.1f, -0.45f, 0.45f, 0.1f, -0.45f, 0.45f, 0f, -0.45f, -0.45f, 0f, -0.45f, 0f, 0f, 1f); 
    modelTile = modelBuilder.end(); 
} 

public void createModelInstance(com.badlogic.gdx.assets.AssetManager assetManager) { 
    Texture texTile = assetManager.get("textures/" + textureFile + ".jpg", Texture.class); 
    Material mat = new Material(TextureAttribute.createDiffuse(texTile)); 
    modelInstance = new ModelInstance(modelTile); 
    modelInstance.nodes.get(0).parts.get(0).material.set(mat); 
} 

Während des Experimentieren, ich, dass die Geschwindigkeit bis zu 25 FPS geht aus (auch bei allen 100 Texturen verwendet werden), wenn ich das Netz ersetzen Teilerstellungscode mit dem Erstellen einer einfachen Box (die die Textur auf allen Seiten zeigt, so dass es für dieses Spiel nicht sehr nützlich ist). Ihre createBox-Methode ruft auch sechsmal rect() auf, aber bis jetzt sehe ich den Unterschied nicht.

modelTile = modelBuilder.createBox(0.9f, 0.1f, 0.9f, matWhite, Usage.Position | Usage.Normal | Usage.TextureCoordinates); 

Was mache ich falsch im ersten Code? Was wäre der richtige Weg, um eine Box mit Textur nur auf einer Seite zu erstellen?

+0

Sind Sie auf dem Desktop oder auf Android/iOS bereitstellen? Stellen Sie bei der Bereitstellung auf dem Desktop sicher, dass Ihre dedizierte GPU verwendet wird. Ich führe gerade etwas ähnliches auf Ubuntu (mit Zeilen, nicht mit Rezepten) und bekomme ähnliche Probleme für ~ 1000 Zeilen. Ich glaube, dass es meine Intel-Karte ist, auf der die App läuft, nicht meine Nvidia-Karte, wodurch die Leistung ziemlich beeinträchtigt wird. Bin aber noch nicht auf den Grund gegangen. –

+0

Die FPS-Werte, die ich geschrieben habe, sind auf einem Samsung Galaxy Tab 2 10.1, obwohl die Emulatorwerte ebenfalls nahe sind (mit der Option "Host GPU verwenden" aktiviert). – Arthur

Antwort

5

Jedes Mal, wenn Sie modelBuilder.part anrufen, impliziert dies einen Zeichenaufruf. Da sie ziemlich teuer sind, möchten Sie die Anzahl der Zeichenaufrufe wirklich auf ein Minimum beschränken. Da Sie verschiedene Vertex-Attribute haben, müssen Sie Mesh und Shader zwischen den ersten und anderen Teilen wechseln. Sie sollten auch die Anzahl der Mesh- und Shader-Switches auf ein Minimum beschränken.

, So starten Sie wahrscheinlich die Teile mit den gleichen Attributen kombinieren optimieren werden wollen:

tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matWhite); 
tileBuilder.rect(-0.45f, 0.1f, 0.45f, 0.45f, 0.1f, 0.45f, 0.45f, 0.1f, -0.45f, -0.45f, 0.1f, -0.45f, 0f, 1f, 0f); 
tileBuilder = modelBuilder.part("others", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite); 
tileBuilder.rect(-0.45f, 0f, -0.45f, 0.45f, 0f, -0.45f,  0.45f, 0f, 0.45f,  -0.45f, 0f, 0.45f, 0f, -1f, 0f); 
tileBuilder.rect(-0.45f, 0.1f, 0.45f, -0.45f, 0f, 0.45f,  0.45f, 0f, 0.45f,  0.45f, 0.1f, 0.45f, 0f, 0f, 1f); 
tileBuilder.rect(-0.45f, 0.1f, 0.45f, -0.45f, 0.1f, -0.45f, -0.45f, 0f, -0.45f, -0.45f, 0f, 0.45f, -1f, 0f, 0f); 
tileBuilder.rect(0.45f, 0.1f, 0.45f, 0.45f, 0f, 0.45f,  0.45f, 0f, -0.45f,  0.45f, 0.1f, -0.45f, 0f, 0f, 1f); 
tileBuilder.rect(-0.45f, 0.1f, -0.45f, 0.45f, 0.1f, -0.45f, 0.45f, 0f, -0.45f, -0.45f, 0f, -0.45f, 0f, 0f, 1f); 

Und weiter zu optimieren (alle Mesh-Schalter eliminiert), können Sie die gleichen Vertex-Attribute verwenden. Natürlich fügt dies Texturattribute zu den Seiten ohne Textur hinzu. Aber solange das Material keine Textur hat, werden sie ignoriert.

tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matTop); 
tileBuilder.rect(-0.45f, 0.1f, 0.45f, 0.45f, 0.1f, 0.45f, 0.45f, 0.1f, -0.45f, -0.45f, 0.1f, -0.45f, 0f, 1f, 0f); 
tileBuilder = modelBuilder.part("others", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matOthers); 
tileBuilder.rect(-0.45f, 0f, -0.45f, 0.45f, 0f, -0.45f,  0.45f, 0f, 0.45f,  -0.45f, 0f, 0.45f, 0f, -1f, 0f); 
... 

Um noch mehr (Beseitigung aller Shader-Switches und die Verringerung der Anzahl von Zeichenaufrufen) zu optimieren, können Sie ein einzelnes Pixel auf die Textur hinzufügen können, die von den Seiten verwendet werden, und die UV-Bereich accordingle gesetzt:

tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matWhite); 
tileBuilder.setUVRange(0,0,1,1); 
tileBuilder.rect(-0.45f, 0.1f, 0.45f, 0.45f, 0.1f, 0.45f, 0.45f, 0.1f, -0.45f, -0.45f, 0.1f, -0.45f, 0f, 1f, 0f); 
tileBuilder.setUVRange(0,0,0,0); // Assumes the top left pixel is the correct color for the other sides 
tileBuilder.rect(-0.45f, 0f, -0.45f, 0.45f, 0f, -0.45f,  0.45f, 0f, 0.45f,  -0.45f, 0f, 0.45f, 0f, -1f, 0f); 
... 

Wenn Sie immer noch Leistungsprobleme haben, können Sie mehrere Kacheln in einem einzigen Modell kombinieren (Teil: Draw Call). Aber das wird bei den obigen Änderungen wahrscheinlich nicht sofort nötig sein.

Weitere Informationen: http://blog.xoppa.com/behind-the-3d-scenes-part1/

+0

25 FPS, yay! Lesen Sie jetzt Ihren Blog-Eintrag, vielen Dank! – Arthur

Verwandte Themen