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.
Profiling of the game running with a low framerate, I have highlighted a couple of points, are they expected?
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.