Hello I'm working on a function that does per pixel collision and I have the idea of having 2 surfaces as parameters for this function.
Then basically create integer variables for each side of the 2 surfaces.
And then cleanly analyse them if the first surface of one of the 4 sides is by pixel in collision with the second surface by one of the second surface 4 sides then do something.
The problem is I don't know how to analyse each side aka *integer variables* for pixel collisions for the first and second surface any tips or solutions would be helpful.
Here is my Code Below
bool PerPixelCollision(SDL_Surface *image,SDL_Surface *Intersection_area)
{
int left_image, left_intersection_area;
int right_image, right_intersection_area;
int top_image, top_intersection_area;
int botttom_image, bottom_intersection_area;
well, you could AND two bit-wise masks together and if you get any true's that would be a collision detect. Perhaps there is a more efficient way to do that via the alpha channels, but i cant say for sure.
I did per-pixel collision in a game long ago (2000/2001) using C and DirectX. I'll post the code below, but, I don't feel like explaining everything.
The basic idea is, when I load an image, I scan it, recording if the color is transparent or not (I used 0 as transparent). I would then store every pixel in a bit-map array; if it's a color, it was 1, if it was transparent, I used 0. I stored this in a hash-table list, with the address of the image as the key
During collision check, I 1st check if the rectangle intersect, if they do, I then find the overlapping rectangles, and then check each bit if, and if any of them are both 1's (AND'ing), then they collide.
Good Luck!
Code when loading image. pucBuffer is a IDirectDrawSurface7, but I get the raw bitmap stored in puwPointer (16-bit colors). pulCopyPointer is the bit-mask'd bitmap array.
// now get the surface
pdds1->Lock(NULL, &ddsd1, DDLOCK_WAIT | DDLOCK_READONLY, NULL);
puwPointer = (UWORD *)ddsd1.lpSurface;
/* allocate the memory, zero, and copy it into it */
pulCopyPointer = (ULONG *)malloc(((ddsd1.dwHeight * ddsd1.dwWidth)/8) + 4);
memset((void *)pulCopyPointer, 0, ((ddsd1.dwHeight * ddsd1.dwWidth)/8) + 4);
for (ulY = 0; ulY < ddsd1.dwHeight; ulY++)
{
for (ulX = 0; ulX < ddsd1.dwWidth; ulX++)
{
// If it's not zero, set bit
if(*(puwPointer + ulX + (ulY * ddsd1.lPitch/2)))
{
SET(*(pulCopyPointer + (ulCount/32)), (ulCount%32));
}
ulCount++;
}
}
// unlock
pdds1->Unlock(NULL);
/* now put in hash table, and then in a list */
Hash.cName = (CHAR *)pucBuffer;
Hash.ulNumber = (ULONG)pulCopyPointer;
// now make list
pPixelList = AddToList(pPixelList, CreateNode((void *)&Hash, sizeof(Hash)));
} /* endof SetObjectDefinition() */
Code for getting the bitmask'd bitmap (what I called an Object Definition)
ULONG *GetObjectDefinition(UCHAR *pucBuffer)
{
ULONG ulIndex;
tStringHash *pHash;
// loop list looking for this buffer
LOOP_LIST(ulIndex, pHash, tStringHash, pPixelList)
{
if (pHash->cName == (CHAR *)pucBuffer)
{
// found it
return ((ULONG *)pHash->ulNumber);
}
}
// Not suppose to be here!
LOG_ERROR("GetObjectDefinition: Bad buffer!\n"));
FLUSH;
// now loop through one of em, checking the color
for (lTempY = 0; lTempY < (LONG)RectObj1.ulSizeY; lTempY++)
{
// increase count to next line
ulCount1 = (Obj1.ulSizeX * (RectObj1.lLocY + lTempY)) + RectObj1.lLocX;
ulCount2 = (Obj2.ulSizeX * (RectObj2.lLocY + lTempY)) + RectObj2.lLocX;
for (lTempX = 0; lTempX < (LONG)RectObj1.ulSizeX; lTempX++)
{
// check for not 0
if (IS_SET(*(pulPointer1 + (ulCount1/32)), (ulCount1%32)) &&
IS_SET(*(pulPointer2 + (ulCount2/32)), (ulCount2%32)))
{
bReturn = TRUE;
break;
}
ulCount1++;
ulCount2++;
}