This is a quick post about the proper way to set up the Oculus Rift DK2 on GNU/Linux, which might not be obvious for users not deeply familiar with the X window system.
(feel free to skip)
I remember discussing this a long time ago in the oculus forums, back when the linux version of the oculus SDK was doing absurdities such as relying on Xinerama to detect and use the oculus display. Setting up the rift display as an extension of the desktop, is wrought with peril and woe. Thankfully, the X window system is awesome, and used to deal with such diverse multi-display contraptions, back when burly men programmed computers made of pumps, grease, and steel… true story.
So anyway, the whole hoop-jumping circus the oculus runtime tries to set up on ms-winblows for “direct access” to the rift, using grotesque custom monitor and display drivers, is really easy to do under X; it’s built into the system since its inception, and it’s called a “Screen”.
It goes like this: each X server is called a “Display”, and each Display has one or more Screens. Before the advent of runtime-reconfigurable X servers, we had to write a configuration file (/etc/X11/xorg.conf or further back /etc/X11/XF86Config) which specified (among other things):
- One or more “Device” sections, describing each graphics card, or graphics output in case of multi-head GPUs, we have installed
- One or more “Monitor” sections, describing each monitor we have connected, with details such as refresh rate ranges
- One or more “Screen” sections, binding together a Device and a Monitor by referencing the appropriate section identifiers, to describe available color depths and resolutions for each combination.
- And a “ServerLayout” section, referencing each Screen we want to use, and specifying their spatial relationships in the real world (such as screen A is on the left side of screen B, which is below screen C, etc)
Once set up this way, the configuration couldn’t change without restarting the X server, and each screen would be completely separate; the mouse cursor would move between screens (according to the spatial layout specified in the ServerLayout), but windows belonged to a specific screen, and couldn’t move between them. Rigid, but simple and extremely clear.
Nowadays of course, most multi-monitor setups use the XR&R (xrandr) extension to add and remove “outputs” on a single X screen dynamically, or the equivalent nvidia proprietary counterpart called TwinView. This approach extends a single desktop area across multiple monitors, which is awesome for regular monitors, but really horrible when it comes to peculiar devices such as the rift.
The proper way to do it, is to set up the rift as a separate X screen. To do this, you just need to create an xorg.conf file under /etc/X11 with something like this:
Section "ServerLayout" Identifier "default" Screen 0 "scr_main" 0 0 Screen 1 "scr_rift" Below "scr_main" # could be RightOf, LeftOf, etc EndSection Section "Monitor" Identifier "mon_dell" VendorName "DELL" ModelName "DELL U2412M" EndSection Section "Monitor" Identifier "mon_rift" VendorName "Unknown" ModelName "OVR Rift DK2" EndSection Section "Device" Identifier "dev_main" Driver "nvidia" VendorName "NVIDIA Corporation" BoardName "GeForce GTX 650 Ti" BusID "PCI:1:0:0" Screen 0 EndSection Section "Device" Identifier "dev_rift" Driver "nvidia" VendorName "NVIDIA Corporation" BoardName "GeForce GTX 650 Ti" BusID "PCI:1:0:0" Screen 1 EndSection Section "Screen" Identifier "scr_main" Device "dev_main" Monitor "mon_dell" DefaultDepth 24 SubSection "Display" Depth 24 EndSubSection EndSection Section "Screen" Identifier "scr_rift" Device "dev_rift" Monitor "mon_rift" DefaultDepth 24 SubSection "Display" Depth 24 EndSubSection EndSection
Of course if you use the proprietary nvidia drivers, you may also run nvidia-settings, configure your screens from the GUI, and press a button to create the xorg.conf file automatically (which will take effect when you restart your X server).
Note that under “configuration” for the currently selected rift screen, it says “X screen 1”. Initially this combo box will have “X screen 0” selected; you need to click on it and select “New X screen” to create a separate screen for the rift.
Running programs on the rift screen
If the rift is set up as a separate X screen, you don’t have to fiddle with moving windows around to place them at the right position of the desktop to show up in the rift, and pray to odin that they stay there when you switch to fullscreen. Just instruct the program to use the correct screen by setting the DISPLAY environment variable, and it can’t escape if its life depended on it (well it could ignore the DISPLAY env var and open a window elsewhere, but that takes conscious effort to do).
So for instance to run my oculus2 test program on the rift, I just have to do something like:
$ DISPLAY=:0.1 ./oculus2
The first number just after the colon is the display (X server) we wish to run the program on, followed by the screen number after the dot (our main monitor would be :0.0, or just :0).
Spying on the rift
Sometimes it’s very useful to see what’s going on in the rift display, without having to put it on and off all the time, especially when hacking VR programs. For this reason I wrote a small shell script which starts a vnc server on the rift screen, and a vnc viewer on the main screen:
#!/bin/sh x11vnc -display :0.1 -scale 0.5 -rotate +90 \ -localhost -nopw -norc -timeout 1 \ -q -viewonly -once -bg && \ vncviewer localhost
I rotated the vnc output by 90 degrees because the rift has a portrait display and all VR apps are sideways to compensate. I also scaled it by 50%, and instructed the vnc server to shut down when the viewer disconnects.
Feel free to use it, I found it very handy.