How do you switch stereo rendering devices at run time?

Hello,

Engine version 4.4.3

I’m looking to switch stereo rendering between stereo and OVR devices at run time. Currently I am using the FFakeStereoRenderingDevice for use with 3DTV and the OculusHMD plugin for VR. My current implementation allows me to switch from 3DTV to OVR at run time with no problems, but when I switch back, the window appears to be stuck on the last frame rendered for the oculus renderer. I can hear audio and the game continues to run.

My current implementation creates both renderers when UEngine::InitializeHMDDevice() and stores shared pointers to each as members of the engine. then, in my player controller just swap which pointer is currently assigned to UEngine::StereoRenderingDevice

bool UEngine::InitializeHMDDevice()
{
	if( !GIsEditor )
	{


		if (FParse::Param(FCommandLine::Get(), TEXT("renderswitchenabled")))
		{
			// Start the rendering device in 3D
			TSharedPtr<FFakeStereoRenderingDevice> FakeStereoDevice(new FFakeStereoRenderingDevice());
			StereoRenderingDevice = FakeStereoDevice;
			Stereo3DRenderingDevice = FakeStereoDevice;

			// Start the HMD and don't enable or set it as the renderer
			if (!HMDDevice.IsValid() && !IsRunningDedicatedServer())
			{
				// Get a list of plugins that implement this feature
				TArray<IHeadMountedDisplayModule*> HMDImplementations = IModularFeatures::Get().GetModularFeatureImplementations<IHeadMountedDisplayModule>(IHeadMountedDisplayModule::GetModularFeatureName());
				for (auto HMDModuleIt = HMDImplementations.CreateIterator(); HMDModuleIt && !HMDDevice.IsValid(); ++HMDModuleIt)
				{
					HMDDevice = (*HMDModuleIt)->CreateHeadMountedDisplay();
				}
			}

			return StereoRenderingDevice.IsValid();
		}

As mentioned, when I switch from stereo to OVR HMD the switch occurs normally. However, switching from OVR to stereo doesn’t seem to utilize the other device.

Is there a legitimate method for notifying the engine of a request to change rendering devices?

The solution was to add a second shared pointer to hold the reference to the hmd device when it wasn’t in use. Then call

		// Reset the HMDDevice pointer to clear the HMD reference
		GEngine->HMDDevice.Reset();

to ensure that the engine does not think that HMDDevice is valid.

I would still be interested to hear if there is a more natural way to accomplish this behavior without altering the engine header and implementation.