0

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

  • 1
    Does this answer your question? [Capture screen using DirectX](https://stackoverflow.com/questions/30021274/capture-screen-using-directx) as for Desktop Duplication API the official sample is here https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/DXGIDesktopDuplication – Simon Mourier Jan 12 '23 at 07:13
  • Actually, I googled these questions and tried to run that code, but both of them didn't work too. I can not image, why my code (which was fully copypasted from working internet examples) after reading documentation gives me black screen – danvik13 Jan 12 '23 at 12:17
  • What "didn't work"? You must be more specific https://stackoverflow.com/help/how-to-ask here is a full compilable version of my code https://pastebin.com/raw/WwLL8N2D – Simon Mourier Jan 12 '23 at 13:37
  • Thanks, this code works! "didn't work" meant capturing black screen – danvik13 Jan 13 '23 at 07:25
  • You want to check all calls for errors and enable DirectX Debug Layer https://learn.microsoft.com/en-us/windows/win32/direct3d11/using-the-debug-layer-to-test-apps https://walbourn.github.io/direct3d-sdk-debug-layer-tricks/ – Simon Mourier Jan 13 '23 at 08:04

0 Answers0