Memory saving versus performance and splitting sprites
kovarex

When working with big number of sprites (Good example is lot of rotation frames of locomotive), you can imagine, that in diagonal directions, very big part of the image is not used (is transparent).

I could imagine some algorithm, that could split sprites into smaller ones and draw those parts separatly.

Have you been experiencing with this kind of stuff?
Could it be not only memory vise, but also performance vice?

Imagine sprite S divided in x sprites that have (S pixel count)*y pixels combined, could the pixel drawing saving save enough to beat the extra cost of drawing more sprites? If so, how to relate x and y to keep it reasonable?

I guess it depends on the ratio of cost of drawing one pixel and drawing bitmap as whole.

Todd Cope

I'm assuming your using Allegro 5. If that is the case, your best bet if you want to draw many sprites is to use atlasing and al_hold_bitmap_drawing(). Shaving a few pixels from a texture won't make any difference. The biggest cost when rendering many different sprites comes from texture binding. If your put all your graphics onto an atlas you can draw many different sprites with only one texture binding. Your drawing code something look something like this:

al_hold_bitmap_drawing(true);
for(i = 0; i < total_sprites; i++)
{
    al_draw_bitmap(sprite[i].bitmap[sprite[i].type], sprite[i].x, sprite[i].y, 0);
}
al_hold_bitmap_drawing(false);

Each bitmap will need to be a sub-bitmap of the atlas bitmap which contains all the sprite images. You can draw thousands of sprites this way with good performance, even on older hardware.

You can search the forums for discussions of atlasing. It has come up a few times. You might find this useful.

kovarex

Hi, thank you for the advice, I'm already aware of atlas and bitmap holding usage (and using it in my game).

The motivation is not performance but saving of video memory.

Todd Cope

Ahh, I was confused because you were talking about the cost of pixel drawing vs. the cost of drawing more sprites.

I wouldn't worry about saving memory unless it is becoming a problem. If I was going to trim the extra space from around sprites I would make a structure to hold the extra positioning information and make a set of drawing functions to match. Something like this:

typedef struct
{

    ALLEGRO_BITMAP * bitmap;
    int ox, oy;

} MY_BITMAP;

void my_draw_bitmap(MY_BITMAP * bp, float x, float y, int flags)
{
    al_draw_bitmap(bp->bitmap, x + bp->ox, y + bp->oy, flags);
}
...

kovarex

Thanks for advice again, but I'm not asking HOW to do it, I'm asking if it is reasonable, and how big performance penalty could I expect (btw all my bitmaps are encapsulated in "middleware" like class that does this kind of things behind the surface automatically)

I will definetly have not enough video memory, and I will have to use every trick possible to be able to use it as much effectively as possible.

weapon_S

Premature optimization, maybe. Is this one of the optimizations you are considering after designing everything else? You are actually talking about splitting up an arbitrary image. I wouldn't go through the trouble, unless I had some serious need for the graphics memory :P And couldn't get it from anywhere else.
What kind of hardware are you running? Are you using a software renderer? How big are the sprites?
An ALLEGRO_BITMAP definitely has some memory overhead. So it might only pay off, if you use a small number of big sprite-sheets. In software you have the problem that your normal memory is your graphics memory. In hardware you have the problem that most textures must have power-of-two dimensions (and the textures will have additional dead-space to accommodate that).
Allegro 4 has RLE-sprites, which would be smaller. In Allegro 5 you could try turning on sub-samples and drawing the original sprite rotated. If the hardware you're working on supports it, you could even look into texture compression, I guess. If you're using software, RLE might be a good option.

kovarex

I'm not sure if it s premature optimisation, the graphics part of the engine is quite complete, and now I'm calculating how much objects can I use, and what quality can I use.

It's obvious that sprites that I would consider to split have to be quite big (200X200 pixels and more of hundrets of textures).
Texture size to be power of two isn't really an issue, as everything is stored in atlases.
Using hardware render.

Thread #610326. Printed from Allegro.cc