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

Author Topic: Drawing Hextiles is slow  (Read 2707 times)

0 Members and 1 Guest are viewing this topic.

Devast8or

  • Newbie
  • *
  • Posts: 2
    • View Profile
Drawing Hextiles is slow
« on: March 05, 2016, 11:37:16 pm »
Hi

I just recently started to experiment with SFML and the idea I have is to build a 2D top down game using hexagonals. I initially started with the idea to build a map editor before I proceed with the game itself. Everything has been working fine until I tried to generate maps larger than 20 * 20 hexes.

In the first test I tried to draw hexes on each screen refresh which resulted in low fps, then I thought well it's a map it will not change so it doesn't have to be redrawn on each frame so I drew it to a texture but it is still slow. To give you an idea a map consisting of 100 * 100 hexes takes approx 16 minutes to draw..

I designed two classes a hex class and a map class.
The hex class derives from sf::ConvexShape and contains a convex shape as one of the members, I'm using it to construct each and every hex.

The map class is built as following
class MAP {
private:
   int rows = 10;
   int columns = 10;
   std::vector<std::vector<HEXTILE>> combatmap;
   
Here I'm using a 2D vector to store each and every HEXTILE object. These are iterated, each hex is given proper x/y coordinates and itsĀ“corners are calculated and stored in a sf::Vector2f.
I'm then calling following method when iterating through the  array.

const sf::ConvexShape& ReturnHex(int r, int c) const { return combatmap[r][c]; }

When drawing I'm using following syntax.

for (int r = 0; r < test.ReturnMap().size(); r++)
   {
      
      size = test.ReturnMap().size();
      for (int c = 0; c < test.ReturnMap()[0].size(); c++)
      {         
         texture.draw(test.ReturnHex(r, c));      
      }
      
   }

I realize that I've probably selected wrong way to implement this but I'm kind of stuck. This is the first time I'm actually working with graphics so the whole concept of drawing/refreshing etc is fairly new to me.. Do I have to go with vertex arrays? I want each hex to be drawn with specific properties like X/Y coordinate, texture etc..

Since it's a map editor the user should be able to create a map with X*Y hexes then change textures in each hex by selecting a terrain type and then clicking on the hex.



DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Drawing Hextiles is slow
« Reply #1 on: March 06, 2016, 04:23:16 pm »
I think you can use vertexArray and draw it from one draw call.

Or try to use:
 texture.setRepeated( true )
« Last Edit: March 06, 2016, 04:25:38 pm by DarkRoku »
I would like a spanish/latin community...
Problems building for Android? Look here

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Drawing Hextiles is slow
« Reply #2 on: March 06, 2016, 06:31:09 pm »
If drawing tenthousand anything takes minutes and not milliseconds then you are doing something horribly wrong somewhere. That much is obvious.

You say that 400 is ok'ish but 10000 is horrible. Do you perhaps have some code that's O(n2) - with 'n' being the number of hex tiles - (or worse) somewhere?

Are you sure you are testing a release build with optimization enabled? Not that I would expect performance with a unoptimized debug build to be that horrendous, but it's still worth checking.

Are you sure your graphics card drivers are up-to-date - they can impact performance.

Some links you should read regarding hex maps:
http://www.redblobgames.com/grids/hexagons/
http://www.gamedev.net/page/resources/_/technical/game-programming/coordinates-in-hexagon-based-tile-maps-r1800

PS. If your compiler supports it, I'd advice using modern C++11/14.
« Last Edit: March 06, 2016, 06:35:13 pm by Jesper Juhl »

Devast8or

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Drawing Hextiles is slow
« Reply #3 on: March 07, 2016, 10:42:30 pm »
Thanks for your comments guys. I switched from debug-mode and it went down from 16 minutes to 2 minutes! Huge improvement but still long time for such a small map. I identified the delay to be located in drawing for loop for vector columns

 for (int c = 0; c < test.ReturnMap()[0].size(); c++)
      {         
         texture.draw(test.ReturnHex(r, c));     
      }

For some reason the test.ReturnMap()[0].size() call makes the whole loop sluggish.
When switching to a number (100) the time to draw 100 * 100 hexes went down to 1.9 seconds.
I still think it's slow if you go higher like 500 * 500 hexes, at 1000 * 1000 hexes it actually crashes and throws an exception.

texture.setRepeated( true ); improved the speed by 0.5 sec for 100*100 map.

If I use vertexArray do I get same functionality as with sf::ConvexShape?



Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing Hextiles is slow
« Reply #4 on: March 08, 2016, 02:41:14 am »
If the size condition is slow, calculate it before the loop and then use the pre-calculated version for the loop (it checks it every iteration). In your original post, it looks like you attempted to pre-calculate it but then didn't use that value for the condition.

That said, if "ReturnMap()" actually returns the map, does it return a copy of the map? Copying the entire map each time could cause delays. Instead, consider creating a method that just returns the size without returning the map.

Vertex Array is the most flexible way within SFML to draw things. It can do all of the things that all the other shapes can do. For this flexibility and power, though, you forfeit some ease of use as a lot of the conveniences disappear. Mastering vertex arrays (they are quite simple but can be daunting at first) greatly increases what you can do with SFML.
"Do I get [the] same functionality as with sf::ConvexShape?"
Using a vertex array with primitive type of triangle fan can create convex shapes in the same way.
However, with a vertex array, you can have many multiple triangles in one object and then draw them all at once (one draw call).

Read the Vertex Array tutorial to become accustomed to what they do and how they work.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*