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

Author Topic: [C#] TileMap renderer  (Read 23631 times)

0 Members and 1 Guest are viewing this topic.

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
[C#] TileMap renderer
« on: January 10, 2013, 04:58:08 pm »
Source: https://github.com/SFML/SFML/wiki/Source:-TileMap-Render

It's a tile renderer that doesn't pre-allocate vertices for every tile (useful for huge maps) and doesn't rebuild vertices every frame.

Somehow I've never seen this idea before. Instead of chunking (or creating vertex array of whole map), I use one vertex array to cover whole screen. Then I update in only when view area changed and new tiles have to be rendered.

The second trick:
if our screen has a width of 20 tiles max, then we will never see tiles 0:0 and 21:0 together. It means that tiles 0:0, 21:0, 42:0, etc. can occupy the same spot in vertex array.
« Last Edit: January 10, 2013, 05:17:22 pm by krzat »
SFML.Utils - useful extensions for SFML.Net

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [C#] TileMap renderer
« Reply #1 on: January 10, 2013, 05:02:08 pm »
I think it's a lie to say that your class is CPU effective, GPU effective and RAM effective. In general, if you optimize one you it gets worse for another. Your code is not CPU effective, compared to the usual solution of storing everything as a big static vertex array.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: [C#] TileMap renderer
« Reply #2 on: January 10, 2013, 05:13:59 pm »
Instead of chunking (or creating vertex array of whole map), I use one vertex array to cover whole screen. Then I update in only when view area changed and new tiles have to be rendered.
Could you explain that a bit further in both ways - what you've experienced that people use and what you've now implemented? :)

Also are you aware of the wiki guildline:
Quote
Licensing
After a community poll decision every source code on this wiki is under the Public Domain License, unless the author of the source code specified a different license. In that case the source code is under the license the author specified.
It's always better to include a notice under which license the provided code is, even though there exists a default one. ;)
« Last Edit: January 10, 2013, 05:18:22 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: [C#] TileMap renderer
« Reply #3 on: January 10, 2013, 05:15:25 pm »
I think it's a lie to say that your class is CPU effective, GPU effective and RAM effective. In general, if you optimize one you it gets worse for another. Your code is not CPU effective, compared to the usual solution of storing everything as a big static vertex array.
Good point. I will better remove these claims.

Could you explain that a bit further in both ways - what you've experienced that people use and what you've now implemented? :)
I added better description.

Usually, people for tilemap drawing use one sprite per tile, huge vertex array or batching every frame (as I was doing before). I have never seen implementation that works like mine.

Also are you aware of the wiki guildline:
It's always better to include a notice under which license the provided code is, even though there exists a default one. ;)
Thanks, I just included it.
« Last Edit: January 10, 2013, 05:35:51 pm 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: [C#] TileMap renderer
« Reply #4 on: January 10, 2013, 09:04:38 pm »
I think I'd rather waste few megabytes of ram(that's nothing these days) rather than risk CPU cycles if player runs at rocket speed through map.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [C#] TileMap renderer
« Reply #5 on: January 10, 2013, 10:12:30 pm »
It's not just a few megabytes of RAM, it's also a few CPU cycles every frame to upload these data to the graphics RAM, and a few GPU cycles to process the invisible geometry. I'm not saying one solution is better than the other, but these things must be considered.

Usually, a compromise is used: the map is still static, but divided into smaller chunks so that only the visible chunks can be drawn/processed/tested/whatever.
Laurent Gomila - SFML developer

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: [C#] TileMap renderer
« Reply #6 on: January 10, 2013, 11:59:10 pm »
I think I'd rather waste few megabytes of ram(that's nothing these days) rather than risk CPU cycles if player runs at rocket speed through map.
* it's not few if you have huge map: 8000x2000x2 -> 2,4 GB of vertices (80 Bytes per quad)
* What you mean by rocket speed? Assuming that you have 16px tiles and move 1000px per second, it's still just 2 columns/rows per frame max.
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: [C#] TileMap renderer
« Reply #7 on: January 11, 2013, 12:28:57 am »
Quote
* it's not few if you have huge map: 8000x2000x2 -> 2,4 GB of vertices (80 Bytes per quad)
Loading and discarding chunks as player moves around(minecraftian approach), adding tigh passes that serve as load zones (sourcian approach), using smaller maps,  using bigger tiles. The two former approaches give seamlessly 'unlimited' map sizes. But updating it every time view changes a few dozen pixels sounds like a weird way to do it. Keeping small rectangle in memory and loading more in the background as player moves(maybe even prepare chunks in other threads, using scoped arrays or something).
Quote
* What you mean by rocket speed? Assuming that you have 16px tiles and move 1000px per second, it's still just 2 columns/rows per frame max.
By rocket speed I mean so quick that you update your small array every few frames. ie view covering a lot of distance quickly. Static maps are practically free, all there is is bounding view to chunks plus the cost of at times loading chunks, on huge maps only.

There's also the crazy clever shader approach where you store your tiles in a single pixel each.
« Last Edit: January 11, 2013, 12:40:30 am by FRex »
Back to C++ gamedev with SFML in May 2023

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: [C#] TileMap renderer
« Reply #8 on: January 11, 2013, 12:59:14 am »
Hmm, maybe you don't realize how my implementation works.

I don't update everything every time view changes(btw. you should know that it is fast enough for most games). I update only rows or columns that appeared on the screen since last update. I would say, that it is even faster than static array,  cause I draw only tiles that are visible and with only one draw call. Your approach would draw whole chunk even if we see only one tile from it.
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: [C#] TileMap renderer
« Reply #9 on: January 11, 2013, 01:03:29 am »
Quote
I update only rows or columns that appeared on the screen since last update.
How does that work? You have array covering the screen then 0,0 goes out, 21,0 pops in there and it's now displayed to the right of 20,0, how?
Back to C++ gamedev with SFML in May 2023

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: [C#] TileMap renderer
« Reply #10 on: January 11, 2013, 01:58:06 am »
I wrap coords. I have offset variable which points to the tile in top-left corner of the view.

Assume i have visible area from 0,0 to 19,19 (size is 20,20).

Now I move x+1, so column 0 becomes invisible, but column 21 appears. View is 1,0 to 20, 19 now.

I don't need column 0 anymore, so i perform modulus on column 20: 20 % 20 = 0. Now i can insert column 20 into space left by column 0.


I made benchmark:

Visible area is 107 x 63 (16px tiles). Refresh indicates time spend on refreshing vertex array, Draw indicates time spend on drawing it. Refreshing one row or column has overhead less than 10% (compared to just drawing raw vertices). If we are moving very fast (9600 pixels per second) Overhead is around 50%. There are 53928 vertices in the array (two layers of quads).
« Last Edit: January 11, 2013, 02:01:32 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: [C#] TileMap renderer
« Reply #11 on: January 11, 2013, 02:02:05 am »
I see now. I was thinking of inserting 21 in 0s place like literally(without position change).
Back to C++ gamedev with SFML in May 2023

shackra

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
    • http://swt.encyclomundi.org
Re: [C#] TileMap renderer
« Reply #12 on: January 24, 2013, 01:48:28 am »
May can someone show me this code implemented in C++? My mind cannot wrap itself around C# code :(. After all, I am a python guy!

some help?

GNU User
Python programmer
Blog

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: [C#] TileMap renderer
« Reply #13 on: January 24, 2013, 04:11:20 pm »
SFML.Utils - useful extensions for SFML.Net

shackra

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
    • http://swt.encyclomundi.org
Re: [C#] TileMap renderer
« Reply #14 on: January 24, 2013, 06:15:30 pm »
Try this: http://pastebin.com/SrBE69EC

cool! :'D
Thanks, I'll try to wrap my mind in this code :)

GNU User
Python programmer
Blog