1
votes

I'm writing a client for a multiplayer tile-based game in libGDX (for Android and Desktop). The game world is composed of thousands of small 32x32 png images that are drawn into a large rectangular view area. The images are downloaded over the socket connection (network) as needed.

What is the best (fastest and most resource-efficient) way to store these images in "memory" so they can be drawn really fast onto the screen when needed?

So far, I have implemented a very naive algorithm that will load each and every 32x32 image into a Texture and keep that in memory indefinitly. (Pure coincidence my images got a size that is a power of two.) It seems to work, but I am worried that this is very inefficient and possible exceeds GPU resources on older devices or something.

I am aware of the TextureAtlas, but that seems to work only for static images that are packed and stored in the compiled android app. As I receive my images over the network dynamically, I believe this won't work for me.

I have found this libgdx SpriteBatch render to texture post that suggest rendering many small images into a FrameBuffer, then using this as a source of TextureRegions. This seems promising to me. Is this a good solution? Is there a better way?

I also wonder if drawing and storing my small images into a large Pixmap might be helpful. Is this possibly a better approach than drawing into a FrameBuffer, as described above? As I understand it from the docs, Pixmaps are purely memory-based. That might be an advantage as it probably doesn't need graphics resources, on the other hand might be slower as loading into a Texture is an expensive operation. Thoughts on this?

1

1 Answers

1
votes

Actually TextureAtlas is the best way to store many images (small or not) and fortunatelly the TextureAtlas instance do not have to be created in a static way.

Take a look at

    addRegion(java.lang.String name, Texture texture, int x, int y, int width, int height)

TextureAtlas'es method. It make it possible to create atlas dynamically.

So what you should do is to create empty atlas

    TextureAtlas atlas = new TextureAtlas();

then add your images in some kind of loop

    for(Texture texture : yourTexturesCollection)
        atlas.addRegion(...);

then you can use your atlas by using findRegion or another method (take a look at reference)


Notice that for android devices it is recommended to use not larger atlas than 2048 x 2048px.

For another kind of devices (like dekstop) this value can be another (usually bigger). It is not LibGDX limit but openGL's!