基于DirectX11的ImGui菜单无法在AssaultCube窗口显示,创建D3D设备和交换链失败(错误码80070057)
基于DirectX11的ImGui菜单无法在AssaultCube窗口显示,创建D3D设备和交换链失败(错误码80070057)
首先拆解你遇到的错误:0x80070057对应Windows错误码E_INVALIDARG,意思是调用D3D11CreateDeviceAndSwapChain时传入了无效参数。结合你直接绑定AssaultCube现有窗口创建新DX11设备的场景,这里有几个关键问题需要逐一解决:
一、先修复交换链描述的参数错误
你的DXGI_SWAP_CHAIN_DESC有几个未正确初始化的字段,这是导致参数无效的直接原因。修改CreateDeviceD3D里的交换链描述部分:
DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 2; // 双缓冲是更稳妥的设置,避免渲染闪烁 sd.BufferDesc.Width = 0; // 自动匹配窗口尺寸没问题 sd.BufferDesc.Height = 0; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; // 匹配常见刷新率 sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hWnd; sd.Windowed = TRUE; // 确保游戏处于窗口化模式,若游戏是全屏则设为FALSE sd.SampleDesc.Count = 1; // 必须显式初始化,默认值未定义会导致参数错误 sd.SampleDesc.Quality = 0; sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // 允许切换显示模式
二、核心问题:不能在已有渲染设备的窗口上创建新D3D设备
AssaultCube默认使用Irrlicht引擎,它的默认渲染后端是OpenGL或DirectX9,而非DX11。同一个窗口不能同时被两个不同的D3D设备(甚至不同版本的D3D)占用,这才是你创建设备失败的根本原因。
正确做法:Hook游戏的渲染流程
如果想在游戏上叠加ImGui菜单,不能自己创建新的D3D设备,而是要复用游戏自身的渲染设备:
- 先确认AssaultCube当前使用的渲染API:打开游戏设置,查看是OpenGL还是DirectX9。
- 对应选择ImGui的后端示例:DX9用
imgui_impl_dx9.cpp,OpenGL用imgui_impl_opengl3.cpp。 - Hook游戏的渲染结束函数(比如DX9的
EndScene/Present,OpenGL的glSwapBuffers),在函数调用前后插入ImGui的初始化和绘制逻辑。
三、其他需要检查的细节
- 权限一致性:如果游戏以管理员身份运行,你的程序也必须以管理员身份启动,否则会因权限不足无法访问游戏窗口或创建设备。
- 显卡兼容性:如果你的显卡不支持DX11,
D3D_FEATURE_LEVEL_11_0会失败。可以调整featureLevelArray的顺序,优先尝试更低版本:const D3D_FEATURE_LEVEL featureLevelArray[] = { D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; - 窗口状态:确保AssaultCube处于窗口化模式运行,全屏模式下创建新交换链会有更多限制。
四、临时测试方案(继续用当前DX11代码)
- 把AssaultCube切换到窗口化模式。
- 用管理员身份启动你的程序。
- 应用上面的交换链参数修改后重新编译。
不过还是建议优先走「Hook游戏渲染流程」的路线,这是游戏外挂式GUI的标准做法,能彻底避免和游戏自身渲染设备的冲突。
备注:内容来源于stack exchange,提问作者drmarble
相关产品推荐
相关产品推荐

