Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Manually setting Z-order  (Read 47537 times)

0 Members and 4 Guests are viewing this topic.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Manually setting Z-order
« Reply #15 on: March 21, 2009, 02:09:39 pm »
If there is any reason not to draw the sprites directly in the order you want them to be placed on the screen, you can have a sprite manager class which holds a container of sprites that can be sorted. The standard container std::priority_queue might be an option.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #16 on: March 21, 2009, 10:12:02 pm »
Sure, storing all the sprites and sorting by Z-order is probably best. I could probably just keep pointers to them in a std::set<> sorted by Z-order.

The downside there, is that I'd have to control the movement manually of all the sprites. For example, I'd have to manually set the position of a "foot" sprite when the "leg" sprite moves. The best way I see to do that is to override GetMatrix() and make it public, then just multiply the matrices together. However, if matrices might disappear in future versions, that scares me.

My other option is to treat SFML as just a pure rendering library, and not use it to store any position information. The would mean simply creating a new sprite every frame. It seems like a shame to duplicate all that though, and it might run slightly slower.

Hmmmm.

Thanks.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Manually setting Z-order
« Reply #17 on: March 22, 2009, 02:41:13 pm »
Quote from: "Imbue"
The downside there, is that I'd have to control the movement manually of all the sprites. For example, I'd have to manually set the position of a "foot" sprite when the "leg" sprite moves.
I don't really understand the connection with Z-order... You'd have to move a "foot" anyway after moving the "leg", wouldn't you? And besides, you could automatize that...

Quote from: "Imbue"
My other option is to treat SFML as just a pure rendering library, and not use it to store any position information. The would mean simply creating a new sprite every frame. It seems like a shame to duplicate all that though, and it might run slightly slower.
Separating logic from graphics is a good idea. There are different approaches: One of them is to recreate sprites every frame. Alternatively, you can hold sprites in a associative container, change for every object only a few properties like position, rotation and redraw the sprites every frame.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #18 on: March 22, 2009, 08:18:57 pm »
Quote from: "Nexus"
Quote from: "Imbue"
The downside there, is that I'd have to control the movement manually of all the sprites. For example, I'd have to manually set the position of a "foot" sprite when the "leg" sprite moves.
I don't really understand the connection with Z-order... You'd have to move a "foot" anyway after moving the "leg", wouldn't you? And besides, you could automatize that...
In SFML, if you draw a sprite inside of another Render() call, it will inherit its parent's properties (scale, position, rotation). So basically, just by having one object own a sprite as a member, that is taken care of automatically, provided you don't care too much about Z-order.

That is all calculated on the graphics card, and it works the same way with 3D models. You can even nest many levels deep, like rotating a shoulder rotates an arm which rotates a forearm which rotates a hand... all automatically.

So now it looks like I'll have a person class that holds all of its body parts, instead of a person class only holding a torso (which in turn holds arms and legs, etc).

drakelord

  • Newbie
  • *
  • Posts: 22
    • View Profile
Manually setting Z-order
« Reply #19 on: May 30, 2009, 08:53:22 am »
Another option would be to derive a new class from the sprite class, add in your own float for z order, then have a map or some sort of list of sprites that are sorted by z order and drawn in that order.

TheMiss

  • Newbie
  • *
  • Posts: 9
    • View Profile
Manually setting Z-order
« Reply #20 on: May 02, 2010, 02:40:05 pm »
Oh! come on, I manually sort z order (sf::Sprite of course) by std::list.sort().

It really hurts performance!

 :?

Are there any way to improve it?

gsaurus

  • Sr. Member
  • ****
  • Posts: 262
    • View Profile
    • Evolution Engine
Manually setting Z-order
« Reply #21 on: May 02, 2010, 11:24:25 pm »
Quote from: "TheMiss"
Oh! come on, I manually sort z order (sf::Sprite of course) by std::list.sort().

It really hurts performance!

 :?

Are there any way to improve it?

I said it more than once on other threads, use a std::multiset, it keeps all elements sorted.
When you update the z order of a sprite, remove that sprite from the set and add it again. This way it "sorts" that sprite only, doesn't have to sort the whole container.
Pluma - Plug-in Management Framework

TheMiss

  • Newbie
  • *
  • Posts: 9
    • View Profile
Manually setting Z-order
« Reply #22 on: May 03, 2010, 09:10:58 am »
Oh thanks!

I found the thread you said about.

How I skipped it over?

Xorlium

  • Jr. Member
  • **
  • Posts: 84
    • View Profile
Manually setting Z-order
« Reply #23 on: July 20, 2010, 06:53:18 pm »
But then if you modify the z-value of a sprite, don't you invalidate the multi-set?

CBenni::O

  • Newbie
  • *
  • Posts: 48
    • View Profile
Manually setting Z-order
« Reply #24 on: July 20, 2010, 10:21:31 pm »
Or you can use a Z-Buffer if you have lots of Sprites ;)

OGL should suport this...

bye, CBenni::O
42!
Metal will never die!

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
Manually setting Z-order
« Reply #25 on: July 21, 2010, 07:53:02 am »
Quote from: "TheMiss"
Oh! come on, I manually sort z order (sf::Sprite of course) by std::list.sort().

It really hurts performance!

 :?

Are there any way to improve it?


use a floating point radix sort?

namuol

  • Newbie
  • *
  • Posts: 1
    • View Profile
Manually setting Z-order
« Reply #26 on: September 21, 2010, 05:56:16 pm »
Quote from: "Xorlium"
But then if you modify the z-value of a sprite, don't you invalidate the multi-set?


The best solution would be to use accessor/mutator functions which automatically sort the list if the z value has changed.

Here's a Z-sorted sprite example (psuedo-C++):

Code: [Select]

class ZSprite : public sf::Sprite
{
  private:
    double z;
    std::list<ZSprite*>* list;
   
  public:
    ZSprite([[Sprite args...]],
                double z=0.0,
                std::list<ZSprite*>* list)
    {
        this->z = z;
        this->list = list;
    }

    double GetZ() { return z; }

    void SetZ(double value)
    {
        if( z != value )
        {
            z = value;
            [[sort your list here...]]
        }
    }
};

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Manually setting Z-order
« Reply #27 on: September 21, 2010, 08:17:03 pm »
There's no need to sort the list every time a sprite is modified, just do it once before drawing. Of course it depends if you have mostly static sprites or dynamic ones, but at least this strategy is consistent, you know that you have no more than 1 sort per frame.
Laurent Gomila - SFML developer

renton_django

  • Newbie
  • *
  • Posts: 8
    • View Profile
Manually setting Z-order
« Reply #28 on: October 05, 2010, 08:08:11 pm »
I have been having similar problems to the previous posters.

I think most people feel that a std::list sort (O(n log n) is too expensive to be running each frame if it doesn't have to be.

I still have to evaluate the std::multiset insertion/deletion method.

NoIdea

  • Full Member
  • ***
  • Posts: 149
    • View Profile
Manually setting Z-order
« Reply #29 on: October 05, 2010, 08:47:04 pm »
Personnaly, I don't use std::sort or std:::lists::sort.
Since elements are always inserted/changed z-order/... less than once per frame, the best performance solution is :
-each_time you add an element, you put it in the right place (insertion).
-each time you change an element's Z-order, you put it in the right place.

=>Your elements are always sorted even if you never sort them all

=> you can delete a Drawable without sorting anything.
=>You only use a bit of performance when you add/change a element.
=> to draw, just create an iterator and draw them all.

Pseudo code :

Code: [Select]
Class::inset_new(Drawable*d, unsigned plan)
    std::list<std::pair<Drawable*, unsigned int> >::iterator it;
    for(it=mylist.begin();it!=mylist.end();it++)
        if(it->second>plan)
            break;
    mylist.insert(std::make_pair(d,plan));


I let you guess the slution for changing Z-order.
This code is Pseudo code because I will not assure it will work (didn't check nor reread myself).