Я пытаюсь подключить игру DirectX. Я успешно загружен мой крюк, и я в состоянии сохранить изображения/BackBuffer на диске с помощью:Direct3D9 BackBuffer to PixelArray
HRESULT Capture(IDirect3DDevice9* Device, const char* FilePath)
{
IDirect3DSurface9* RenderTarget = nullptr;
HRESULT result = Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &RenderTarget);
//for some reason result is never S_OK but this still works.
result = D3DXSaveSurfaceToFile(FilePath, D3DXIFF_PNG, RenderTarget, nullptr, nullptr);
SafeRelease(RenderTarget);
return result;
}
Это экономит успешно, и я рад. Тем не менее, я хочу сохранить в пиксельный массив, а не на диск. Я попытался с помощью:
#include <memory>
std::unique_ptr<std::uint8_t[]> mem(new std::uint8_t[100 * 100 * 4]);
HRESULT Direct3DDevice9Proxy::EndScene()
{
IDirect3DSurface9* RenderTarget = nullptr;
HRESULT result = ptr_Direct3DDevice9->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &RenderTarget);
D3DLOCKED_RECT LR;
RenderTarget->LockRect(&LR, nullptr, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
memcpy(mem.get(), LR.pBits, LR.Pitch - 1);
RenderTarget->UnlockRect();
SafeRelease(RenderTarget);
return ptr_Direct3DDevice9->EndScene();
}
Однако, он никогда не блокируется, и он бросает нарушение доступа при попытке получить доступ к LR.pBits. Я не уверен, почему он не будет заблокирован. Есть ли другой способ, с помощью которого я могу захватить пиксели из backbuffer в массив байтов? Максимальное количество просмотров игры - 1366x768.
EDIT: Я пробовал:
void dump_buffer(LPDIRECT3DDEVICE9 Device, std::unique_ptr<std::uint8_t[]> &bits)
{
IDirect3DSurface9* RenderTarget = nullptr;
IDirect3DSurface9* DestTarget = nullptr;
D3DSURFACE_DESC rtDesc = {};
Device->GetRenderTarget(0, &RenderTarget);
RenderTarget->GetDesc(&rtDesc);
Device->CreateOffscreenPlainSurface(rtDesc.Width, rtDesc.Height, rtDesc.Format, D3DPOOL_DEFAULT, &DestTarget, nullptr);
Device->GetRenderTargetData(RenderTarget, DestTarget);
if(DestTarget != nullptr)
{
D3DLOCKED_RECT rect;
DestTarget->LockRect(&rect, 0, D3DLOCK_READONLY);
memcpy(bits.get(), rect.pBits, rtDesc.Width * rtDesc.Height * 4);
std::uint8_t* ptr = &bits[0];
CG::Image(ptr, rtDesc.Width, rtDesc.Height).Save("Foo.bmp");
DestTarget->UnlockRect();
DestTarget->Release();
}
RenderTarget->Release();
}
HRESULT Direct3DDevice9Proxy::EndScene()
{
dump_buffer(ptr_Direct3DDevice9, mem);
return ptr_Direct3DDevice9->EndScene();
}
но мой образ черный. Есть идеи?
Я пробовал это. Это не сработало. Это привело к нарушению доступа. Вместо этого я использовал GetRenderTargetData, и вместо этого я получил черное изображение. Отредактировал OP, чтобы отразить то, что я пробовал. – Brandon