You are currently viewing archived documentation. Use the left navigation to return to the latest.

Display Device Management

This section was original written when management of the Rift display as part of the desktop was the only option.

With the introduction of the Oculus Display Driver, the standard approach is now to select Direct HMD Access from Apps mode and let the SDK manage the device. However, until the driver matures, it might still be necessary to switch to one of the legacy display modes which requires managing the display as part of the desktop. For this reason, this section is still in this guide for reference purposes.

Display Identification

Display devices identify themselves and their capabilities using Extended Display Identification Data (EDID).

The display within the Oculus Rift interacts with the system in the same way as a typical PC monitor. It also provides EDID information which identifies it as having a OVR manufacturer code, a Rift DK1model, and support for several display resolutions (including the native 1280 × 800 at 60Hz).

Display Configuration

After connecting a Rift to the PC, you can modify the display settings through the Windows Control Panel.

In Windows 7, select Control Panel -> All Control Panel Items -> Display -> Screen Resolution. In MacOS, select System Preferences -> Displays. In Ubuntu Linux, select System Settings -> Displays.

The following figure shows how to configure a Windows PC with the Rift display and a monitor. In this configuration, there are four available modes: duplicate mode, extended mode, standalone mode the monitor, and standalone mode for the Rift.

Figure 15. Windows Screen Resolution Dialog Box

Duplicate Display Mode

In duplicate display mode, the same portion of the desktop is shown on both displays; each device uses the same resolution and orientation settings. Your computer attempts to choose a resolution that is supported by both displays, while favoring the native resolutions described in the EDID information reported by the displays. Duplicate mode can be useful for configuring the Rift. However, it suffers from vsync issues.

Extended Display Mode

In extended mode, the displays show different portions of the desktop. You can use the Control Panel to set the desired resolution and orientation independently for each display. Extended mode suffers from shortcomings due to the fact that the Rift is not a viable way to interact with the desktop. Nevertheless, it is the current recommended configuration option. For more information about the shortcomings, see Rift Display Considerations.

Standalone Display Mode

In standalone mode, the desktop is displayed on either the monitor or the Rift. It is possible to configure the Rift as the sole display, but this becomes impractical when interacting with the desktop.

Selecting A Display Device

Reading of EDID information from display devices can occasionally be slow and unreliable. In addition, EDID information may be cached, leading to problems with old data.

As a result, display devices can become associated with incorrect display names and resolutions, with arbitrary delays before the information becomes current.

Because of these issues, we adopt an approach that attempts to identify the Rift display name among the attached display devices. However, we do not require that it is found for an HMD device to be created using the API.

If the Rift display device is not detected, but the Rift is detected through USB, then an empty display name string is returned. When this happens, your application can attempt to locate it using additional information, such as the display resolution.

In general, due to the uncertainty associated with identifying the Rift display device, you might want to incorporate functionality into your application that allows the user to choose the display manually, such as from a drop-down list of display devices. One possible cause of the this scenario, aside from EDID issues, is that the user failed to plug in the Rift video cable. Make sure you have appropriate assistance within your application to help users troubleshoot an incorrectly connected Rift device.

Windows

If there are no EDID issues and we detect the Rift display device successfully, then we return the display name corresponding to that device, for example \\.\DISPLAY1\Monitor0.

To display the video output on the Rift, the application needs to match the display name determined above to an object used by the rendering API. Unfortunately, each rendering system used on Windows (OpenGL, Direct3D 9, Direct3D 10-11) uses a different approach. OpenGL uses the display device name returned in HMDInfo, Direct3D requires the display name must be matched against a list of displays returned by D3D. You can use the DesktopX and DesktopY members of HMDInfo to position a window on the Rift if you do not want to use fullscreen mode.

When using Direct3D 10 or 11, the following code shows how to obtain an IDXGIOutput interface using the DXGI API:

IDXGIOutput* searchForOculusDisplay(char* oculusDisplayName)
{
    IDXGIFactory* pFactory;
    CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));

    UInt32 adapterIndex = 0;
    IDXGIAdapter* pAdapter;

    // Iterate through adapters.
    while (pFactory->EnumAdapters(adapterIndex, &pAdapter) != 
                                DXGI_ERROR_NOT_FOUND)
    {               
        UInt32 outputIndex = 0;
        IDXGIOutput* pOutput;
        
        // Iterate through outputs.
        while (pAdapter->EnumOutputs(outputIndex, &pOutput) != 
                                DXGI_ERROR_NOT_FOUND)
        {           
            DXGI_OUTPUT_DESC outDesc;
            pOutput->GetDesc(&outDesc);
            char* outputName = outDesc.DeviceName;

            // Try and match the first part of the display name.
            // For example an outputName of "\\.\DISPLAY1" might
            // correspond to a displayName of "\\.\DISPLAY1\Monitor0".
            // If two monitors are setup in 'duplicate' mode then they will
            // have the same 'display' part in their display name.
            if (strstr(oculusDisplayName, outputName) == oculusDisplayName)
            {
                return pOutput;
            }
        }
    }

    return NULL;
}                
            

After you’ve successfully obtained the IDXGIOutput interface, you can set your Direct3D swap-chain to render to it in fullscreen mode using the following:

IDXGIOutput* pOculusOutputDevice = searchForOculusDisplay(oculusDisplayName);
pSwapChain->SetFullscreenState(TRUE, pOculusOutputDevice);                
            

When using Direct3D 9, you must create the Direct3DDevice with the “adapter” number corresponding to the Rift (or other display that you want to output to). This next function shows how to find the adapter number:

unsigned searchForOculusDisplay(const char* oculusDisplayName)
{
for (unsigned Adapter=0; Adapter < Direct3D->GetAdapterCount(); Adapter++)
{
MONITORINFOEX Monitor;
Monitor.cbSize = sizeof(Monitor);
if (::GetMonitorInfo(Direct3D->GetAdapterMonitor(Adapter), &Monitor) && Monitor.szDevice[0])
{
DISPLAY_DEVICE DispDev;
memset(&DispDev, 0, sizeof(DispDev));
DispDev.cb = sizeof(DispDev);
if (::EnumDisplayDevices(Monitor.szDevice, 0, &DispDev, 0))
{
if (strstr(DispDev.DeviceName, oculusDisplayName))
{
return Adapter;
}
}
}
}
return D3DADPATER_DEFAULT;
}
            

Unfortunately, you must re-create the device to switch fullscreen displays. You can use a fullscreen device for windowed mode without recreating it (although it still has to be reset).

MacOS

When running on MacOS, the ovrHMDDesc struct contains a DisplayID which you should use to target the Rift in fullscreen. If the Rift is connected (and detected by libovr), its DisplayId is stored, otherwise DisplayId contains 0. The following is an example of how to use this to make a Cocoa NSView fullscreen on the Rift:

CGDirectDisplayId RiftDisplayId = (CGDirectDisplayId) hmd->DisplayId;

NSScreen* usescreen = [NSScreen mainScreen];
NSArray* screens = [NSScreen screens];
for (int i = 0; i < [screens count]; i++)
{
    NSScreen* s = (NSScreen*)[screens objectAtIndex:i];
    CGDirectDisplayID disp = [NSView displayFromScreen:s];

    if (disp == RiftDisplayId)
        usescreen = s;
}
        
[View enterFullScreenMode:usescreen withOptions:nil];                
            

You can use the WindowPos member of ovrHMDDesc to position a window on the Rift if you do not want to use fullscreen mode.

Rift Display Considerations

There are several considerations when it comes to managing the Rift display on a desktop OS.

Duplicate Mode VSync

In duplicate monitor mode, it is common for the supported video timing information to be different across the participating monitors, even when displaying the same resolution. When this occurs, the video scans on each display will be out of sync and the software vertical sync mechanism will be associated with only one of the displays. In other words, swap-chain buffer switches (for example following a glSwapBuffers or Direct3D Present call) only occurs at the correct time for one of the displays, and ‘tearing’ will occur on the other display. In the case of the Rift, tearing is very distracting, and so ideally we’d like to force it to have vertical sync priority. Unfortunately, the ability to do this is not something currently exposed in system APIs.

Extended Mode Problems

When extended display mode is used in conjunction with the Rift, the desktop partly extebds onto the regular monitors and partly onto the Rift. Since the Rift displays different portions of the screen to the left and right eyes, it is not suited to displaying the desktop in a usable form, and confusion may arise if icons or windows find their way onto the portion of the desktop displayed on the Rift.

Observing Rift Output on a Monitor

Sometimes, it can be useful to see the same video output on the Rift and on an external monitor. This is particularly useful when demonstrating the device to a new user, or during application development. One way to achieve this is through the use of duplicate monitor mode as described above. However, we don’t currently recommend this approach due to the vertical sync priority issue. An alternative approach is through the use of a DVI or HDMI splitter. These take the video signal coming from the display adapter and duplicate it such that it can be fed to two or more display devices simultaneously. Unfortunately, this can also cause problems depending on how the EDID data is managed. Specifically, with several display devices connected to a splitter, which EDID information should be reported back to the graphics adapter? Low cost HDMI splitters have been found to exhibit unpredictable behavior. Typically they pass on EDID information from one of the attached devices, but exactly how the choice is determined is often unknown. Higher cost devices may have explicit schemes (for example they report the EDID from the display plugged into output port one), but these can cost more than the Rift itself! Generally, the use of third party splitters and video switching boxes means that Rift EDID data may not be reliably reported to the OS and libovr will not be able to identify the Rift.

Windows: Direct3D Enumeration

As described above, the nature of the Rift display means that it is not suited to displaying the Windows desktop. As a result you might be inclined to set standalone mode for your regular monitor to remove the Rift from the list of devices displaying the Windows desktop. Unfortunately, this also causes the device to no longer be enumerated when querying for output devices during Direct3D setup. As a result, the only viable option currently is to use the Rift in extended display mode.