I'm trying to create a screen taking app that can get a raw bitmap of a desktop window from the GPU. I did it via GDI and it works properly, but using both DirectX and DXGI Duplication api, I have black screen or an error.
void dump_buffer() {
IDirect3D9* d3d = nullptr;
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
out("1");
ZeroMemory(&d3dpp, sizeof(d3dpp));//COCK?
D3DDISPLAYMODE d3ddm;
if(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
err("IDirect3D9");
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = FALSE;
IDirect3DDevice9* d3ddev = nullptr;
out("2");
d3d->CreateDevice(
D3DADAPTER_DEFAULT, // Используем видеокарту, установленную в Windows по умолчанию (= в качестве основной).
D3DDEVTYPE_HAL, // Используем аппаратный рендеринг (Hardware Abstraction Layer).
GetDesktopWindow(), // Дескриптор) окна
D3DCREATE_SOFTWARE_VERTEXPROCESSING, // Не использовать "фишки" T&L для лучшей совместимости с бОльшим числом видеоадаптеров.
&d3dpp, // Указатель на заранее заполненную структуру параметров отображения (D3DPRESENT_PARAMETERS).
&d3ddev // Указатель на создаваемый объект устройства Direct3D.
);
if (d3ddev == nullptr)
err("IDirect3DDevice9");
out("3");
IDirect3DSurface9 *pRenderTarget = nullptr;
IDirect3DSurface9 *pDestTarget = nullptr;
// sanity checks.
// get the render target surface.
HRESULT hr = d3ddev->GetRenderTarget(0, &pRenderTarget);
if (FAILED(hr)){
err("GetRenderTarget");
}
// get the current adapter display mode.
// hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);
out("4");
D3DDISPLAYMODE mode;
hr = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
if (FAILED(hr)){
err("GetAdapterDisplayMode");
}
// create a destination surface.
out(mode.Width);
out(mode.Height);
out(mode.Format);
hr = d3ddev->CreateOffscreenPlainSurface(mode.Width,
mode.Height,
mode.Format,
D3DPOOL_SYSTEMMEM,
&pDestTarget,
nullptr);
if (FAILED(hr)){
err(("CreateOffscreenPlainSurface"));
}
out("5");
//copy the render target to the destination surface.
hr = d3ddev->GetRenderTargetData(pRenderTarget, pDestTarget);
if (FAILED(hr)){
err(DXGetErrorDescription9A(hr));
err(("GetRenderTargetData"));
}
//save its contents to a bitmap file.
out("6");
hr = D3DXSaveSurfaceToFile(file,
D3DXIFF_BMP,
pDestTarget,
nullptr,
nullptr);
out("7");
// clean up.
pRenderTarget->Release();
pDestTarget->Release();
}
p.s: Do I understand correctly that when using GetDesktopWindow() am I capturing a desktop containing an image of the entire screen?
Some help in solving this problem is needed