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

Author Topic: sf::VertexArray: Draw only vertices within certain bounds  (Read 3047 times)

0 Members and 1 Guest are viewing this topic.

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
sf::VertexArray: Draw only vertices within certain bounds
« on: July 06, 2014, 06:25:42 am »
I am using the code from the tutorial to draw a tile map and it works just fine.

Now, my level vertex array is getting pretty big and I only want to render tiles within certain bounds (those tiles that are currently in the view) instead of drawing all of them. The tutorial code has the following lines to draw the whole vertex array:

states.transform *= getTransform();
states.texture = &m_tileset;
target.draw(m_vertices, states);

How would I modify that code to draw only vertices that are, say, in an sf::IntRect(x, y, w, h) which I'd pass as a parameter?

I seriously have no idea. Could you please help me / start me off?

Thanks!

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: sf::VertexArray: Draw only vertices within certain bounds
« Reply #1 on: July 06, 2014, 06:50:35 am »
Is this performance hit something you are already experiencing now? Or is it something you fear will happen?

Either way, sf::VertexArray does not allow drawing sub-ranges of vertices. You can only draw all or none of them. This normally suffices since you would have a 1:1 mapping of an sf::VertexArray to an entity. Its usage in the context of tilemaps is something that is common, but that was not its originally intended purpose.

Before trying anything, you should really measure the performance of your application carefully. It might turn out that a performance hit might not even be caused by drawing the VertexArray but instead something else.

If you do determine that it is the VertexArray causing the performance drop, you have to bear in mind that on the GPU the vertices that are not within the viewport are culled anyway so you would only be saving on the cost of the data transfer by reducing the amount of vertices you draw. If this is really the bottleneck, you can either split your level up into multiple VertexArrays whose size is aligned to what is visible on the screen and perform CPU culling on a VertexArray by VertexArray basis. This way, you would only need to draw at most 4 VertexArrays to make sure your level is rendered seamlessly.

The second method, if you really have a lot of CPU time to spare, is to simply recreate the VertexArray every frame based on what is visible and draw it. The GPU wouldn't care because from its point of view, SFML is sending it new data every frame anyway.

The most important thing to do first is to measure. Premature optimization is often the root of almost all evil.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: sf::VertexArray: Draw only vertices within certain bounds
« Reply #2 on: July 06, 2014, 08:07:25 am »
Thank you for this extensive answer

I experienced no performance drops, I was just trying to optimise rendering the vertices like I do with other stuff, e.g. drawing objects only if they're on-screen.

For now I'll stick with a single vertex array then.

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: sf::VertexArray: Draw only vertices within certain bounds
« Reply #3 on: July 06, 2014, 11:20:17 am »
You can do it like this: http://en.sfml-dev.org/forums/index.php?topic=10249.0

Though, recreating array every frame is the most universal technique, because you can have animations and whatever you want. It's also fast enough if done right.
SFML.Utils - useful extensions for SFML.Net