I’m developing a screen capture application using DirectX 11 and the Desktop Duplication API in C++. The goal is to capture the screen content and process it. However, I’m encountering an issue where the captured frame data is always all zeros.
Steps I’ve Taken:
Initialized DirectX Components:
Created ID3D11Device, ID3D11DeviceContext, and IDXGIOutputDuplication.
Ensured all components are properly initialized.
Acquired the Frame:
Used AcquireNextFrame to capture the frame.
Converted the Resource to Texture:
Used QueryInterface to convert the resource to ID3D11Texture2D.
Copied the Resource to a Staging Texture:
Used CopyResource to copy the acquired texture to a staging texture.
Mapped the Staging Texture:
Mapped the staging texture to access the data.
Output:
Output Device: \.DISPLAY1
Frame acquired successfully.
Resource converted to texture successfully.
Acquired Texture Width: 1920 Height: 1080
Acquired Texture Format: 87
CopyResource called.
Staging Texture Width: 1920 Height: 1080
RowPitch: 7680
First 64 bytes of mapped data after CopyResource:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Initialization and Frame Acquisition:
HRESULT hr;
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
Microsoft::WRL::ComPtr<ID3D11Device> device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
device.As(&dxgiDevice);
Microsoft::WRL::ComPtr<IDXGIOutput1> dxgiOutput1;
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> deskDupl;
dxgiOutput1->DuplicateOutput(device.Get(), &deskDupl);
Microsoft::WRL::ComPtr<IDXGIResource> desktopResource;
DXGI_OUTDUPL_FRAME_INFO frameInfo;
deskDupl->AcquireNextFrame(500, &frameInfo, &desktopResource);
Resource to Texture Conversion:
Microsoft::WRL::ComPtr<ID3D11Texture2D> acquiredDesktopImage;
desktopResource.As(&acquiredDesktopImage);
Copying Resource to Staging Texture:
D3D11_TEXTURE2D_DESC desc;
desc.Width = 1920;
desc.Height = 1080;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTex;
device->CreateTexture2D(&desc, nullptr, &stagingTex);
context->CopyResource(stagingTex.Get(), acquiredDesktopImage.Get());
Mapping and Accessing Staging Texture Data:
D3D11_MAPPED_SUBRESOURCE mappedResource;
context->Map(stagingTex.Get(), 0, D3D11_MAP_READ, 0, &mappedResource);
std::vector<BYTE> buffer(mappedResource.RowPitch * desc.Height);
memcpy(buffer.data(), mappedResource.pData, buffer.size());
context->Unmap(stagingTex.Get(), 0);
Why is the captured frame data all zeros despite following these steps? How can I resolve this issue and correctly capture the screen content using the Desktop Duplication API?