/** Helper function for acquiring the appropriate FSceneViewport */ FSceneViewport* FindSceneViewport() { if (!GIsEditor) { UGameEngine* GameEngine = Cast<UGameEngine>(GEngine); return GameEngine->SceneViewport.Get(); } #if WITH_EDITOR else { UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine); return (FSceneViewport*)(EditorEngine->GetPIEViewport()); } #endif return nullptr; }
bool FOSVRHMD::EnableStereo(bool bStereo) { bool bNewSteroEnabled = IsHMDConnected() ? bStereo : false; if (bNewSteroEnabled == bStereoEnabled) { return bStereoEnabled; } bStereoEnabled = bNewSteroEnabled; if (bStereoEnabled) { StartCustomPresent(); } else { StopCustomPresent(); } if (bHmdEnabled != bStereoEnabled) { EnableHMD(bStereoEnabled); } auto leftEye = HMDDescription.GetDisplaySize(OSVRHMDDescription::LEFT_EYE); auto rightEye = HMDDescription.GetDisplaySize(OSVRHMDDescription::RIGHT_EYE); auto width = leftEye.X + rightEye.X; auto height = leftEye.Y; GetRenderTargetSize_GameThread(width, height, width, height); // On Android, we currently use the resolution Unreal sets for us, bypassing OSVR // We may revisit once display plugins are added to OSVR-Core. #if !PLATFORM_ANDROID FSystemResolution::RequestResolutionChange(width, height, EWindowMode::Windowed); #endif FSceneViewport* sceneViewport; if (!GIsEditor) { //UE_LOG(OSVRHMDLog, Warning, TEXT("OSVR getting UGameEngine::SceneViewport viewport")); UGameEngine* gameEngine = Cast<UGameEngine>(GEngine); sceneViewport = gameEngine->SceneViewport.Get(); } #if WITH_EDITOR else { //UE_LOG(OSVRHMDLog, Warning, TEXT("OSVR getting editor viewport")); UEditorEngine* editorEngine = CastChecked<UEditorEngine>(GEngine); sceneViewport = (FSceneViewport*)editorEngine->GetPIEViewport(); if (sceneViewport == nullptr || !sceneViewport->IsStereoRenderingAllowed()) { sceneViewport = (FSceneViewport*)editorEngine->GetActiveViewport(); if (sceneViewport != nullptr && !sceneViewport->IsStereoRenderingAllowed()) { sceneViewport = nullptr; } } } #endif if (!sceneViewport) { UE_LOG(OSVRHMDLog, Warning, TEXT("OSVR scene viewport does not exist")); return false; } else { //UE_LOG(OSVRHMDLog, Warning, TEXT("OSVR scene viewport exists")); #if !WITH_EDITOR auto window = sceneViewport->FindWindow(); #endif if (bStereo) { //UE_LOG(OSVRHMDLog, Warning, TEXT("OSVR bStereo was true")); // the render targets may be larger or smaller than the display resolution // due to renderOverfillFactor and renderOversampleFactor settings // The viewports should match the render target size not the display size //if (mCustomPresent) //{ //uint32 iWidth, iHeight; //mCustomPresent->CalculateRenderTargetSize(iWidth, iHeight); //float screenScale = GetScreenScale(); //width = float(iWidth) * (1.0f / screenScale); //height = float(iHeight) * (1.0f / screenScale); //} //else //{ // temporary workaround. The above code doesn't work because when the game // is packaged, mCustomPresent is not initialized before this call. In the editor, it is. // calling CalculateRenderTargetSize when mCustomPresent isn't initialized // results in Initialize being called, which has to be done on the render thread. // The proper fix is to move the render target size API from render manager to OSVR-Core // so we don't need a graphics context to calculate them. In the meantime, we'll // implement this temporary workaround (parse the renderManagerConfig manually and // calculate the render target sizes ourselves). //} //UE_LOG(OSVRHMDLog, Warning, TEXT("OSVR Actually set viewport size")); sceneViewport->SetViewportSize(width, height); #if !WITH_EDITOR if (window.IsValid()) { window->SetViewportSizeDrivenByWindow(false); } #endif } #if !WITH_EDITOR else { if (window.IsValid()) { auto size = sceneViewport->FindWindow()->GetSizeInScreen(); sceneViewport->SetViewportSize(size.X, size.Y); window->SetViewportSizeDrivenByWindow(true); } } #endif } GEngine->bForceDisableFrameRateSmoothing = bStereo; return bStereoEnabled; }