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

Author Topic: [Solved] Efficient way to draw different types of game objects.  (Read 2881 times)

0 Members and 1 Guest are viewing this topic.

Klungo

  • Newbie
  • *
  • Posts: 2
    • View Profile
[Solved] Efficient way to draw different types of game objects.
« on: December 11, 2013, 10:41:12 pm »
I'll try to be as clear as possible.

Background:
In the game I'm creating, there are several different types of game objects (tiles, walls, items, interactive objects like a door, fixed structures like a statue, players, etc). Each type can be expressed easily in their own separate image files. Say, Player.png stores the motions of a distinct character on each row, Tile.png and Wall.png stores all tiles in a grid-like fashion. Furthermore, walls can be a different size than tiles and fixed structures. All objects are around (50-200)x(50-200) pixels and each map can be up to 500x500 tiles. There will be many maps (only the player's current chunk will be drawn) and many of each category (i.e. 500-100 tiles, 200-300 items, etc).

Tiles can easily be implemented via a tile-map with the vertex array since they are always fixed and in the background.

On the other hand, walls and other fixed structures, although fixed, have to be in drawn in an order (picture a player standing behind a table but in front of a chair). And of course, the characters themselves are not fixed as they move around.

Since tile-maps can only use one texture at a time per draw call, I can't use it since all objects must be drawn in some unfixed order among different textures. I don't want to combine all textures into one file, but rather group them into these categories to avoid hard coding (especially since different categories may be added during development).

My question:
Is the attempt below efficient? Otherwise, what would you recommend? Would you recommend I merge tiles with the attempt or should I use two draw calls draw(tilemap) and draw(map_img) per frame?

Attempt:
At the start of the program, load each image: sf::Image tiles_img, sf::Image player_img, etc with their respective files. Each time I want to draw the map, I create an image sf::Image map_img that is as big as the screen. As I go along the coordinates, I determine which object should be drawn according to the order and use sf::Image::copy to copy the necessary instance from say, player_img, to the map_img. I repeat until I have no remaining object. Then I create an texture and LoadFromImage(map_img), create a sprite, setTexture, and then draw it.


I appreciate the help.


Solved
Did some research and implemented a variant of the Z-buffer algorithm (with additional constraints that suit my needs). The algorithm improved my FPS tenfold.

To add
The attempt algorithm above is bad for large maps. Do not use.
« Last Edit: December 13, 2013, 05:53:02 am by Klungo »

KarmaKilledtheCat

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: Efficient way to draw different types of game objects.
« Reply #1 on: December 12, 2013, 03:34:01 am »
You should create an image manager that stores all of the images so that you only have to load them in once per game run. This way you don't have to copy the image, which is extremely expensive on your game's speed.

Klungo

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Efficient way to draw different types of game objects.
« Reply #2 on: December 12, 2013, 04:03:32 am »
You should create an image manager that stores all of the images so that you only have to load them in once per game run. This way you don't have to copy the image, which is extremely expensive on your game's speed.

I'm not entirely sure what you mean. I do load all images necessary within their categories (a single image dedicated to all tiles, another dedicated to all walls, etc) at the beginning and never load them again. I'm curious if displaying the map's current state via copying the needed pieces from each image (a table from the objects image or a grass tile from the tiles image) onto a final map image and then calling a single draw on that map image per frame is an efficient way to handle the constraints mentioned above.


For the record, this is more efficient than switching textures and calling multiple draws per frame right?

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: Efficient way to draw different types of game objects.
« Reply #3 on: December 12, 2013, 10:47:17 am »
Quote
Since tile-maps can only use one texture at a time per draw call

I won't say that in general. You could use different vertexArrays for different textures/categories . If you have 1 or 30 draw calls doesn't matter.

Quote
(picture a player standing behind a table but in front of a chair)
Add different layers to your tilemap= Draw: BackgroundLayer -> Player -> ForegroundLayer

Quote
For the record, this is more efficient than switching textures and calling multiple draws per frame right?

I don't think so. Just draw your visible objects on the winow/rendertexture. You can easily have more than 2000 draw calls per frame on a modern hardware (And I don't guess that you have more than 2000objects in one scene).  premature optimization is the root of all evil try it and when you run into performance issues try to fix them.


AlexAUT

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Efficient way to draw different types of game objects.
« Reply #4 on: December 12, 2013, 02:58:15 pm »
premature optimization is the root of all evil try it and when you run into performance issues try to fix them.

Just to be clear, premature optimization is not evil. The love of premature optimization is the root of all evil  ;D
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor