DXGI与D3D关系
DXGI 为未来的图形组件提供了一个通用框架。
DXGI 的目的是与内核模式驱动程序和系统硬件进行通信,如下图所示。
image.png
DXGI捕获桌面图像流程
- 创建d3d设备,并通过d3d设备查询到DXGI设备
- 通过DXGI设备获取DXGI适配器
IDXGIAdapter
- 通过DXGI适配器
IDXGIAdapter
,获取DXGIIDXGIOutput
和IDXGIOutput1
- 然后获取DXGI
IDXGIOutputDuplication
- 通过
IDXGIOutputDuplication
的接口AcquireNextFrame
获取桌面图像帧资源IDXGIResource
- 查询到桌面图像帧资源的纹理数据(数据类型是RGB数据)
- 释放帧
ReleaseFrame
获取DXGI适配器IDXGIAdapter
// 为抓取桌面图像创建DXGI设备
// 2.创建DXGI设备
hr = m_device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&m_dxgiDevice));
if (FAILED(hr)) {
return false;
}
// 3.获取DXGI适配器
hr = m_dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_dxgiAdapter));
if (FAILED(hr)) {
return false;
}
枚举显示器
// 3.1 枚举所有显示器
for (int i = 0; i < 6; i++) {
IDXGIOutput* dxgiOutput;
HRESULT hr = m_dxgiAdapter->EnumOutputs(i, &dxgiOutput);
if (FAILED(hr)) {
break;
}
DXGI_OUTPUT_DESC desc;
dxgiOutput->GetDesc(&desc);
}
获取DXGI IDXGIOutputDuplication
// 4.获取DXGI output
IDXGIOutput* dxgiOutput;
HRESULT hr = dxgiAdapter->EnumOutputs(monitorIdx, &dxgiOutput);
if (FAILED(hr)) {
Log(LOG_ERROR, "failed for get EnumOutputs");
return false;
}
// 5.获取DXGI output1
IDXGIOutput1* dxgiOutput1;
hr = dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&dxgiOutput1));
if (FAILED(hr)) {
Log(LOG_ERROR, "failed for get IDXGIOutput1");
return false;
}
// 6.获取DXGI OutputDuplication
IDXGIOutputDuplication* outputDup;
hr = dxgiOutput1->DuplicateOutput(device, &outputDup);
if (FAILED(hr)) {
Log(LOG_ERROR, "failed for DuplicateOutput");
if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
Log(LOG_ERROR, "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE");
}
return false;
}
获取图像帧
// 7. 获取桌面图像
DXGI_OUTDUPL_FRAME_INFO frameInfo;
IDXGIResource* idxgiRes;
HRESULT hr = m_outputDupV[idx]->AcquireNextFrame(1000, &frameInfo, &idxgiRes);
ID3D11Texture2D* desktopTexture2d;
hr = idxgiRes->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&desktopTexture2d));
D3D11_TEXTURE2D_DESC desktopDesc;
desktopTexture2d->GetDesc(&desktopDesc);
捕获光标
使用Windows API GetCursorInfo
将捕获到光标数据。
网友评论