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

Author Topic: Layers of graphics  (Read 10627 times)

0 Members and 1 Guest are viewing this topic.

mothmann

  • Newbie
  • *
  • Posts: 8
    • View Profile
Layers of graphics
« on: December 14, 2010, 06:21:50 am »
I've missed this in the tutorials or its not there. I didn't find what i wanted with the search function either

I want to take several sprites. Draw them on a layer. Then draw that layer onto the screen. I want to be able to move the layer around and it basically moves all the contained sprites. Not sure how this is done with SFML

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Layers of graphics
« Reply #1 on: December 14, 2010, 07:22:34 am »
You could first render it onto a RenderImage, export it as an image and link a sprite to it. Voila!

Anyway a bit more lightweight but more complex is that you create your own own drawable called Layer but with an array of Drawables inside it. Then these child drawables will inherit the proprties of the parent drawable when drawn. So if you move the layer the others will also be moved.

Code: [Select]

class Layer : public sf::Drawable
{
public:
/* Some public methods in order to interact with the layer */
protected:
        typedef std::vector<sf::Drawable *> DrawableList;
        // This example is written for SFML1 just so you know
        void Render(sf::RenderTarget &target)
        {
                for(DrawableList::iterator it = myDrawables.begin(), end = myDrawables.end(); it != end; it++)
                        target.Draw(*it);
        }
private:
        DrawableList myDrawables;
};


Though for this to work you have to draw the Layer, if you draw the sprites individually then they will only use their own position.
Code: [Select]
Layer myLayer;
myLayer.AddDrawable( mySprite ); /* My sprite comes from somewhere */
myLayer.SetPosition(50, 50)
myWindow.Draw(myLayer)
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

mothmann

  • Newbie
  • *
  • Posts: 8
    • View Profile
Layers of graphics
« Reply #2 on: December 14, 2010, 01:58:41 pm »
Render(sf::RenderTarget &target)

Im not really sure what this function is being used for since you showed no example of it being used. would the target not be itself?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Layers of graphics
« Reply #3 on: December 14, 2010, 02:09:34 pm »
The call is triggered by Draw, and the target is the window.

Basically, when you call window.Draw(drawable), it ends up in drawable.Render(window).
Laurent Gomila - SFML developer

mothmann

  • Newbie
  • *
  • Posts: 8
    • View Profile
Layers of graphics
« Reply #4 on: December 14, 2010, 03:01:14 pm »
sounds like the first option would be in the best. but im not sure how taxing it is.

its gonna be for tiles and didn't see the point in redrawing every tile every frame  and thats exactly what the class is doing.

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Layers of graphics
« Reply #5 on: December 14, 2010, 04:16:02 pm »
No it is not redrawing them it's just an indirection in drawing. This is needed in order to get a "layer". You need a object which contains the sprites inside the layer which will tell the sprites to be drawn when itself is being drawn. And in SFML, to keep it simple, you could say that any other drawable drawn inside a drawables Render method will inherit the position.

So if we write:
Code: [Select]

Layer layer;
layer.SetPosition( 500, 500 );
sf::Sprite sprite( /* Set image from somewhere */ );
sprite.SetPosition( 10, 20 );
layer.AddDrawable( sprite );

myWindow.Draw( layer ); // <- The sprite is drawn at (510, 520).
myWindow.Draw( sprite ); // <- The sprite is drawn a second time at (10, 20).


Here sprite will be drawn two times at two different positions. If we remove the last line then it will only be drawn once. See at the layer object as something abstract that is not directly viewable at the screen but the effects are.

I hope I'm clearer this time.

**EDIT**
Did you mean the sf::RenderImage? Sorry then yes it will be drawn a second time but there are several techniques that depends on that you render the data to a off-screen image before rendering it into frame. Though telling the graphic card to use a texture and apply it to a quad covering the entire screen is a simple process for the GPU. So shouldn't be much of a problem.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

mothmann

  • Newbie
  • *
  • Posts: 8
    • View Profile
Layers of graphics
« Reply #6 on: December 14, 2010, 06:46:13 pm »
But using the LAYER CLASS you provided.
in the main loop you would have something around

App.Draw(Layer)
App.Display();

meaning every sprite inside the layer will be drawn onto display using Layers post effects/specs Every loop. which is kinda what im wanting but i also didn't want to draw every individual sprite in every loop. instead i was looking to draw the sprites onto the layer once and said layer actually being a seperate sprite that is 1 large image that only has be drawn.  I think im understanding all this correctly. but the Layer class you provided still might be the faster way performance wise thats something im unsure of plus it seems to produce neater code. I will probalby end up using it till i finish the gameplay and start optimizing then make my descision


like to note i found this

http://www.sfml-dev.org/forum/viewtopic.php?t=1686&sid=9c77a66844aa8ba267c176c59a3d8930

after i was having trouble with this line of code

Target.Draw(*i);

noticed it has to be like this instead

Target.Draw(*(*i));


thats straight out of the wiki so they say.