OpenVR初始化失败主因是SteamVR未运行或权限不足;姿态为空因未调WaitGetPoses刷新缓存;纹理提交失败因未按平台规范设共享属性;事件收不到因未启用事件队列。

OpenVR 初始化失败:vr::VR_Init 返回 VRInitError_Init_HmdNotFound
不是头显没插,而是 SteamVR 进程根本没起来,或者当前用户没权限访问 VR 运行时。OpenVR 不会自动拉起 SteamVR,它只连接已运行的实例。
- 先手动启动 SteamVR(从 Steam 客户端或直接运行
steam://run/250820),再运行你的程序 - 确保你的程序和 SteamVR 在同一用户会话下——比如用 Windows 服务或远程桌面后台运行时,
vr::VR_Init几乎必失败 - 初始化前加一句
vr::VR_IsHmdPresent()判断,比硬等VR_Init更早暴露问题 - 别在 DLL 的
DllMain里调VR_Init,Windows 加载器阶段不支持 IPC,会卡死或返回VRInitError_Init_Timeout
获取追踪姿态总为空:vr::TrackedDevicePose_t 的 bPoseIsValid 始终为 false
OpenVR 不会“推”姿态,它只“存”上一帧数据;你得主动调 vr::VR_Compositor()->WaitGetPoses() 才能刷新所有设备的位姿缓存。
- 必须每帧调一次
WaitGetPoses,且要在渲染前、提交前——漏掉一帧,后续所有GetRawTrackedDevicePoses都拿不到新数据 -
WaitGetPoses第一个参数是头显 ID(通常是vr::k_unTrackedDeviceIndex_Hmd),第二个是手柄等其他设备数组,别把顺序搞反 - 如果只关心手柄,也得传入包含 HMD 的完整数组,否则 OpenVR 可能跳过姿态更新逻辑
- 返回
vr::EVRCompositorError::VRCompositorError_None才代表姿态已就绪;其他错误(如VRCompositorError_IncompatibleVersion)说明 SDK 头文件和运行时版本不匹配
SteamVR 启动后黑屏或报错 VRCompositorError_TextureIsNotShared
你传给 Submit 的纹理句柄,对 OpenVR 来说“不可见”——常见于 D3D11 共享纹理没设 DXGI_USAGE_SHARED,或 Vulkan 的 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT 缺失。
- D3D11:创建纹理时
D3D11_TEXTURE2D_DESC的Usage必须是D3D11_USAGE_DEFAULT,且BindFlags包含D3D11_BIND_SHADER_RESOURCE,CPUAccessFlags为 0 - Vulkan:提交前必须调
vkGetImageMemoryRequirements2确认内存类型支持共享,且vkCreateImage的flags要含VK_IMAGE_CREATE_ALIAS_BIT或对应平台扩展要求 - OpenGL 下不用共享纹理,但必须用
glXMakeCurrent把上下文绑定到正确显示(X11)或wglMakeCurrent(Windows),否则Submit会静默失败
手柄按钮事件收不到:vr::VRSystem()->PollNextEvent 总是返回 false
OpenVR 的事件队列默认不开启,而且它和姿态更新是两套独立路径——你不主动启用,按钮、震动、系统菜单键统统不会进队列。
立即学习“C++免费学习笔记(深入)”;
- 初始化后立刻调
vr::VRSystem()->SetBoolTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_BooleanProperty, true)是没用的;正确做法是调vr::VRSystem()->SetStringTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_InputProfilePath_String, "{default}/input/all_views.json") - 更简单的是:在 SteamVR 设置里打开「开发者模式」,并确保你的应用被识别为「已知应用」(通过
vrpathreg addapplication注册路径) -
PollNextEvent必须在主线程循环中持续调用,不能只调一次;事件结构体vr::VREvent_t的event_type字段才是判断按钮的关键,比如VRInputEvent_ButtonPress对应按键按下 - 别依赖
TrackedDeviceButtonPressed这类旧事件——它们已被弃用,SteamVR 2.x+ 默认不发



















