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

Author Topic: Need help with render methods for different layers  (Read 3282 times)

0 Members and 1 Guest are viewing this topic.

Inflammatory Nugget

  • Newbie
  • *
  • Posts: 21
    • View Profile
Need help with render methods for different layers
« on: January 08, 2014, 09:37:27 pm »
Hello,

I am attempting to create a video game with a top-down perspective. However, I'm having trouble with finding the best way to render all of the graphics to the sf::RenderWindow. The environment should have 8 different layers:

-1: This is the floor.
-2: This layer includes objects that cannot be moved or rotated. Assets, one could call them.
-3: There should also be a layer for effects, such as some dust kicking up. All objects in this layer should be animations which are removed once finished.
-4: Layer 4 consists of all the characters and objects which the player or other characters can interact with.
-5: This layer has the same base as layer 2, however it includes objects which should be placed over the characters, such as a roof or a treetop.
-6: The final layer includes all the UI: buttons, health bars, indicators...
-7: This should be a layer for all sf::Texts. But by trial I learned that a std::vector<sf::Text*> is not the way to go, because of the many calls to sf::RenderWindow::draw().
-8: This layer consists of a single sf::Sprite that replaces the standard mouse cursor.

I imagine layer 1, 2 and 5 should be sf::VertexArrays, as the objects are static. I'm clueless over what way layer 3, 4, 6 and 7 should be rendered. Ideally, the environment of the game should be one big world with seamless transitions between areas. That means no loading screens or slowdowns during gameplay.

What would be the best render method for every layer? Are there too many layers? Am I asking too much?

Any help would be appreciated.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Need help with render methods for different layers
« Reply #1 on: January 08, 2014, 09:49:30 pm »
Ideally, you implement the layer architecture independent of the way how its contents are rendered, such that you can easily experiment with different approaches and only rewrite a small part of your code. In general, start with simple and small code and don't overengineer things for functionality you don't really need.

Keep in mind that while sf::VertexArray provides faster drawing, it adds a lot of book-keeping and synchronization overhead. When you to take dynamic objects and culling into account, you will be changing/rebuilding the vertex array all the time (but often, this may still be faster than drawing the elements one by one). So don't overuse it, sf::Sprite is fine for scenarios where you only have a couple of elements to draw.

A spatial division (such as a 2D grid with cells) is certainly a good idea if you have large areas. It allows effective optimizations for culling, collision detection, and other game logic.


This should be a layer for all sf::Texts. But by trial I learned that a std::vector<sf::Text*> is not the way to go, because of the many calls to sf::RenderWindow::draw().
How many texts did you have before the performance of rendering them became an issue? And what's the alternative?

By the way, std::vector<sf::Text*> is never the way to go, because it requires manual memory management. Use std::vector<sf::Text>. In situation where you need pointers (e.g. for polymorphism), use unique pointers: std::vector<std::unique_ptr<sf::Drawable>>. If you're interested in the rationale behind that, you might want to look at RAII and possibly some other topics I listed here.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Need help with render methods for different layers
« Reply #2 on: January 08, 2014, 10:40:03 pm »
I would go with simplest approach.
1. If you want big world, you will definitely need spatial partitioning. Grid would be the easiest. QuadTree sounds fancy, but isn't always better.
2. Tilemaps use spatial partitioning by definition, so you don't have to insert separate tiles to another grid/tree (waste of memory and CPU).
3. Layers 6 - 8 can be IMO grouped as one thing - GUI. Not sure what those text objects are. Console?
4. Layer 1 one is probably tilemap, so see point 2.
5. Layers 2-5 should go into your spatial partitioning structure. Give each object some layerID so you can sort them later. They can be sprites.

Then, every frame:
1. Get visible region of tiles, write them to vertex array and draw (you should reuse one array).
2. Get visible objects from your grid/tree, sort by layer and draw.
3. Draw GUI hovever you want.

Note: try not to change texture between draw calls, use sprite sheets.
Note: group your particles (layer 3) by source so they don't take too much space on grid/tree.

EDIT: I recently updated my spritebatch, which my help. Sprites are quite heavy so usually it's better to generate vertices directly.
« Last Edit: January 08, 2014, 10:50:09 pm by krzat »
SFML.Utils - useful extensions for SFML.Net

Inflammatory Nugget

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Need help with render methods for different layers
« Reply #3 on: January 09, 2014, 10:01:18 pm »
Alright, thank you both for your help and suggestions.
Quote
How many texts did you have before the performance of rendering them became an issue? And what's the alternative?
I haven't tried to find the maximum amount of sf::Text objects before slowdown kicks in. I came to the conclusion that you should try to limit the amount of calls to sf::RenderWindow::draw. Is this incorrect?

Also, could sf::RenderTexture serve a purpose in my program?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Need help with render methods for different layers
« Reply #4 on: January 09, 2014, 10:42:44 pm »
I haven't tried to find the maximum amount of sf::Text objects before slowdown kicks in. I came to the conclusion that you should try to limit the amount of calls to sf::RenderWindow::draw. Is this incorrect?
No, it's correct, but don't make it a dogma. Compare draw calls to possible alternatives and decide for each situation what works best. Obviously, you can't do much about some texts that just have to be drawn. For a few texts, this won't be a problem at all.

Render textures to pre-render texts would complicate everything massively and would probably not contribute critically to a performance improvement.
« Last Edit: January 09, 2014, 10:44:17 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: