SFML community forums
Help => Graphics => Topic started by: Nafffen on March 31, 2024, 06:50:16 pm
-
Hello,
Currently reading the tutorial about sprites and textures
https://www.sfml-dev.org/tutorials/2.5/graphics-sprite.php#the-importance-of-using-as-few-textures-as-possible
Using as few textures as possible is a good strategy, and the reason is simple: Changing the current texture is an expensive operation for the graphics card. Drawing many sprites that use the same texture will yield the best performance.
As far as I understand, it is not `setTexture` method of `sf::Sprite` that in expensive, it is the fact of drawing a sprite with a texture, then a sprite with another one.
Am I right ?
Thank you
-
That's right.
When you a draw something that uses a different texture to the previous thing drawn, the texture has to be swapped on the card and can be expensive.
Setting the texture of a sprite actually only stores a pointer so it's extremely lightweight; it's the draw that can be expensive.
-
Hey, thank you for your reply !
Just a following question, is the 'cost' of that texture change related to the size of the texture ?
For example, would it be more efficient to :
- have a big single texture for multiple objects but alternately used with other small textures (Big texture -> Small Texture -> Big Texture -> Small texture)
- have many small textures and alternately called them (Small Texture -> Small Texture -> Small Texture -> Small Texture -> ...)
-
I don't know the technically exact cost but larger textures should not incur a significantly larger cost to switch to or from - if any at all - than a smaller texture.
It's the switching that's costly but why it's costly and how costly it may be may or may not be partly related to its size.
The 'solution' to your question is a third option, re-order so that all the draws with the big texture are drawn next to each other (or even as one) and the small texture together the same way.
If they 'must' be drawn in this way, consider adding the small texture to the big texture.
With the 'alternating small textures', you could always combine them both into one, reducing the switching of textures and potentially reducing all of those alternating draw calls to just one.
Just remember, if you're trying to be efficient with your textures, use one at a time (avoiding switching) and draw multiple objects using that texture at once (avoiding excessing draw calls).
So, to provide a possible solution to your original post:
place the textures for both sprites into one image (you can do this programmatically if you'd like), and then load it to a texture. Then, draw each sprite with that same texture but use the texture rectangle (textureRect) to specify which part.
-
Very clear thank you very much !
-
Once you've 'sorted' the textures to avoid switching and all is left to do is group (batch) together the objects to avoid multiple draw calls, you can use this simple batcher (that I created):
https://github.com/SFML/SFML/wiki/Source%3A-Simple-Sprite-Batcher
It's simple to use (sprites only) and should always reduce time used to draw. The more sprites to batch, the more effective the batcher is!
Remember, though, that you can only batch sprites that use the same textures.