将 C++ 应用程序变成 VR

Turning a C++ Application into VR

我有一个使用 openGL 和 Cuda 的 C++ 应用程序,我想将其转换为 VR 应用程序。我在网上搜索了一下,似乎开发 VR 应用程序的标准方法是使用游戏引擎(unity 或 unreal)。是否有任何其他可能的方法来避免使用其中之一,而只是将我现有的应用程序转换为 VR?

通常的方法是,在开始渲染帧时,轮询 VR API 每只眼睛的投影和 "camera" 平移矩阵,然后使用它来渲染使用 FBO 转换为纹理,最后将这些纹理的 ID 传回 API。使用 OpenVR:

初始化FBO

vr::EVRInitError err_hmd = vr::VRInitError_None;
m_hmd = vr::VR_Init(&err_hmd, vr::VRApplication_Scene);
if( err_hmd != vr::VRInitError_None ){
    m_hmd = nullptr;
}
if( m_hmd ){
    m_hmd->GetRecommendedRenderTargetSize(&m_hmd_width, &m_hmd_height);
    mat44_from_hmd44(m_prj_l, m_hmd->GetProjectionMatrix(vr::Eye_Left,  0.01f, 10.f) );
    mat44_from_hmd44(m_prj_r, m_hmd->GetProjectionMatrix(vr::Eye_Right, 0.01f, 10.f) );

    mat44_from_hmd34(m_eye_l, m_hmd->GetEyeToHeadTransform(vr::Eye_Left)  );
    mat44_from_hmd34(m_eye_r, m_hmd->GetEyeToHeadTransform(vr::Eye_Right) );

    if( !vr::VRCompositor() ){
        vr::VR_Shutdown();
        m_hmd = nullptr;
    }

    m_timer_vr = startTimer(1000/50);
} else {
}

if( m_hmd_width && m_hmd_height ){
    qDebug() << "resize to" << m_hmd_width << m_hmd_height;
    eye_target_textures.create(m_hmd_width, m_hmd_height);
}

更新 HMD 姿势:

vr::VREvent_t vrev;
while( m_hmd->PollNextEvent(&vrev, sizeof(vrev)) );

// Process SteamVR action state
// UpdateActionState is called each frame to update the state of the actions themselves. The application
// controls which action sets are active with the provided array of VRActiveActionSet_t structs.
vr::VRActiveActionSet_t actionSet = { 0 };
vr::VRInput()->UpdateActionState( &actionSet, sizeof(actionSet), 1 );

vr::TrackedDevicePose_t tdp[ vr::k_unMaxTrackedDeviceCount ];
vr::VRCompositor()->WaitGetPoses(tdp, vr::k_unMaxTrackedDeviceCount, NULL, 0);

mat4x4_translate(m_pose, 0, 0, -1);

for( int i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i ){
    if( !tdp[i].bPoseIsValid ){ continue; }

    switch( m_hmd->GetTrackedDeviceClass(i) ){
    case vr::TrackedDeviceClass_HMD:
        mat44_from_hmd34(m_pose, tdp[i].mDeviceToAbsoluteTracking );
        break;
    }
}

然后在渲染时使用 m_posem_eye… 矩阵。