SFML community forums

Help => Graphics => Topic started by: coder2k on January 07, 2013, 01:23:24 am

Title: What's the best way to draw a lot of sprites?
Post by: coder2k on January 07, 2013, 01:23:24 am
Hello everyone, this is my first post :)

I'm trying to create a game with an isometric map and I wonder what's the best way to draw it. At first I was drawing all tiles seperately but that was way too slow with a map size of (64x64 tiles). Then I thought I could draw all tiles to a RenderTexture first and just draw that onto the screen. Turned out well - worked really fast. But the problem is the limitation of the size of a RenderTexture. On my older PC I just can't create a RenderTexture that's big enough (and the middle-sized RenderTexutures are way too slow).
Any suggestions?
Title: Re: What's the best way to draw a lot of sprites?
Post by: eXpl0it3r on January 07, 2013, 01:40:17 am
In programming never ask for 'the best way', because there is no such thing, is always completely depends on what you want to achieve.

Generally you should try to reduce the draw calls, for this you can use sf::VertexArray and store all the needed information in there.

Additionally you'll also have to make a decision on how much backwards compability you want to support...
Title: Re: What's the best way to draw a lot of sprites?
Post by: coder2k on January 07, 2013, 01:46:05 am
Okay, you're right. But perhaps there is a "best way" for what I want to do.

To reduce the draw calls I drew the sprites onto a RenderTexture and then simply drew that onto the screen. As mentioned before: The maximum size could be a problem.
Can you explain how sf::VertexArray could help me? Isn't that one only for primitives like rectangles, etc? I need to draw images onto the screen. Or am I missing something?
Title: Re: What's the best way to draw a lot of sprites?
Post by: eXpl0it3r on January 07, 2013, 01:57:11 am
Can you explain how sf::VertexArray could help me? Isn't that one only for primitives like rectangles, etc? I need to draw images onto the screen. Or am I missing something?
What are images? Exactly quads/rectangle. ;)

With sf::VertexArray (or for more flexibility std::vector<sf::Vertex>) you define every point (vertex) of your image and apply the needed texture coordinate to it. Thus you can use one texture and one vertex array with one draw call, but display hundred or even thousands of 'images'. And since graphics card are build to handle millions of vertices the performance will be very good.

You can look at the documentation here (http://www.sfml-dev.org/documentation/2.0/classsf_1_1VertexArray.php) and some example code here (https://github.com/SFML/SFML/wiki/Source%3A-TileMap). ;)
Title: Re: What's the best way to draw a lot of sprites?
Post by: coder2k on January 07, 2013, 02:09:51 am
Thanks for those links! Definately will look into that...seems like the way to go. Have to refresh my C++ knowledge ;-)
Thanks for your support so far :)
Title: Re: What's the best way to draw a lot of sprites?
Post by: krzat on January 07, 2013, 02:51:33 am
Try this: http://pastebin.com/DjaXwD4t

Usage:
SpriteBatch sb;
sb.setRenderTarget(window); //initialization

for(int i=0; i < spritesCount; i++) //in your game loop
        sb.draw(sprites[i]);
sb.display();

 

Should be at least 2x times faster than standard drawing (if you use texture atlases).
If need this for tiles, you can skip sprites completly and use:
void draw(const Texture *texture, FloatRect dest, IntRect rec, Color color);
 
Title: Re: What's the best way to draw a lot of sprites?
Post by: masskiller on January 07, 2013, 03:07:09 am
Does Spritebatch allow the usage of individually transforming (positioning, rotating and scaling) each sprite?
Title: Re: What's the best way to draw a lot of sprites?
Post by: krzat on January 07, 2013, 03:21:58 am
Yep. It was meant to replace standard drawing (of sprites) completly.
Title: Re: What's the best way to draw a lot of sprites?
Post by: masskiller on January 07, 2013, 04:51:41 am
Is there any more code? From what I saw in the link there is some code that handles transformations, but no function that allows you to move each sprite individually as you'd like. I am asking because I am programming a similar class and I want to see different approaches towards it.
Title: Re: What's the best way to draw a lot of sprites?
Post by: krzat on January 07, 2013, 11:30:52 am
It takes a sprite, generates vertices from it and stores them in array. You have to redraw each sprite every frame.

As I understood, you want something different: keep track of all the sprites and update vertices only when something changes. The problem i see here, is that SFML doesn't support depth buffer, so each time you want to remove sprite(or insert it behind existing one), you have to rewrite both arrays (or implement depth buffer).
Title: Re: What's the best way to draw a lot of sprites?
Post by: masskiller on January 07, 2013, 03:29:45 pm
Quote
The problem i see here, is that SFML doesn't support depth buffer, so each time you want to remove sprite(or insert it behind existing one), you have to rewrite both arrays (or implement depth buffer).

This is a problem that has no good solution around it as deleting a member of a std::vector can usually be expensive. My use cases are mostly to initialize the container of vertices with a set quantity and discourage changing sizes. In my case for my own programming I wouldn't add any function for that kind of handling, but since it's going on the wiki I'll implement it just in case.

Eventually the container has the capacity of being reused, so once its usefulness is gone you just set a new texture and work it from there on what you need to do with it.

I do redraw the vertices everytime, just that I don't update their positions, rotation or anything else unless the programmer states that he wants to with the said functions. Like a class with a std::vector of sf::sprites would.
Title: Re: What's the best way to draw a lot of sprites?
Post by: Nexus on January 07, 2013, 08:00:47 pm
Try this: http://pastebin.com/DjaXwD4t
A few tips:
In general, make things simple, correct and bug-free before applying micro-optimizations that won't be noticable.
Title: Re: What's the best way to draw a lot of sprites?
Post by: krzat on January 07, 2013, 10:55:21 pm
Thanks for hints. Here is version with fixes: http://pastebin.com/Jk0m1VE8

This is port from C#, so some optimizations make less sense. I can't use Transformable because double wrapping (on C#) would destroy performance. This is why standard drawing is 3x times slower on .Net.

Drawing without lookup tables is 30% slower on C++ and 80% slower on C#. Current lookup has maximum error of 0,6% - IMO worth it.

I'm also happy to say, that C# version is as fast as C++.