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

Author Topic: Does SFML batch render draw calls?  (Read 17589 times)

0 Members and 1 Guest are viewing this topic.

TechnoCore

  • Newbie
  • *
  • Posts: 3
    • View Profile
Does SFML batch render draw calls?
« on: January 06, 2009, 05:50:34 pm »
When i draw more than around 1000 sprites each frame, the app really slows down. Why? Is there no batching of the draw calls?

I should be able to draw *a lot* more than that, should i not? Maybe I am doing something wrong.

My app is in C++, on an Intel quad 9550, with the radieon 4870 gfx card.

Thanks for any help!

/ TC :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Does SFML batch render draw calls?
« Reply #1 on: January 06, 2009, 07:05:43 pm »
There's no batching, because SFML is too low level (i.e. it has no global knowledge about what you're drawing). How would you batch with the current interface? After you call window.Draw(sprite) you expect your sprite to be drawn on screen, not to be put in a list-to-be-rendered-some-time-later. Moreover, the order of call defines the order of drawing, so the triangles can't be reordered to allow batching.

A class will probably added to handle explicit batching, for systems such as tiles or particles. By the way, it's already in the roadmap ;)
Laurent Gomila - SFML developer

irri

  • Newbie
  • *
  • Posts: 18
    • View Profile
    • http://www.irri.se
Does SFML batch render draw calls?
« Reply #2 on: January 06, 2009, 07:16:11 pm »
Hmm.. is this the same as I'm experiencing in my game ( http://www.sfml-dev.org/forum/viewtopic.php?t=830 )???
I call the draw-method at least around 140 times per frame. And it goes really slow on my laptop.
2D RPG Game (School project): http://PA.irri.se/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Does SFML batch render draw calls?
« Reply #3 on: January 06, 2009, 07:20:49 pm »
Probably, even if 140 rendering calls is not really a lot to handle for the GPU.
Laurent Gomila - SFML developer

TechnoCore

  • Newbie
  • *
  • Posts: 3
    • View Profile
Does SFML batch render draw calls?
« Reply #4 on: January 07, 2009, 11:28:22 am »
Thanks for your quick answer :)

I see the problem with the ordering. Nice to hear about the batching class.

So I could then maybe create a batch and add sprites to it, like:
my_batch.AddSprite( sprite )

...and when i want to draw all sprites in the batch i just call like Window.DrawBatch( my_batch )

Or ?

/TC :)

TechnoCore

  • Newbie
  • *
  • Posts: 3
    • View Profile
Does SFML batch render draw calls?
« Reply #5 on: January 07, 2009, 11:49:16 am »
Quote from: "irri"
Hmm.. is this the same as I'm experiencing in my game ( http://www.sfml-dev.org/forum/viewtopic.php?t=830 )???
I call the draw-method at least around 140 times per frame. And it goes really slow on my laptop.


Yeah, its because there is one draw-call per sprite. The graphics card can only handle around 1000 draw-calls per frame (or something like that) after that it will slow down alot.

In order to optimize things you can send a chunk (a batch) consisting of many sprites at the same time in a single draw-call. This is called batching.

Optimal size of a batch is something like 1000 vertices, and a sprite would consist of 4 vertices. (4 corners ), so maybe 250 sprites per draw-call could be rendered without any penalties in speed. 250 sprites  * 1000 draw calls = 250.000 sprites / frame on a modern gfx card.

And just like Laurent says it's in the to-do list :)

Pfhreak

  • Newbie
  • *
  • Posts: 11
    • View Profile
Does SFML batch render draw calls?
« Reply #6 on: February 03, 2009, 11:12:04 pm »
So, I have a corollary to this. I'm building an asteroids-esque game, and I want to have stars flying by in the background with parallax, hue, etc.

Currently, I just a 1x1px png for my star, and an array of sprites to accomplish what I want. So my Background.Draw() method looks something like:

Code: [Select]

for (int i = 0; i < MAX_STARS; i++)
{
  renderWindow.Draw(_stars[i]);
}


I've looked at my code using two different profilers, and this is where I am spending the majority of each frame. Setting MAX_STARS above 100 or so really impacts the framerate. Is there a better way to do this?

Eventually, batching will solve this problem, right?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Does SFML batch render draw calls?
« Reply #7 on: February 03, 2009, 11:25:56 pm »
Absolutely.
Laurent Gomila - SFML developer

Pfhreak

  • Newbie
  • *
  • Posts: 11
    • View Profile
Does SFML batch render draw calls?
« Reply #8 on: February 03, 2009, 11:31:13 pm »
For now, the workaround I've found is simply to have my background class contain 1 sf::Image that I change the pixels of. Every Update() I write all the star pixels black, change all my structs, and write their new locations white.

It's resulted in a 10x improvement in framerate, and it allows me to draw many more stars.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Does SFML batch render draw calls?
« Reply #9 on: February 04, 2009, 12:19:56 am »
What about shapes? Are they subject to the same problem, too?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Does SFML batch render draw calls?
« Reply #10 on: February 04, 2009, 07:50:27 am »
Quote
What about shapes? Are they subject to the same problem, too?

What makes rendering several drawables slow, is that each object has its own set of render states, and reseting OpenGL states is what eats most of the performances. So, same problem for shapes. They might be slightly faster because they don't use textures.

Quote
For now, the workaround I've found is simply to have my background class contain 1 sf::Image that I change the pixels of. Every Update() I write all the star pixels black, change all my structs, and write their new locations white.

It's resulted in a 10x improvement in framerate, and it allows me to draw many more stars.

Even better optimization: create a Background class which inherits from sf::Drawable, and draw your stars using OpenGL commands in its Render function. You'll be able to draw millions of them ;)
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Does SFML batch render draw calls?
« Reply #11 on: February 04, 2009, 01:32:13 pm »
The same goes for tilemaps. Maybe it'd be a good idea to create a new class from sf::Drawable that constructs a connected mesh (flat terrain) and applies the proper textures, thus rendering all the stuff in a row.

I'm not an OpenGL expert and I've only used it rarely directly,  but what about display lists? Can't they just be created around Draw() calls for compiling them?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Does SFML batch render draw calls?
« Reply #12 on: February 04, 2009, 01:45:34 pm »
Quote
I'm not an OpenGL expert and I've only used it rarely directly, but what about display lists? Can't they just be created around Draw() calls for compiling them?

It doesn't improve performances.

I've basically tested all optimizations that don't involve major code changes (using display lists, using a state manager to avoid setting multiple times the same state, precomputing as much as possible), but nothing is enough. That's why I have to introduce a new concept in SFML, which is batching.
Laurent Gomila - SFML developer

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
Does SFML batch render draw calls?
« Reply #13 on: February 04, 2009, 02:01:32 pm »
Quote from: "Laurent"
What makes rendering several drawables slow, is that each object has its own set of render states, and reseting OpenGL states is what eats most of the performances.

Can't you keep the same render states as much as possible ?
This means testing the state with glGet*/glIs* and enabling/disabling only when needed.

Edit: testing is not the point. I just mean not enabling and disabling everything for each Draw() call.

Quote from: "Laurent"
After you call window.Draw(sprite) you expect your sprite to be drawn on screen, not to be put in a list-to-be-rendered-some-time-later.

Nah, I expect the sprite to be drawn when calling Display(), so maybe you could put everything that needs to be drawn in a list and draw all that only when calling Display().
Want to play movies in your SFML application? Check out sfeMovie!

dabo

  • Sr. Member
  • ****
  • Posts: 260
    • View Profile
    • http://www.dabostudios.net
Does SFML batch render draw calls?
« Reply #14 on: February 04, 2009, 02:30:19 pm »
When batching is available will you gain anything from it even if you don't draw a lot of sprites? Will batching improve performance on all drawables (including strings)? How many sprites can you draw before you notice a performance decrease? I don't use a lot of sprites, I do draw a lot of text how ever.