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

Author Topic: Wiki TileMap Question  (Read 2428 times)

0 Members and 1 Guest are viewing this topic.

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Wiki TileMap Question
« on: January 07, 2013, 10:37:28 pm »
Hello everybody,
I was reading though this post and I have a related queation. I want to implement a Tile Engine. I also think the best way to go is a vector of Vertices, because of the size limitation of the RenderTexture. In the thread mentioned above there is a link to a wiki page, that shows a example implementation using a vertex array. It looks good, but reading through it I was wondering one thing: Is the clipping necessary? Isn't it actually costing performance?
Because from my experience it's more efficient to draw a big Vertexarray (containing Quads) once instead of drawing a lot of quads. And if I understand the source code correct every quad inside the clipping range is drawn individually. The tile map would have to be huge in order for this to be more efficient than simply drawing the entire Vertexarray. Plus you have to execute the code for the clipping calculation every loop.
Maybe I'm missing something, but I was wondering and though maybe someone has a question for it.

Foaly


edit: Another question: Why are you using a 2 dimensional Array of sf::VertexArray's instead of one std::vector<sf::Vertex>?
« Last Edit: January 07, 2013, 10:39:09 pm by Foaly »

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Wiki TileMap Question
« Reply #1 on: January 07, 2013, 11:02:39 pm »
I swear, that this FRex on github is not me.. you believe me, right? :) No :(?
Well, ok.. Let's digest this post... and this code is not optimal, it's a basic example. If you really need a lot of performance(you don't, probably..) there is a shader based approach in projects subforum.
Quote
Is the clipping necessary? Isn't it actually costing performance?
Yes it is, in theory you're limited by ram, so you could have a map of 1024x1024 tiles, each being 32x32.
With default constants:
enum {tilesize=32,chunksize=32};//change values of these to match your needs and improve performance
that's sizeof(sf::Vertex)*4 mb + vectors cost. But if you drew everything with 60 fps, you'd be drawing and texturing 60 milions of quads per second = 240 milion vertices per second -That's a bit too much..

Quote
edit: Another question: Why are you using a 2 dimensional Array of sf::VertexArray's instead of one std::vector<sf::Vertex>?
And do what? Draw extreme amount of quads from across the map? I did do, in my editable tile map(not on wiki) single vector of arrays and just offset in the array and get right amount of vertices passed to draw, it was slower than this one, but it was easily editable.

Quote
Because from my experience it's more efficient to draw a big Vertexarray (containing Quads) once instead of drawing a lot of quads. And if I understand the source code correct every quad inside the clipping range is drawn individually
They are not drawn individually. arrays are drawn, each of them has chunksize*chunksize quads in them, or less if it's bottom or right edge of map. Matching constants makes big difference. I'm fairly sure for 32x32 tiles, 32x32 chunks are better than 64x64 or 16x16. I did little bit of tests, but only a litte.
And look at the sizes, 32 pixels per * 32 tiles per chunk = 1024 pixels per chunk side. That is quite a lot. In some bizzare scenario, like 2048x2048 view and most unfortunate position, you will draw 9 times. Usually less, and with normal views(ie. my 1360 wide, 700 something high screen) you will draw much much less(usuall 4 on fullscreen for me, 6 in unfortunate positions).

Oh, and the example uses the arrays from sf, I use vectors of vertices instead of SFML arrays so they can be optimized with reserve, usually they allocate up to 30% more memory than they actually use.
Oh2: there is a thread about my map example in wiki subforum ;)
« Last Edit: January 07, 2013, 11:33:16 pm by FRex »
Back to C++ gamedev with SFML in May 2023

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Wiki TileMap Question
« Reply #2 on: January 08, 2013, 11:17:49 pm »
I swear, that this FRex one github is not me.. you believe me, right? :) No :(?
[...]
[...] thread about my map example [...]
I was going to say of course I believe you, but you confused me... Are you the on from github?! :D

Alright to the post: I knew I was getting something wrong... (Really shoudn't have stayed up late and tried to understand other peoples code. looked at it this morning and understood it right away) For some reason I was missing the whole chunk part. So the map actually is divided into 32x32 sized chunks, each chunk made out of 32x32 pixel sized quads (default values). Using clipping the chunks inside the viewport are found and their vertex arrays are passed to the draw function. (The 2 dimensional array makes a lot of sense now...)
For some reason I was thinking the map is divided into quads and through clipping the quads inside the view are found and then passed to the draw function.
This obviously doesn't make of sense at all, that's why I was wondering.

I've seen the shader approach on the forum, but I think it's a little overkill and to complicated to implement. But I still want to use the most efficient solution using a vertex array. If you know an even more efficient solution for drawing tile maps than this, please let me know! The chunk approach seams very nice to me and i think it can safe you a lot of render time/power especially on big maps.

So the only way this code could be improved would be to use std::vector<sf::Vertex> instead of a sf::VertexArray to remove the vertex arrays overhead and also avoid unnecessary copying (using reserve()).

Another question:
usually they allocate up to 30% more memory than they actually use.
You mean the sf::VertexArray, right?!

Thanks for all the clarifications!
Foaly
« Last Edit: January 08, 2013, 11:26:06 pm by Foaly »

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Wiki TileMap Question
« Reply #3 on: January 08, 2013, 11:54:43 pm »
I have just finished fast tilemap renderer. It draws only visible tiles, supports multiple layers and maps of any size. It's both CPU and memory efficient.

Written in C#, but you should be able to port it: http://pastebin.com/S0Bbp2M8
« Last Edit: January 09, 2013, 12:00:10 am by krzat »
SFML.Utils - useful extensions for SFML.Net

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Wiki TileMap Question
« Reply #4 on: January 09, 2013, 12:02:13 am »
Quote
You mean the sf::VertexArray, right?!
vectors do, but you can shrink them with method in c++11, idiom or reserve up front. Since all c++ programmers love std::vectors Evil Laurent cuddled one and packed it into sf::VertexArray and then you can't do that to it.
Quote
I was going to say of course I believe you, but you confused me... Are you the on from github?! :D
Yes.
Quote
So the only way this code could be improved would be to use std::vector<sf::Vertex> instead of a sf::VertexArray to remove the vertex arrays overhead and also avoid unnecessary copying (using reserve()).
That can save some space overall and time loading. You might want to gut that class anyway and do your own thing with it like move texture out and so on, it's not that hard. If you really need to you can just use it as is and make your own loader class. Or you can port that C# code above or use shaders or whatever. 99% chances it'll not be a bottleneck but saving power to brute force something fancy and/or inefficient later is nice so take a pick.
« Last Edit: January 09, 2013, 12:18:05 am by FRex »
Back to C++ gamedev with SFML in May 2023