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

Author Topic: Terrain Layers  (Read 10710 times)

0 Members and 2 Guests are viewing this topic.

stulleman

  • Newbie
  • *
  • Posts: 12
    • View Profile
Terrain Layers
« on: January 27, 2015, 05:55:56 pm »
Hello!

I'm building a little game (Top Down) with procedural terrain generation. (I'm coming from Unity and c# so I'm learning c++ and sfml while reproducing projects from the past  ;). And of course I learned c++ with other tutorials)

So my design looks like this:

I have a World class, that stores all my Chunks. My World is drawable, and my chunks as well. So i simply have to call window->draw(*world) to draw my world.
My chunks have VertexArrays to store the mesh.

My problem is when it comes to terrain layers. I want some things like vegetation to be drawn over the ground layer. Since we are in 2d I can only overdraw what is already on the screen, right? But wouldn't that mean I would double or triple drawcalls?

Is there maybe another approach for terrain layers?

Thanks in advance!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Terrain Layers
« Reply #1 on: January 27, 2015, 07:13:17 pm »
Hello!
Hi! :)

Since we are in 2d I can only overdraw what is already on the screen, right? But wouldn't that mean I would double or triple drawcalls?
Not true actually. Your vertex arrays draw the primitives in the order that they are stored in the vertex array but there is nothing stopping you from placing vertices/primitives that overlap/cover previously drawn primitives.

Simply put, put the back stuff at first in the vertex array and the front stuff at the end of the vertex array.

Thanks in advance!
You're welcome in advance :P
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

stulleman

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Terrain Layers
« Reply #2 on: January 27, 2015, 09:39:24 pm »
Ah I see. I'm not ready to test it because it's a lot more work in c++ compared to Unity ;)
But therefore you get more flexibility. I'll get there and if I have problems I'll come back :P
Thank you!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Terrain Layers
« Reply #3 on: January 27, 2015, 09:48:22 pm »
compared to Unity
Unity is a game engine. SFML is a multimedia library (not an engine). They shouldn't be compared :P

Typically, a number of classes wouldn't share a vertex array so it would become that multiple draw calls would be required to display multiple classes. I'm not sure why you are worried about an extra draw call or two. It's when you hit hundreds, thousands or even tens of thousands that you should probably be concerned.

Just to clarify, a single vertex array (which can have many vertices and therefore many primitives) only requires one draw call to display it.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

stulleman

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Terrain Layers
« Reply #4 on: January 27, 2015, 10:25:53 pm »
Oh okay!

I don't share a vertex array. My world instantiates many chunks and each chunk has it's own 16x16 vertex array.
That's something I used to do in Unity and I simply adapted it thinking it's the best method, isn't it?
Because of that I'm worried of draw calls. Because if you have 10 x 10 chunks you have 10x10 draw calls right?
It's not 1 draw call for the world.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Terrain Layers
« Reply #5 on: January 27, 2015, 11:19:55 pm »
If each chunk has its own vertex array and therefore a draw call then yes, 100 chunks would be 100 draw calls.
You may want to consider batching the chunks into one vertex array to draw only once instead of a hundred times.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Terrain Layers
« Reply #6 on: January 27, 2015, 11:31:49 pm »
You might want to do some tests to determine if it actually matters.
If a few hundred draw calls still gives you acceptable performance - who cares?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Terrain Layers
« Reply #7 on: January 27, 2015, 11:38:15 pm »
This is just for the terrain. Add to that the extra layers as mentioned above such as "vegetation" (which could double - or more if there are more layers - the number of draw calls of the terrain), and then the HUD, players, NPCs, enemies, projectiles, effects... (you get the idea), then draw calls would very probably be into the higher hundreds, possibly thousands.
Wouldn't it also be a good time to learn about how to use a vertex array in a more effective way rather than "only using what I already know"?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Terrain Layers
« Reply #8 on: January 27, 2015, 11:41:54 pm »
Sure. But there's also value in sometimes measuring things to determine if they are "good enough" and then move onto more important stuff and actually meet deadlines. It's easy to get sidetracked into microoptimizations that don't actually matter and waste a lot of time.
And in MHO, a few thousand draw calls is not often the main drain on performance - physics, AI, pathfinding and similar tends to take that place.
As always: profile, measure, test and make informed choices.
« Last Edit: January 27, 2015, 11:49:03 pm by Jesper Juhl »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Terrain Layers
« Reply #9 on: January 27, 2015, 11:46:29 pm »
True.
If you don't know it, you should learn it.
Once you know it, you probably won't need to use it.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

stulleman

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Terrain Layers
« Reply #10 on: January 28, 2015, 12:19:33 am »
I will consider both. I will not try to over optimize it.
But the idea of just one draw call for the whole terrain sounds good. I just don't know how I would do it. Since I separated the chunks for a reason, and this is that it is fast to update them.
Do you have any ideas how this could be done?

Ztormi

  • Jr. Member
  • **
  • Posts: 71
  • Web developer by day. Game developer by night.
    • View Profile
Re: Terrain Layers
« Reply #11 on: January 28, 2015, 12:17:39 pm »
I think you are overcomplicating things if you are using chunks with N-layers as vertex arrays.
What if there is tree sprite on the very edge of the chunk? Let's say you are drawing chunks from left to right and your tree is placed to the right border of your first chunk. Now when the second chunk is drawn it will be partially drawn on top of the tree.

In my opinion you should either:

a) Use chunks, but have all the layers stored in separate vertex arrays. The order of drawing would then be:
Left ground chunk>Right ground chunk>Left Scenery chunk>Right scenery chunk etc.
b) Ditch the chunks and use one vertexarray for each layer, draw layers from bottom to top.
c) Ditch the chunks and store all layers in one vertex array.

C would probably be the fastest of these but I'm with Jesper Juhl here. Just go with what feels most logical and easiest to you. Using vertexarrays at all should yield good perfomance already.

Edit:

I prefer option b because:
- It looks good in code and makes sense
- I can use different shader for each layer
- I can use different spritesheet for each layer

« Last Edit: January 28, 2015, 12:25:46 pm by Ztormi »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: Terrain Layers
« Reply #12 on: January 28, 2015, 12:23:51 pm »
I think one draw call per layer is very well acceptable. Anything lower and you'll probably end up reorganizing vertices longer as it would take to make a draw call.

When it comes to 2D drawing with SFML you essentially end up with one rule: Whatever you draw last will be drawn on top of the rest.
One possibility you have is to pre-render certain bits, by using a render texture.

Thus if you want just one draw call, you'll have to add everything to ond vertex array and you need to sort and arrange the vertices the order they need to be drawn in.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

stulleman

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Terrain Layers
« Reply #13 on: January 28, 2015, 11:43:03 pm »
Yes I'm totally okay with one draw call per layer.
But I'm not sure how I would organize my terrain without chunks like Ztormi suggested?

I'll explain what I have planned:

I have a big array in my world class where the current loaded terrain data (1 byte for each type) is stored.
I have planned to let it be as big as the player can see + a margin for not loading from disk all the time.

Now I have chunks, that know their position and where to get their information from the world class array. So whenever I want to edit the terrain I'll simply have to edit the array and tell the chunk that is responsible for this area to update it's vertex array.

If I understand you right Ztormi, you would suggest a vertex array that covers the whole area the player can see? But if I move to one side, this would mean a rebuild of the whole array. Or did you have something else in mind?

Thanks for the suggestions and help so far!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Terrain Layers
« Reply #14 on: January 29, 2015, 01:06:05 am »
You could have an class object that holds all of the chunks and the final vertex array and then each chunk would be able to update the same vertex array.

Rebuilding a vertex array is pretty quick. It would be slow to clear it and push back each vertex each time, but working out how many vertices you need and resizing it to that once each cycle is unlikely to cause much of a problem.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*