SFML community forums

Help => Graphics => Topic started by: The Terminator on April 05, 2014, 08:46:52 pm

Title: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: The Terminator on April 05, 2014, 08:46:52 pm
Hi there,

I have a couple questions on how to approach an issue I'm having. I have a tilemap that I just designed that draws ~3000 tiles, but slows to a crawl (~35 fps from 200 fps earlier). What I'm doing right now is having a "tile" be represented as a drawable sprite, and in its constructor the sprite is given a pointer to a texture in my resource manager. Because of this, only 1 texture has to be created per type of tile.

Now sf::Sprite is a very lightweight class, but I'm pretty confused as to why it's really bringing down fps, especially since there's an extremely low number of sf::Texture 's being used (Exactly 1, lol).

This brings me to my first question: why is this approach slowing down my program so significantly?

Second question: Would a sf::VertexArray be a much better approach? I'm pretty confused on how to define the vertices because my tile images are not packed into one sprite sheet, they're individual .png files.

Thanks!
Title: AW: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: eXpl0it3r on April 05, 2014, 09:28:16 pm
The issue is the number of draw calls that are being made (window.draw(x)). Each of them have a bit of overhead, thus if you do everything in one draw call, i.e. by using a vertex array, then you'll gain quite a bit of performance. ;)
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: The Terminator on April 05, 2014, 09:45:05 pm
Thanks for the response. Do you think you could give me an example of using the vertex array the way that I want it? I looked at the vertex array tutorial but I'm sort of confused on how the vertex array actually gets the pixel data and how to draw it.

Thanks again!
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: Laurent on April 05, 2014, 10:29:09 pm
A single vertex array can only use a single texture, but it is not a problem because this is exactly what you should do to get the best performances. Using one image per tile type is the worst strategy.
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: The Terminator on April 05, 2014, 11:06:14 pm
How do you pack the textures into one image in the tutorials Laurent?
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: coderx0x on April 05, 2014, 11:13:06 pm
How do you pack the textures into one image in the tutorials Laurent?

any picture editor
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: dabbertorres on April 06, 2014, 12:40:02 am
How do you pack the textures into one image in the tutorials Laurent?
You could even write a program using SFML that takes multiple files, and packs them together into a tilemap. I did that for making frame animated sprites.
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: Mutoh on April 06, 2014, 01:12:06 am
You could pre-render your level with a sf::RenderTexture and sf::Sprite combo, Terminator.  :) Like so:

class Level : public sf::Drawable {
        public:
                std::vector<Tile> m_tiles;
               
                sf::RenderTexture m_renderer;
                sf::Sprite m_preRendered;
               
                // ---
               
                sf::Vector2u getSize() const;
               
                Level::Level() {
                        // insert tiles into m_tiles
                       
                        m_renderer.create(getSize());
                        m_preRendered.setTexture(m_renderer.getTexture());
                       
                        for (Tile& tile: m_tiles) {
                                m_renderer.draw(tile);
                        }
                }
               
                void draw (sf::RenderTarget& tar, sf::RenderStates states) const {
                        tar.draw(m_preRendered, states);
                }
};

If you want your level to have, for example, moving platforms, or tiles that fall upon being stepped on, make them separate entities. If you want something almost Worms-like and want any of your tiles to be destructible, you could make it so that fixed portions of your level (with the altered Tile) are re-rendered, or something else.
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: zsbzsb on April 06, 2014, 01:46:23 am
You could pre-render your level with a sf::RenderTexture and sf::Sprite combo, Terminator.  :) Like so:

.....

That works, but with 3000 tiles I am pretty sure that is going to exceed the maximum texture size  ;)
Title: Re: A couple of questions regarding sf::VertexArray and sf::Sprite
Post by: The Terminator on April 06, 2014, 01:52:36 am
I did several optimizations in the rendering and updating of the tiles, and I brought my fps back up to about ~130 fps. I think I will stick with the approach I have because 3000 tiles will be like the max amount I will be drawing.

Thanks for all the responses!