Question

I need to render objects in libgdx (average of 20-30) on screen, all sorted by Y value, so the sprites with the lowest Y values are rendered first. ( think about this perspective: http://i.stack.imgur.com/m1VQA.gif )

The game utilizes texture atlases, each has the size of 2048*2048.

I currently have three atlases. One for the playable characters, one for the NPC characters, and one for animals/monsters. Eventually we plan add a lot of different objects, npc sets and so on, so mixing up all the sprites to one big atlas is not an option (can get very limited on both design, and hardware).

The current rendering method first sorts the objects on screen every frame by Y value, and then draws them. This works perfectly, except for the fact, that this way, many texture switching can occour.

For example, rendering: - 3 animals - 2 npc's - player - 1 npc - 1 animal - 1 npc - 2 animal,

would need 7 texture switching. This entirely depends on the objects position on screen.

Sorting the sprites by atlas is not an option (first drawing the animals, then npc's, then the player), because this would make Y sorting impossible.

(The first thing I had in mind was increasing the texture atlas to 8192*8192, but many older desktop pc's, and mobile devices would be unable to run the game. The second thing I thought of was some kind of depth buffering, but I am unsure how to do that, if possible.)

What method must be used to achieve the desired result (sorted sprites from multiple textures), while maintaining stable frame rates? Is there any viable openGL trick to do this? Should I be worried about having 6-7 texture switches per frame?

Was it helpful?

Solution

See this link which is libgdx test, there is z as depth on test but you may use y axis

SortedSpriteTest

You need to use comparator and sort the array and obviously reduce performance of the game.

OTHER TIPS

Actually that shouldn't be an problem if you give your Actor the specified Sprite as attribut. You never load anything while you render stuff. If you create your Actors you do load the sprites, textures and so on from the Atlas and give it to your Actor. Something like this:

Texture monster = getTextureByType(type);
Monster mon = new Monster(level, new Sprite(monster), screen, ai,npc);

Inside of your Monster (Actor!) you save those as your Sprite. Regular constructor i think

public Monster(int level, Sprite sprite, GameScreen screen, AIInterface ai,
                boolean npc) {
            this.life = 300;
            this.curLife = 200;
            this.ai = ai;
            this.level = level;
            this.sprite = sprite;
            this.sprite.setRegion(0, 0, 32, 48);
    }

The draw is preaty simple:

    @Override
    public void draw(SpriteBatch batch, float parentAlpha) {
        if (alife) {
            sprite.setPosition(this.getX() + ofset, this.getY());
            sprite.draw(batch);
        }
     }

If you did this you will have no problems with any framerate. Not at such a low actor count. Simply dont load the texture inside of the draw/render cycle and it should work without any problem. And it shouldn't be any problem with multiple Atlas. The atlas isn't used to render. It's used to put multiple textures into one texture to handle it more easy. You never load something inside of the draw or render method from an atlas. If you do so you'll get a really bad performance.

For the sorting do use insertionsort. That should be faster than the collection sort in your szenario. Maybe call it every 10 Frames. You shouldn't even notice that they are not correct sorted in that short period.

private void sortList(Array<Actor> array) {
    // double starttime = System.nanoTime();
    for (int i = 1; i < array.size; i++) {
        Actor temp = array.get(i);
        int j = i - 1;

        while (j >= 0 && array.get(j).getY() < temp.getY()) {
            array.set(j + 1, array.get(j));
            j--;
        }
        array.set(j + 1, temp);
    }
    // System.out.println("Time taken: " + (System.nanoTime() - starttime));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top