我尝试在C++中使用DirectX 11来捕获屏幕并将其转换为我可以使用OpenGL或ImGui渲染的纹理。我使用了Windows API和BitBlt,但这导致fps低于15,所以这不是一个选项。
我使用的是Windows 11,带有Nvidia显卡。
库导入:
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
字符串
正在初始化DirectX 11:
bool DirectX11::initDirectX11() {
HRESULT hr = S_OK;
IDXGIFactory* DXGIFactory = nullptr;
IDXGIAdapter* Adapter = nullptr;
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0;
Output = nullptr;
deskDupl = nullptr;
hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory));
if (FAILED(hr)) {
std::cout << "Failed to create DXGI Factory" << std::endl;
return false;
}
hr = DXGIFactory->EnumAdapters(0, &Adapter);
if (FAILED(hr)) {
std::cout << "Failed to create adapter" << std::endl;
return false;
}
hr = Adapter->EnumOutputs(0, &Output);
if (FAILED(hr)) {
std::cout << "Failed to create output" << std::endl;
return false;
}
hr = Output->QueryInterface(__uuidof(Output), (void**)(&deskDupl));
if (FAILED(hr)) {
std::cout << "Failed to create output1" << std::endl;
return false;
}
hr = Output->GetDesc(&OutputDesc);
if (FAILED(hr)) {
std::cout << "Failed to get output description" << std::endl;
return false;
}
hr = D3D11CreateDevice(Adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, &FeatureLevel, &deviceContext);
if (FAILED(hr)) {
std::cout << "Failed to create D3D11 device" << std::endl;
return false;
}
DXGIFactory->Release();
Adapter->Release();
return true;
}
型
捕获屏幕:
void DirectX11::captureScreen() {
HRESULT hr = S_OK;
IDXGIResource* DesktopResource;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
// Get new frame
hr = deskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource);
if (FAILED(hr)) {
std::cout << "Failed to acquire next frame" << std::endl;
return;
}
// Store the frame as a texture
// Trows exception
// Read access violation
// DesktopResource was 0xFFFFFFFFFFFFFFFF
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&AcquiredDesktopImage));
if (FAILED(hr)) {
std::cout << "Failed to query interface" << std::endl;
return;
}
}
型
问题是它不断抛出读访问冲突异常。
Read access violation
DesktopResource was 0xFFFFFFFFFFFFFFFF
型
1条答案
按热度按时间nsc4cvqm1#
此代码
字符串
无效,因为它将
IDXGIOutput
引用写入IDXGIOutputDuplication
引用。要获取
IDXGIOutputDuplication
引用,必须调用IDXGIOutput1::DuplicateOutput method,因此必须先获取IDXGIOutput1
,如下所示:型
然后
型
但要成功执行此操作,您必须从
IDXGIFactory1
或从CreateDXGIFactory1(DXGI 1.1)创建的IDXGIFactory
工厂创建设备,因此将调用CreateDXGIFactory
替换为CreateDXGIFactory1
。注意事项:为了避免对
QueryInterface
和许多其他COM调用进行危险的(void**)
转换,从而避免在使用Visual Studio时发生原始转换错误(至少部分错误),您可以使用IID_PPV_ARGS宏。因此,您可以编写以下内容:型
现在,
IUnknown
定义头文件(Windows SDK的Unknwnbase.h
)也定义了一些更有用的C++模板,所以你甚至可以直接调用QueryInterface:型
PS:注意确保这存在于MSVC以外的其他编译器中。