2
\$\begingroup\$

I'm getting bad frame rates while developing a game on Android. I have been developing on desktop too and only have the issues on Android. I am testing with a Nexus 6 (can't imagine how badly it will perform on older devices at the moment). Its directly related to the amount of actors I am adding to my scene. I am removing actors that are not on the screen which helps but not enough. Currently I am calling batch.totalRenderCalls around 190 times a frame. Is it excessive?

It is currently hammering me down to around 20fps and I plan to add more to this screen making it difficult to continue development until I have resolved this. Other screens in the game run easily at 60 fps with less actors.

I am extending Actor and storing a texture against it as recommended http://www.gamefromscratch.com/post/2013/11/27/LibGDX-Tutorial-9-Scene2D-Part-1.aspx

Everything on the screen is an actor of some sort, the background (1080p image) and every square or rectangle is crafted from a 1px by 1px image and colour altered in libgdx. The hair, and skin colour and ties of each character are separate textures and create a unique face. This is exactly the same technique as I used in AndEngine in different games I have released with much less framerate trouble, I thought libgdx would have better performance, am I mistaken?

Below I've included some code snippets and a screenshot of my game in development.

Example screen with struggling framerate

Profiling of the game running with a low framerate, I have highlighted a couple of points, are they expected? profiling

My textures:

public class ActorTex extends Actor {
Texture texture;

public ActorTex(float width, float height, Texture texture) {
    this(texture);
    setWidth(width);
    setHeight(height);
}

public ActorTex(Texture texture) {
    this.texture = texture;
    setWidth(texture.getWidth());
    setHeight(texture.getHeight());
}

@Override
public void draw(Batch batch, float alpha) {
    Color color = getColor();
    batch.setColor(color.r, color.g, color.b, color.a);
    batch.draw(texture, getX(), getY(), getWidth(), getHeight());
}

@Override
public void act(float delta) {
    super.act(delta);
    setBounds(getX(), getY(), getWidth(), getHeight());
}
}

My screen:

public abstract class AbstractScreen extends Stage implements Screen {

private FPSLogger log;

public AbstractScreen(Viewport v) {
    super(v);
    log = new FPSLogger();
    GLProfiler.enable();
}

@Override
public void show() {
}

@Override
public void render(float delta) {
    SpriteBatch batch = (SpriteBatch) getBatch();
    batch.totalRenderCalls = 0;
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

    // Calling to Stage methods
    super.act(delta);
    super.draw();
    System.out.println(batch.totalRenderCalls);
}

@Override
public void resize(int width, int height) {
    getViewport().update(width, height, true);
}

Game class render method:

@Override
public void render() {
    super.render();
    fpsLogger.log();
}

Managing my textures:

public class ResourceManager {

private static AssetManager manager;
private static String filePath;

public static void load() {
    manager = new AssetManager();
    filePath = "img/"; // where we store our images

    for (TextureEnum te : TextureEnum.values()) {
        manager.load(filePath + te.path, Texture.class);
    }
    manager.finishLoading();
}

public static Texture getTexture(TextureEnum te) {
    return manager.get(filePath + te.path, Texture.class);
}

public static Boolean isLoaded() {
    if (manager.getProgress() >= 1) {
        return true;
    }
    return false;
}

public static void dispose() {
    manager.dispose();
    manager = null;
}
}

Wondering if anyone can help, would love to get this sorted. Been stuck on this for quite a while now and I'm out of ideas unfortunately.

Does anyone have any good tips or ways to approach this? It does not seem to be a memory management problem as all these textures are in memory in other game screens without issues, also I tried replacing every texture in the game with a 1x1 pixel image and the performance problem did not seem affected, and I am not loading / doing anything funky in my render loop that I am aware of. It is only when they are displayed as actors, when they are removed as actors, the frame rate improves again. Feels like it could be something simple I have done wrong in my rendering.

\$\endgroup\$
1
  • \$\begingroup\$ May I ask why you have created an Actor that draws a texture when Image already exists? \$\endgroup\$
    – Charanor
    Apr 19 '17 at 17:53
1
\$\begingroup\$

Every actor uses it's own texture so they cannot be batched. I suggest packing the textures into a TextureAtlas, or just make one big texture and change UVs around yourself.

https://github.com/libgdx/libgdx/wiki/Texture-packer#texturepacker

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .