GetPixel, HDC, and heartattacks
For those of you that've read some of my most recent posts, you'll know the little project I'm working on. Basically, I'm trying to get as many little Dudes (4x4 Blue Square) flying randomly across my screen. So far, with no collision detection, I've been able to display 300 Dudes at 75FPS, 500 at 50FPS, and 1000 at about 30FPS.
My first collision detection method consisted of starting with the first Dude in my array, and seeing if he was within colliding distance with ALL Dudes above him in the array. The I'd check #2 with all Dudes above him, and so on. With 100 dudes, it was pretty much 100! checks. That method resulted in being able to have 100 Dudes at 75FPS, 200 Dudes at 45FPS, 1000 Dudes at 3FPS, and I gave up after about 3 minutes while waiting for the first frame of 80000 Dudes.
These rates just don't cut it, so, my better idea is to check the 8 Pixels surrounding a Dude...
- Each Dude travels in the X Direction at a maximum speed of 3 Pixels Per Frame.
- Each Dude travels in the Y Direction at a maximum speed of 3 PPF.
By checking the colour of merely 8 Pixels, I can reduce the number of checks from (for 100 Dudes):
9.3 x (10^157) <-- Rounded down hugely
to
8.0 x (10^2)
There is a problem with this new method that the two can still miss eachother, but just by looking at those two numbers, I'm willing to throw in a bit of extra code to fix that and get the performance improvement. (Incase you don't quite get what I'm saying, I drew a picture down below).
Now, for the actual check, here's what I have:
Code:
My "Organism" Class:
class cORGANISM
{
public:
cORGANISM(void)
{
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
m_pD3DDevice = NULL;
m_pTexture = NULL;
m_pSprite = NULL;
}
virtual ~cORGANISM(void)
{
DeleteDC(hDC);
if(m_pSprite != NULL)
{
m_pSprite->Release();
m_pSprite = NULL;
}
if(m_pTexture != NULL)
{
m_pTexture->Release();
m_pTexture = NULL;
}
if(m_pD3DDevice != NULL)
m_pD3DDevice = NULL;
}
HRESULT Initialise(IDirect3DDevice9 *pD3DDevice);
void StringActiveDudes(char *NumDudes);
void Render(void);
private:
IDirect3DDevice9 *m_pD3DDevice;
IDirect3DTexture9 *m_pTexture;
ID3DXSprite *m_pSprite;
std::vector<cDUDE> Dude;
HDC hDC;
};
Each Dude gets the hDC passed to it inside the cDude::Collision() method:
bool cDUDE::Collision(float X, float Y, HDC *hDC)
{
unsigned long Colour;
if(*hDC == NULL)
return false;
for(int I = -4; I <= 4; I = I + 4)
{
for(int J = -4; J <= 4; J = J + 4)
{
if((I != 0)||(J != 0))
{
Colour = GetPixel(*hDC, (int)X+I, (int)Y+J);
if(Colour != CLR_INVALID)
{
if(Colour != 0xFF000000)
{
return true;
}
}
else
{
return false;
}
}
}
}
return false;
}
The problem is that Colour, in the Collision Detection method is always CLR_INVALID. Is there some mistake that I'm making with my code above that's spottable?
Also, GetPixel doesn't seem to be the quickest of calls. My FrameRate actually seems to have suffered more since changing collision methods. But I'm hoping it has something to do with the actual hDC and I'm making an error somewhere along the way that's just muddling things up.
(And incase it makes a difference, my window was created with the "CS_OWNDC" style, way back when registering the WNDCLASS object).
If you've managed to make it all the way down here, wow :) As always, any advice or comments are appreciated.