我使用了MS桌面复制API获取桌面图片,并获得了一张空白图片。 但是当在调试模式下运行并在AcquireNextFrame之后放置一个断点时,可以重新恢复映像。 我错过了什么?源代码:
#include "stdafx.h"
typedef struct _DX_RESOURCES
{
ID3D11Device* Device;
ID3D11DeviceContext* Context;
} DX_RESOURCES;
HRESULT InitializeDX(DX_RESOURCES *res) {
HRESULT hr = S_OK;
// Driver types supported
D3D_DRIVER_TYPE DriverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
// Feature levels supported
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
D3D_FEATURE_LEVEL FeatureLevel;
// Create device
for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
{
hr = D3D11CreateDevice(nullptr, DriverTypes[DriverTypeIndex], nullptr, 0, FeatureLevels, NumFeatureLevels,
D3D11_SDK_VERSION, &res->Device, &FeatureLevel, &res->Context);
if (SUCCEEDED(hr))
{
break;
}
}
return hr;
}
DX_RESOURCES dxRes;
int main()
{
HRESULT hr = InitializeDX(&dxRes);
if (FAILED(hr)) {
return -1;
}
D3D11_TEXTURE2D_DESC texdes;
texdes.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
texdes.BindFlags = 0;
texdes.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texdes.Height = 1080;
texdes.Width = 1920;
texdes.MiscFlags = 0;
texdes.MipLevels = 1;
texdes.ArraySize = 1;
texdes.SampleDesc.Count = 1;
texdes.SampleDesc.Quality = 0;
texdes.Usage = D3D11_USAGE_STAGING;
ID3D11Texture2D* screenTexture;
hr = dxRes.Device->CreateTexture2D(&texdes, NULL, &screenTexture);
if (FAILED(hr))
{
return -1;
}
IDXGIDevice* DxgiDevice = nullptr;
hr = dxRes.Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice));
if (FAILED(hr))
{
return -1;
}
IDXGIAdapter* DxgiAdapter = nullptr;
hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter));
DxgiDevice->Release();
DxgiDevice = nullptr;
if (FAILED(hr))
{
return -1;
}
IDXGIOutput* DxgiOutput = nullptr;
hr = DxgiAdapter->EnumOutputs(0, &DxgiOutput);
DxgiAdapter->Release();
DxgiAdapter = nullptr;
if (FAILED(hr))
{
return -1;
}
DXGI_OUTPUT_DESC OutputDesc;
DxgiOutput->GetDesc(&OutputDesc);
IDXGIOutput1* DxgiOutput1 = nullptr;
hr = DxgiOutput->QueryInterface(__uuidof(DxgiOutput1), reinterpret_cast<void**>(&DxgiOutput1));
DxgiOutput->Release();
DxgiOutput = nullptr;
if (FAILED(hr))
{
return -1;
}
IDXGIOutputDuplication* DeskDupl;
// Create desktop duplication
hr = DxgiOutput1->DuplicateOutput(dxRes.Device, &DeskDupl);
DxgiOutput1->Release();
DxgiOutput1 = nullptr;
if (FAILED(hr))
{
if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
{
return -1;
}
return -1;
}
DXGI_OUTDUPL_FRAME_INFO duplicateFrameInformation;
IDXGIResource* screenResource;
ID3D11Texture2D* acquiredDesktopImage;
DWORD t1 = GetTickCount();
hr = DeskDupl->AcquireNextFrame(500, &duplicateFrameInformation, &screenResource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
return 1;
}
if (FAILED(hr))
{
return -1;
}
hr = screenResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&acquiredDesktopImage));
screenResource->Release();
screenResource = nullptr;
if (FAILED(hr))
{
return -1;
}
ID3D11DeviceContext* context;
dxRes.Device->GetImmediateContext(&context);
context->CopyResource(screenTexture, acquiredDesktopImage);
IDXGISurface* screenSurface;
hr = screenTexture->QueryInterface(__uuidof(IDXGISurface), reinterpret_cast<void **>(&screenSurface));
if (FAILED(hr))
{
return -1;
}
DXGI_SURFACE_DESC desc;
screenSurface->GetDesc(&desc);
DXGI_MAPPED_RECT rect;
hr = screenSurface->Map(&rect, DXGI_MAP_READ);
if (FAILED(hr))
{
return -1;
}
FILE *fp;
fp = fopen("d:\\test.rgba", "wb");
fwrite(rect.pBits, 1, 1920 * 1080 * 4, fp);
fclose(fp);
screenSurface->Unmap();
acquiredDesktopImage->Release();
acquiredDesktopImage = nullptr;
DWORD t2 = GetTickCount() - t1;
printf("OK\n");
return t2;
}
答案 0 :(得分:1)
afert AcquireNextFrame,应检查[duplicateFrameInformation]的输出值。
// Get metadata
if (duplicateFrameInformation.TotalMetadataBufferSize)
{
....do some process
}