Я пытаюсь реализовать идеальный по пикселям алгоритм обнаружения столкновений из онлайн-учебника, но он написан с использованием d3d9. Я пишу свою игру в d3d11, поэтому я хотел бы знать, как лучше ее конвертировать. Исходный код, использующий заблокированные ректы, которые c, ч после исследования я обнаружил, не были в D3D11. Кстати, я использую DirectX TK, поэтому мне нужно преобразовать ShaderResourceView в текстуру. Вот оригинальный код:
int Bird::PixelPerfectCollision(Vector2* birdPoints, Vector2* pipePoints, Renderer& renderer)
{
// Creation of the bounding rectangles from the SPRITE values
// Remember that coordinates start in the upper left corner of the screen
//bird
RECT rect1;
rect1.left = (long)birdPoints[4].x;
rect1.top = (long)birdPoints[0].y;
rect1.right = (long)birdPoints[2].x;
rect1.bottom = (long)birdPoints[3].y;
//pipe
RECT rect2;
rect2.left = (long)pipePoints[0].x;
rect2.top = (long)pipePoints[0].y;
rect2.right = (long)pipePoints[1].x;
rect2.bottom = (long)pipePoints[2].y;
// Intersection of the bounding rectangles
// Up to here the code is just bounding box collision detection
RECT dest;
if (IntersectRect(&dest, &rect1, &rect2))
{
ComPtr<ID3D11ShaderResourceView> birdTexSRV = renderer.GetBirdTexture();
ComPtr<ID3D11ShaderResourceView> pipeTexSRV = renderer.GetPipeTexture();
// Loking of the textures
// In this case the SPRITE object holds the texture to draw
// We will access it and invoke the LockRect method of LPDIRECT3DTEXTURE9
// The pixels will be saved in each D3DLOCKED_RECT object
Microsoft::WRL::ComPtr<ID3D11Resource> resource;
birdTexSRV->GetResource(resource.GetAddressOf());
ComPtr<IDirect3DTexture9> birdTex;
DX::ThrowIfFailed(resource.As(&birdTex));
D3DLOCKED_RECT rectS1;
HRESULT hResult = birdTex->LockRect(0, &rectS1, NULL, NULL);
if (FAILED(hResult))
{
MessageBox(0, L"Failed", L"Info", 0);
return 0;
}
Microsoft::WRL::ComPtr<ID3D11Resource> resource;
pipeTexSRV->GetResource(resource.GetAddressOf());
ComPtr<IDirect3DTexture9> pipeTex;
DX::ThrowIfFailed(resource.As(&pipeTex));
D3DLOCKED_RECT rectS2;
hResult = pipeTex -> LockRect(0, &rectS2, NULL, NULL);
if (FAILED(hResult))
{
MessageBox(0, L"Failed", L"Info", 0);
return 0;
}
// Get the pointer to the color values
// From now on, we will read that pointer as an array
D3DCOLOR* pixelsS1 = (D3DCOLOR*)rectS1.pBits;
D3DCOLOR* pixelsS2 = (D3DCOLOR*)rectS2.pBits;
// We will check the area of the intersected rect (dest)
// In this rectangle, we have to check that in the same spot:
// A pixel from each texture collide
for (int rx = dest.left; rx < dest.right; rx++)
{
for (int ry = dest.top; ry < dest.bottom; ry++)
{
// Translation from the "dest" rect to sprite1 coordinates
int s1x = rx - screenPos.x;
int s1y = ry - screenPos.y;
// Translation from the "dest" rect to sprite2 coordinates
int s2x = rx - pipePoints[0].x;
int s2y = ry - pipePoints[0].y;
// Check the alpha value of each texture pixel
// The alpha value is the leftmost byte
BYTE a = (pixelsS1[s1y * 128 + s1x] & 0xFF000000) >> 24;
BYTE b = (pixelsS2[s2y * 480 + s2x] & 0xFF000000) >> 24;
// If both pixels are opaque, we found a collision
// We have to unlock the textures and return
if (a == 255 && b == 255)
{
birdTex->UnlockRect(0); pipeTex->UnlockRect(0);
return 1;
}
}
}
// If we reached here, it means that we did not find a collision
birdTex->UnlockRect(0);
pipeTex->UnlockRect(0);
return 0;
return true;
}
return 0;
}