Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Is this the right way of using al_hold_bitmap_drawing?

This thread is locked; no one can reply to it. rss feed Print
Is this the right way of using al_hold_bitmap_drawing?
Karol Wu
Member #16,795
January 2018

Hello.

Generally I'm new to Allegro library. I'm also new to these forums, so Hello everyone!
I'm Carl, I'm from Poland and currently working on a MMORPG game.

I've been investigating different ways of accelerating map (2D) rendering and found this: https://www.allegro.cc/manual/5/al_hold_bitmap_drawing. I've implemented this idea in my code aand...

My question is... am I doing it in the right way? Here's my code:

#SelectExpand
1std::map<unsigned int, ALLEGRO_BITMAP *> bitmaps; 2 std::map<unsigned int, std::vector<std::shared_ptr<Tile>>> tiles_stagged; 3 4 for(unsigned short x = start_x; x <= end_x; ++x) 5 { 6 for(unsigned short y = start_y; y <= end_y; ++y) 7 { 8 std::shared_ptr<Tile> tile = this->layers[(Layer::Type)i].tiles[x][y]; 9 10 if(tile == 0) continue; 11 12 ALLEGRO_BITMAP *tilegfx = NULL; 13 14 if(bitmaps.find(tile->graphic_id) == bitmaps.end()) 15 { 16 tilegfx = GFXLoader().GetBitmap(gid_offset[i], tile->graphic_id); 17 bitmaps[tile->graphic_id] = tilegfx; 18 } 19 20 if(tile->x >= start_x && tile->x <= end_x && tile->y >= start_y && tile->y <= end_y) 21 tiles_stagged[tile->graphic_id].push_back(tile); 22 } 23 } 24 25 for(auto &ts : tiles_stagged) 26 { 27 al_hold_bitmap_drawing(true); 28 for(auto &tile : ts.second) 29 { 30 if(bitmaps[ts.first] == NULL) continue; 31 32 int screen_x = tile->x * 64 - tile->x * 32 - tile->y * 32 + rx; 33 int screen_y = tile->y * 16 + tile->x * 16 + ry; 34 35 int w = al_get_bitmap_width(bitmaps[ts.first]); 36 int h = al_get_bitmap_height(bitmaps[ts.first]); 37 38 if(i == (int)Layer::Type::Object) 39 { 40 if(w > 64) 41 { 42 screen_x -= w / 2; 43 screen_x += 32; 44 } 45 if(h > 32) 46 { 47 screen_y -= h; 48 screen_y += 32; 49 } 50 if(w < 64) 51 { 52 screen_x -= w / 2; 53 screen_x += 32; 54 if(h > 32) screen_y -= 8; 55 } 56 if(h < 32) 57 { 58 screen_y -= h / 2; 59 screen_y += 16; 60 } 61 } 62 63 al_draw_bitmap(bitmaps[ts.first], screen_x, screen_y, 0); 64 } 65 al_hold_bitmap_drawing(false); 66 }

Eric Johnson
Member #14,841
January 2013
avatar

Hello Carl. Welcome to the forum! Yes, that looks right. Although it might be better to move al_hold_bitmap_drawing() outside of the for loops, depending on what your aim is.

Elias
Member #358
May 2000

Unless your bitmaps are all sub-bitmaps of the same parent bitmap, al_hold_bitmap_drawing won't have any effect btw.

--
"Either help out or stop whining" - Evert

Karol Wu
Member #16,795
January 2018

Hello Carl. Welcome to the forum! Yes, that looks right. Although it might be better to move al_hold_bitmap_drawing() outside of the for loops, depending on what your aim is.

Thanks! Tiles are grouped by the bitmap ID they are using, so I thought it would be good to enable and disable al_hold_bitmap_drawing() for tiles of each bitmap. Wouldn't it? Would it have same effect if I enable it just once before drawing all tiles?

Elias said:

Unless your bitmaps are all sub-bitmaps of the same parent bitmap, al_hold_bitmap_drawing won't have any effect btw.

I appreciate your opinion. I would use same parent bitmap for all of them although it would require merging 100's of bitmaps ;D I don't think I can use such big bitmap.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

If you use a couple large sprite sheets or tile maps, you can group them together on one large atlas texture. Then allocate each image a sub bitmap of an area on that larger atlas. This is where al_hold_bitmap_drawing comes in, because it can delay drawing as long as the bound context doesn't change. So you can happily blit millions of sprites as long as they are on the same texture.

Elias
Member #358
May 2000

Karol Wu said:

I appreciate your opinion. I would use same parent bitmap for all of them although it would require merging 100's of bitmaps ;D I don't think I can use such big bitmap.

Well, I overstated that - there will be no affect if none of the bitmaps is a sub-bitmap - it does not have to be a single parent.

If I understand right you actually are grouping your al_hold_bitmap_drawing calls around bitmaps with the same parent, in which case you are using it exactly as intended. And in that case it doesn't matter if you call it once around both loops or inside each loop - basically all "held" bitmaps are drawn whenever one of two things happens:

1. al_hold_bitmap_drawing(false) is called
2. a bitmap with a different parent is drawn

--
"Either help out or stop whining" - Evert

Karol Wu
Member #16,795
January 2018

Elias said:

If I understand right you actually are grouping your al_hold_bitmap_drawing calls around bitmaps with the same parent

Yes exactly.

Elias said:

And in that case it doesn't matter if you call it once around both loops or inside each loop - basically all "held" bitmaps are drawn whenever one of two things happens:

1. al_hold_bitmap_drawing(false) is called
2. a bitmap with a different parent is drawn

Big thanks to you for sharing this information.

Regards
Carl

Go to: