PDA

View Full Version : Big slowdown while drawing tiles from a vector



RootKernel
10-15-2012, 11:53 AM
Hello,

(This is a continuation of my previous thread (http://www.rtsoft.com/forums/showthread.php?5996-CL_PixelBuffer-transfer-to-another-CL_PixelBuffer))

I'm doing a map loader system with ClanLib
the map is defined in a XML file, it has different tilesets (PNG: a collection of 16*16 tiles) and different layers

A layer is composed of multiples tiles, a tile is composed of the position X & Y and the ID of the positon on the associated tileset
A tileset is a simple CL_Sprite wich contains all the image tiles.

Here is my loop for drawing these :


unsigned char tileset_index;
unsigned short gid;
unsigned int pos_x;
unsigned int pos_y;

for (int i = 0; i < layers.size(); ++i)
{
Layer layer = layers[i];
for (int j = 0; j < layer.get_tiles().size(); ++j)
{
Tile tile = layer.get_tiles()[j];
gid = tile.get_gid();
tileset_index = tile.get_tileset();
pos_x = tile.get_x();
pos_y = tile.get_y();
if (tileset_index != 0)
tilesets[tileset_index].draw_gid(gid, pos_x, pos_y);
}
}

Where gid is the image i want to draw


void Tileset::draw_gid(unsigned short gid, int x, int y)
{
tileset->set_frame(gid);
tileset->draw(World::get_gc(), x, y);
}

But this method is very very slow.

Any advices ?

Thanks

rombust
10-16-2012, 07:41 AM
Slow in the DEBUG build, or the RELEASE build?

RootKernel
10-16-2012, 10:11 AM
Slow in the DEBUG build, or the RELEASE build?

Hello rombust,

I'm developping under gcc, I compile with this command line : (in reality it's a custom Makefile from example folder)


g++ `pkg-config --cflags clanCore-2.3 clanDisplay-2.3 clanApp-2.3 clanSWRender-2.3 clanGL-2.3 clanGL1-2.3` -pthread -Isrc/includes -c src.cpp

rombust
10-18-2012, 08:22 AM
Are the pngs contained in the same file?

If not, they will really slow down the OpenGL pipeline because you cannot batch draw them

(technically, for clanGL you are allowed 3 pngs without breaking the batcher)

There is a utility to do this: ClanLib-2.3/Utilities/TexturePacker
It also adds a pixel border to each image, so that you do not get colour bleeding problems with stretched images (An alternative is to also disable linear filtering)
If I remember correctly, it does not work 100% on linux because it is missing a file requester, but no harm trying :)
http://clanlib.org/w/images/b/bd/Example_texturepacker.png

This process should ideally be automated by clanlib internally. Maybe for ClanLib 3.0 :)

RootKernel
10-18-2012, 11:41 AM
Hello rombust :)

Actually my map only uses 3 tilesets (so 2 PNGs : there is a collision layer that isn't drawn)

I tried with only one tileset (only one PNG image of 640x640), but there is still an important FPS drop.

I use CL_Sprite for tilesets (and a CL_SpriteDescription to cut my tileset in 16x16 tiles with a spacing/margin of 1)

rombust
10-18-2012, 04:12 PM
Use CL_Image instead of CL_Sprite, that should make it faster.

The fastest way is to use "gc.draw_primitives() via a CL_VertexArrayBuffer, when a single OpenGL can draw the scene.

But you would need to do a bit of coding.

Also try clanGL vs clanGL1

Judas
10-19-2012, 02:51 PM
I don't think the slowdown is caused by ClanLib.

My theory would be that he's making a copy of the vector when doing "Layer layer = layers[i];" and "Tile tile = layer.get_tiles()[j];" - that is a lot of memory copying.

Try pass them by reference or pointer, i.e. "Layer &layer = layers[i];"