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\$
  • \$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.