Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Faster way to build a mask image?

This thread is locked; no one can reply to it. rss feed Print
Faster way to build a mask image?
HellfireXP
Member #14,798
December 2012

I am building a game engine using Allegro 5 and I've got a function (below) that builds a mask image from an existing sprite tile sheet. What the function does is replace the transparent color of the sprite with white, and non-transparent regions with black. In a later "CollisionCheck" function I plan to pass two masks plus their X,Y locations to return a boolean value if the black regions intersect.

The question I have is if it's possible to speed up the process below? Maybe my code is too slow because my logic is actually doing it "the hard way" or maybe I'm not using the right Allegro functions, but when I run this function, it takes at least 5-10 seconds to construct a mask for a modestly sized sprite. I can imagine doing this with several images and watching my game load for a good 30 seconds or more :/

#SelectExpand
1class MASK{ 2public: 3 ALLEGRO_BITMAP *mBmp; 4 void Create(SPRITESHEET, ALLEGRO_COLOR); 5 void Destroy() { al_destroy_bitmap(mBmp); } 6}; 7 8void MASK::Create(SPRITESHEET ss, ALLEGRO_COLOR maskClr) 9{ 10 //Create the mask bitmap based on ss dimensions 11 mBmp = al_create_bitmap(ss.GetWidth(),ss.GetHeight()); 12 //Set current focus to the mask bitmap 13 al_set_target_bitmap(mBmp); 14 ALLEGRO_COLOR iClr; 15 //Loop through all pixels in the spritesheet 16 for (int iWid=0; iWid<ss.GetWidth(); ++iWid) 17 { 18 for (int iHgt=0; iHgt<ss.GetHeight(); ++iHgt) 19 { 20 //Get the color of current pixel position 21 iClr = al_get_pixel(ss.sBmp,iWid,iHgt); 22 //Check to see if this color is the same as the maskClr 23 if (iClr.r == maskClr.r && 24 iClr.g == maskClr.g && 25 iClr.b == maskClr.b && 26 iClr.a == maskClr.a ) 27 { 28 //If maskClr == iClr then change color to WHITE 29 al_put_pixel(iWid,iHgt,al_map_rgb(255,255,255)); 30 } else 31 { 32 //If maskClr != iClr then change color to BLACK 33 al_put_pixel(iWid,iHgt,al_map_rgb(0,0,0)); 34 } 35 } 36 } //End of loop through all pixels in spritesheet 37 38 //Return focus to the previous object 39 al_set_target_bitmap(FOCUS); 40}

weapon_S
Member #7,859
October 2006
avatar

HellfireXP
Member #14,798
December 2012

Ok, that made a significant difference. Here's my modified code. Thanks.

#SelectExpand
1void MASK::Create(SPRITESHEET ss, ALLEGRO_COLOR maskClr) 2{ 3 //Create the mask bitmap based on ss dimensions 4 mBmp = al_create_bitmap(ss.GetWidth(),ss.GetHeight()); 5 //Lock bitmaps 6 al_lock_bitmap(mBmp,ALLEGRO_PIXEL_FORMAT_ANY,ALLEGRO_LOCK_WRITEONLY); 7 al_lock_bitmap(ss.sBmp,ALLEGRO_PIXEL_FORMAT_ANY,ALLEGRO_LOCK_READONLY); 8 //Set current focus to the mask bitmap 9 al_set_target_bitmap(mBmp); 10 ALLEGRO_COLOR iClr; 11 //Loop through all pixels in the spritesheet 12 for (int iWid=0; iWid<ss.GetWidth(); ++iWid) 13 { 14 for (int iHgt=0; iHgt<ss.GetHeight(); ++iHgt) 15 { 16 //Get the color of current pixel position 17 iClr = al_get_pixel(ss.sBmp,iWid,iHgt); 18 //Check to see if this color is the same as the maskClr 19 if (iClr.r == maskClr.r && 20 iClr.g == maskClr.g && 21 iClr.b == maskClr.b && 22 iClr.a == maskClr.a ) 23 { 24 //If maskClr == iClr then change color to WHITE 25 al_put_pixel(iWid,iHgt,al_map_rgb(255,255,255)); 26 } else 27 { 28 //If maskClr != iClr then change color to BLACK 29 al_put_pixel(iWid,iHgt,al_map_rgb(0,0,0)); 30 } 31 } 32 } //End of loop through all pixels in spritesheet 33 //Unlock bitmaps 34 al_unlock_bitmap(mBmp); 35 al_unlock_bitmap(ss.sBmp); 36 //Return focus to the previous object 37 al_set_target_bitmap(FOCUS); 38}

LennyLen
Member #5,313
December 2004
avatar

Have you considered per-rendering your masks and saving them in their own tile sheet?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I am thinking of something similar for my collision detection in my SantaHack game, but non axis aligned bounding boxes might make it problematic. For that reason I have been considering a shader in case that might work for pixel perfect collision detection but I have no experience with shaders so I don't know.

Go to: