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

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

0 Members and 1 Guest are viewing this topic.

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« on: November 22, 2008, 05:51:36 am »
Will SFML ever support a real Z-order system?

Since SFML uses OpenGL it seems like this should be an easy thing to add.

Perhaps add a method to sf::Drawable like SetZ(float z)? If it's left at zero then the Z order is determined by the render order, otherwise it's predetermined by z.

Seems like a simple enough thing, it would really help in some situations.

Thanks.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
Re: Manually setting Z-order
« Reply #1 on: November 22, 2008, 07:29:56 am »
Quote from: "Imbue"
Seems like a simple enough thing, it would really help in some situations.

Giving some examples would really help your cause.

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #2 on: November 22, 2008, 09:19:54 am »
Sure, here's my current situation:

Drawables have a nice feature where any calls to Render inside of another Render inherit their parent's transformations. This make Drawables nice for creating hierarchies for character animation. For example, if you have a "body" object owning an "arm" object (which in turn owns a "hand" object), SFML can propagate any changes to the body's position down to the arm (Internally I believe this is just using OpenGL's matrix stack). The biggest problem of doing it that way is that it makes controlling draw order (and therefor Z order) difficult.

If you have any suggestions on how to otherwise accomplish this, please tell me.

On an only slightly related topic, why is sf::Drawable::GetMatrix() protected and not public? I feel that Matrices are a higher level concept and should be allowed for more use by the end user. The alternative is a call to GetPosition(), GetScale(), GetCenter(), and GetRotation(). Doesn't that seem like a lower level interface with less encapsulation?

BTW, I'm a noob at all this, so I'm definitely open to any suggestions.

Thanks. :D

bullno1

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Manually setting Z-order
« Reply #3 on: November 22, 2008, 09:50:52 am »
Z ordering is a "high level" concept. SFML is quite low-level. There is no "scenegraph" structure. You need to manually call window.Draw() on your Drawables so there's no way SFML can determine the order of drawing. I think this is a design decision, the author wants you to do it yourself and implement it the way you like. Thanks to that, in my engine, I can implement layers of sprite and different methods of ordering sprite within the same layer(based on z or based on y for 2D RPGs) .

Regarding the matrix thing, I have requested this before. For now, you can...
Edit the header  8) . There's no need to recompile. I believe that protected or private modifier only decides whether a method is "exported". Members are always exported or else how can the compiler know how to allocate memory when we create new objects?

Quote
If you have any suggestions on how to otherwise accomplish this, please tell me.

Order the list of sprite yourself. std::sort or std::list::sort should do the trick.

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #4 on: November 22, 2008, 10:26:56 am »
Quote from: "bullno1"
Quote
If you have any suggestions on how to otherwise accomplish this, please tell me.

Order the list of sprite yourself. std::sort or std::list::sort should do the trick.
Thanks, for you suggestion, but I think you missed the point of my example. SFML does give a "scene graph" like quality, and you can have complicated object hierarchies by using recursive sf::Drawable::Render calls. This nearly forces an arbitrary Z ordering, though.

If I instead throw my objects in a sorted container (like std::set) I lose this scene graph quality and would have to re-implement it myself. Honestly, I may and do just that. If I hack GetMatrix() to be public, it shouldn't be too tough to make a reasonable 2d scene graph.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Manually setting Z-order
« Reply #5 on: November 22, 2008, 11:41:30 am »
You mean you have a hierarchy of drawables, but this hierarchy defines an incorrect order of drawing ? Can you tell us more about this situation ?
Laurent Gomila - SFML developer

bullno1

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Manually setting Z-order
« Reply #6 on: November 22, 2008, 01:29:48 pm »
Quote
You mean you have a hierarchy of drawables, but this hierarchy defines an incorrect order of drawing ? Can you tell us more about this situation ?


I think he means that he create his own Drawable class which has children. In the render method of the parent, he calls the children's Render method. The children Render methods re-use the parent's transformation state and this enables a relative coordinate system and a hierarchy. However, by doing this, he cannot control the z-order since the children are always drawn before or after the parents. And the render order of parents also decides the order of their children

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Manually setting Z-order
« Reply #7 on: November 22, 2008, 01:47:01 pm »
That's exactly why I'm asking this question. Usually, one of the benefits of having a hierarchy is that it also defines a valid order of traversal for drawing.
Laurent Gomila - SFML developer

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #8 on: November 22, 2008, 06:59:27 pm »
Sure, say I'm looking at a side view of a person. This person's body has a left leg and a right leg. Since this is a side view, on leg should be drawn before (under - obstructed by) the body, and one leg should be drawn after (above) the body. That's still doable, but means the hierarchy is transversed several times and the code becomes messy.

So consider a tree like this for a character's lower body facing right (draw order parenthesized):
Code: [Select]

          body(3)
        /      \
left leg(2)    right leg(4)
left foot(1)   right foot(5)


So body needs to draw one leg, itself, and then the other leg. One leg draws it's child first, one leg draws it's child after. With a more complicated hierarchy, draw may have to be called multiple times on the some member. In a real situation I'd have the legs split, and also arms, and a head to deal with, at the very least.

More to the point, I'd like my character animation to simply read some rules from an XML file and do the right thing. I suppose the current situation could still be made to work OK, but it would be much easier to specify a Z order to SFML and make the transversal once.

I know that with SMFL the way it is now, I can draw anything. If you're going for an absolute minimal approach, I can respect that and work around it. I just think it would be cool to give the end user a choice of draw order, and passing a Z value to OpenGL. I suppose if you want to implement software rendering in the future, then Z order may be a bad thing.

Thanks.

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #9 on: November 22, 2008, 07:00:53 pm »
BTW, Laurent, whats the rational for hiding GetMatrix()?

Thanks.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Manually setting Z-order
« Reply #10 on: November 23, 2008, 12:03:18 am »
Matrices are usually hard to understand and to manipulate for beginners. I prefer providing helper functions which modify internal matrices indirectly.

Moreover, matrices initially didn't exist. They're just an implementation optimization; one day I might end up removing them for any reason. So they should never appear in the public interface.
Laurent Gomila - SFML developer

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #11 on: March 21, 2009, 04:35:55 am »
I'm working on my game again after a hiatus with another project.

This Z-ordering is still an issue for me. What is the best way to do what I'm looking for? If I draw in order, it seems that I'll have to forgo using nested Render() calls, which would be a shame. Any advice would be appreciated.

Surely other people have this problem. There must be a reasonable solution.

Why doesn't SFML allow arbitrary Z-ordering, though? It seems like it would be free, performance wise.

Thanks.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Manually setting Z-order
« Reply #12 on: March 21, 2009, 09:44:21 am »
Quote
Why doesn't SFML allow arbitrary Z-ordering, though? It seems like it would be free, performance wise.

SFML can't delay drawing operations in order to reorder them, and can't use Z-Buffer because it might not be available on some platforms. So, SFML can't do Z-ordering :)
Laurent Gomila - SFML developer

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Manually setting Z-order
« Reply #13 on: March 21, 2009, 10:13:57 am »
Laurent, thanks for the definitive answer.

I'm still looking for advice then, from anyone, on workarounds. Should I implement my own scene graph? Are there decent libraries out there for that already?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Manually setting Z-order
« Reply #14 on: March 21, 2009, 11:03:07 am »
Why not using a sprite manager (or something like that) to manage your Z-order ?
SFML / OS X developer