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

Author Topic: 8x8 tiles and big map, bad idea? [Solved]  (Read 6032 times)

0 Members and 1 Guest are viewing this topic.

Guido_Ion

  • Newbie
  • *
  • Posts: 42
    • View Profile
    • Flow Soccer development
8x8 tiles and big map, bad idea? [Solved]
« on: June 25, 2015, 05:22:25 am »
Hi, I've been working with SFML for some months now and some weeks ago I started to do the tileset for my game. I began by making 64x64 tiles and everything was working fine but now I need to do 8x8 tiles so I can create very detailed figures, but with tiles this small I need to do big maps, something like 300 * 120 tiles which gives a total of 36000 tiles!! of course this dropped my frames to a little bit more than 30 (before it was >200).

From what I know this 36000 tiles means 36000 calls to draw() which is expensive to the CPU, is that correct?

The question is: is there another way to do this or I need to go to bigger tile sizes?

It would be good to be able to use small tiles because I want to create circuits (like those of a motherboard), what I'm doing now is every tile is a small segment of a circuit (straight line, curve, circle, etc.) and I create different circuits with each segment.

« Last Edit: June 25, 2015, 10:01:52 pm by Guido Bisocoli »

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: 8x8 tiles and big map, bad idea?
« Reply #1 on: June 25, 2015, 05:32:06 am »
You're probably going to want to use vertex arrays. They are meant for this situation. http://www.sfml-dev.org/tutorials/2.3/graphics-vertex-array.php

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: 8x8 tiles and big map, bad idea?
« Reply #2 on: June 25, 2015, 07:02:03 pm »
My suggestion would be, store the tiles in one sf::VertexArray.
And then draw X vertices to optimize drawing, and allow you to have almost infinite map size (As long as your ram allows it)

And draw using this, i copy it from documentation, its a sf::RenderWindow::draw
Code: [Select]
void draw (const Vertex *vertices, std::size_t vertexCount, PrimitiveType type, const RenderStates &states=RenderStates::Default)

it would be something like this
Code: [Select]
for(y...)//Column
{
   for(x...)//Row
   {
      renWin.draw(...);
   }
}
« Last Edit: June 25, 2015, 07:05:19 pm by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Hapax

  • Hero Member
  • *****
  • Posts: 3387
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: 8x8 tiles and big map, bad idea?
« Reply #3 on: June 25, 2015, 07:13:53 pm »
draw using this, i copy it from documentation, its a sf::RenderWindow::draw
Code: [Select]
void draw (const Vertex *vertices, std::size_t vertexCount, PrimitiveType type, const RenderStates &states=RenderStates::Default)

it would be something like this
Code: [Select]
for(y...)//Column
{
   for(x...)//Row
   {
      renWin.draw(...);
   }
}
This kind of goes against your reason for using a vertex array. You still have all the draw calls for each tile.

A vertex array can hold many vertices and therefore all of the (visible) tiles at once. Then, there's no need for a loop; you just call draw on the vertex array and it draws them all.

There is a tile map example in the vertex array tutorial.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Guido_Ion

  • Newbie
  • *
  • Posts: 42
    • View Profile
    • Flow Soccer development
Re: 8x8 tiles and big map, bad idea?
« Reply #4 on: June 25, 2015, 08:57:31 pm »
Thanks all, I'm using this Tiled Map Editor to SFML/Box2D converter (http://trederia.blogspot.co.uk/2013/05/tiled-map-loader-for-sfml.html) and apparently it uses Vertex Arrays to draw as seen here:

Quote
void MapLoader::Draw(sf::RenderTarget& rt, MapLayer::DrawType type, bool debug)
{
   m_SetDrawingBounds(rt.getView());
   switch(type)
   {
   default:
   case MapLayer::All:
      for(const auto& l : m_layers)
         rt.draw(l);
      break;
   case MapLayer::Back:
      {
      //remember front of vector actually draws furthest back
      MapLayer& layer = m_layers.front();
      m_DrawLayer(rt, layer, debug);
      }
      break;
   case MapLayer::Front:
      {
      MapLayer& layer = m_layers.back();
      m_DrawLayer(rt, layer, debug);
      }
      break;
   case MapLayer::Debug:
      for(auto layer : m_layers)
      {
         if(layer.type == ObjectGroup)
         {
            for(const auto& object : layer.objects)
               if (m_bounds.intersects(object.GetAABB()))
                  object.DrawDebugShape(rt);
         }
      }
      rt.draw(m_gridVertices);
      rt.draw(m_rootNode);
      break;
   }
}

void MapLoader::Draw(sf::RenderTarget& rt, sf::Uint16 index, bool debug)
{
   m_SetDrawingBounds(rt.getView());
   m_DrawLayer(rt, m_layers[index], debug);
}

Lines rt.draw(m_gridVertices); rt.draw(m_rootNode); and m_DrawLayer(rt, m_layers[index], debug); are called once.

I asked the creator anyway to make sure, he didn't answer yet.

So the problem might not be that? I'm confused here because when using less and bigger tiles it works fine  :o

Hapax

  • Hero Member
  • *****
  • Posts: 3387
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: 8x8 tiles and big map, bad idea?
« Reply #5 on: June 25, 2015, 09:07:48 pm »
Are you drawing it with "MapLayer::Debug" because object.DrawDebugShape(rt); looks like a lot of draw calls.

It might not be the draw calls. It could be your logical transformations. Are you altering each tile every frame (even if they stay the same)?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Guido_Ion

  • Newbie
  • *
  • Posts: 42
    • View Profile
    • Flow Soccer development
Re: 8x8 tiles and big map, bad idea?
« Reply #6 on: June 25, 2015, 09:24:15 pm »
oops, my bad those are not called, this one is called:

Quote
void MapLoader::draw(sf::RenderTarget& rt, sf::RenderStates states) const
{
   sf::View view  = rt.getView();
   if(view.getCenter() != m_lastViewPos)
   {
      sf::FloatRect bounds;
      bounds.left = view.getCenter().x - (view.getSize().x / 2.f);
      bounds.top = view.getCenter().y - (view.getSize().y / 2.f);
      bounds.width = view.getSize().x;
      bounds.height = view.getSize().y;

      //add a tile border to prevent gaps appearing
      bounds.left -= static_cast<float>(m_tileWidth);
      bounds.top -= static_cast<float>(m_tileHeight);
      bounds.width += static_cast<float>(m_tileWidth * 2);
      bounds.height += static_cast<float>(m_tileHeight * 2);
      m_bounds = bounds;
   }
   m_lastViewPos = view.getCenter();

   for(auto& layer : m_layers)
      rt.draw(layer);
}

rt.draw(layer) is called 3 times, one for each layer I made on Tiled.

It might not be the draw calls. It could be your logical transformations. Are you altering each tile every frame (even if they stay the same)?

I think I'm not doing that, maybe the MapLoader is but I've been investigating the code and it doesn't seem to be doing any extra processing on the tiles, here it is the entire code (https://github.com/fallahn/sfml-tmxloader) and here it is the MapLoaderPrivate.cpp where the draw fuction is (https://github.com/fallahn/sfml-tmxloader/blob/master/src/MapLoaderPrivate.cpp)


EDIT: This is it!
On MapLayer.cpp:
Quote
void LayerSet::draw(sf::RenderTarget& rt, sf::RenderStates states) const
{
   for(auto& q : m_quads)
   {
      if(q->m_needsUpdate)
      {
         for(auto& i : q->m_indices)
         {
            m_vertices.position += q->m_movement;
         }
         q->m_needsUpdate = false;
      }
   }
   
   if(!m_vertices.empty() && m_visible)
   {
      states.texture = &m_texture;
      rt.draw(&m_vertices[0], static_cast<unsigned int>(m_vertices.size()), sf::Quads, states);
   }
}

Renderer would check *every* TileQuad each frame for any updates. This is corrected on the last update of April 2015 (here: http://trederia.blogspot.co.uk/2015/04/tmx-loader-for-sfml-update.html)

Thanks for the help!  ;)
« Last Edit: June 25, 2015, 10:01:30 pm by Guido Bisocoli »

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: 8x8 tiles and big map, bad idea?
« Reply #7 on: June 26, 2015, 09:48:29 am »
draw using this, i copy it from documentation, its a sf::RenderWindow::draw
Code: [Select]
void draw (const Vertex *vertices, std::size_t vertexCount, PrimitiveType type, const RenderStates &states=RenderStates::Default)

it would be something like this
Code: [Select]
for(y...)//Column
{
   for(x...)//Row
   {
      renWin.draw(...);
   }
}
This kind of goes against your reason for using a vertex array. You still have all the draw calls for each tile.

A vertex array can hold many vertices and therefore all of the (visible) tiles at once. Then, there's no need for a loop; you just call draw on the vertex array and it draws them all.

There is a tile map example in the vertex array tutorial.

Completely valid except (draw calls for each tile), it would rather be that there will be draw call for one row of tiles, but at some point it becomes better then drawing a massively huge vertex array.
« Last Edit: June 26, 2015, 09:50:04 am by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Hapax

  • Hero Member
  • *****
  • Posts: 3387
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: 8x8 tiles and big map, bad idea?
« Reply #8 on: June 26, 2015, 08:10:20 pm »
@Guido Bisocoli
I don't use or know much about that TMX Loader so I don't think I can be any more help here. Sorry  :(

it would rather be that there will be draw call for one row of tiles
That is not what tha code does. It iterates columns, and for each column, iterates rows, and for each row, draws. That's drawing every tile separately  ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything