This post is a portion of Part 12 in my on going series about 2D Game Development using the Allegro 5 library. These posts are in course order. You can see all of the posts in this course by clicking the “2D Game Development” button at the top of this site.
- 12.0 – Collision Detection
- 12.1 – Bounding Rectangle Collision Detection
- 12.2 – Distance Based Collision Detection
- 12.3 – Pixel Perfect Collision Detection
Full source can be found here.
It took 11.5 seconds for me to load on a 1.4 GHz PC, so the result will vary for every computer. Just a little something to keep in mind for everyone. =)
Yes, it is certainly not optimized.
Mask_New() would probably be *much* faster if you ran al_lock_bitmap(bmp) before the for-loop and al_unlock_bitmap(bmp) afterwards.
Agreed. Locking would definitely optimize this library
For ball2.image i set a realy big png with transparent center.
(I want it would work like a map background with trasnparent center.)
But somehow i believe when i set the mask: ball2.mask = Mask_New(ball2.image);
it aligns it to middle of the image.
So the collision and mask draw is not currently aligned with the image x y.
al_draw_bitmap(ball2.image, 0, 0, 0);
Mask_Draw(ball2.mask, ball2.x, ball2.y);
it looks like this: http://s16.postimage.org/8ggrk2bqt/asd.jpg
;D
So I want to know where to change in the PPCD.cpp so it would align mask normaly by x and y.
I tried to compile this on Ubuntu 11.10 and give me this error
/tmp/cccJve2m.o: In function `Mask_Create(int, int)’:
PPCD.cpp:(.text+0x195): undefined reference to `operator new(unsigned int)’
PPCD.cpp:(.text+0x1bb): undefined reference to `operator new[](unsigned int)’
/tmp/cccJve2m.o: In function `Mask_Delete(mask*)’:
PPCD.cpp:(.text+0x2ce): undefined reference to `operator delete[](void*)’
PPCD.cpp:(.text+0x2df): undefined reference to `operator delete(void*)’
collect2: ld devolvió el estado de salida 1
If you’re compiling in c you should replace those with malloc and free
I’m guessing, since (s)he is using Ubuntu, that the GNU Compiler Collection is being used. GCC is supposed to automatically detect that .cpp files are written in C++. Mario, have you installed the GNU C++ Compiler, yet? This might be the source of your problem.
Of course, you can always turn it into C code like psam suggested, but I recommend keeping a C++ compiler around anyway, since a lot of modern programs require it.
Hey everybody.
Two things here.
First, on Linux, you need to download the “arial.ttf” file and have it in the same folder / to run the demo.
The second thing is to LOCK the ALLEGRO_BITMAP when criating its mask. It makes mask creation incredibly faster (on my machine, 14 seconds faster!).
Here is the code you should have in PPCD.cpp for the Mask_New(ALLEGRO_BITMAP *bmp) function.
al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
for(int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
pixel = al_get_pixel(bmp, j, i);
if(!Color_Equiv(pixel, transColor) && !Transparent(pixel))
Mask_SetBit(temp, j, i);
}
}
al_unlock_bitmap(bmp);
Hope it helps somebody out there,
Thanks! Now it’s down to less than second from 3 seconds. Btw, silly question, why is locking the bitmap so important for the efficiency of that piece of coding?
If you don’t lock it yourself, every single al_get_pixel() command will do their own locks, effectively locking and unlocking the texture hundreds of times.
The reason for this is that part of locking is downloading the texture data so that we can actually get pixel information. If it weren’t locked, the pixel data would be unavailable to us.
thaaaaaaanks!
Just a quick confirmation that using al_lock_bitmap does wonders on mask creation time and mask drawing times as well.
My sistem creates the two masks in 9.5 seconds to 4.53 milliseconds, I’m running on an Win7 Core i3 @2.2Ghz, that is a REALLY strong improvement.
Also drawing the masks locking the backbuffer improves performances a lot, so you do not get any lag.
You are 100% correct. I have been meaning to update my code ever since I posted it originally and I keep forgetting. I didn’t include it originally because I wanted to illustrate the time sync of performing this type of detection and I didn’t want to confuse viewers. In hindsight I should have just put it in.
And that was with a DEBUG build.
RELEASE Optimized code makes a single ORB mask in 690 microseconds.
(different platform thou, this is a Core i7 @ 2.2GHz)
I was sort of hoping you would go over the PPCD.cpp file in your video as well.
I have developed a small 2d game engine whose input is from a remote application using OpenCV computer vision system, basically object tracking.
I am experimenting some kind of virtual reality small games and applications in case anybody is interested, let me know here in the comments.
Carlos Ramirez.
sounds interesting, im interested
Hey! I think that you’re wrong in a part of your code in PPCD.cpp
If the image isn’t squared the script doesn’t work so I looked for the error and I think you should put this:
void Mask_SetBit(mask_t *m, int x, int y)
{
m->bits[y * m->w + x] = 1;
}
Instead of this:
void Mask_SetBit(mask_t *m, int x, int y)
{
m->bits[x * m->w + y] = 1;
}
You exchanged y and x!
Oh Mike. Great tutorials.
Just one thing. I see you forgot the 12.4 video. I saw on your youtube channel, but not here nor the source code.
thx for all.