QVR  3.0.0
A library to build Virtual Reality applications
QVR: A library to build Virtual Reality applications

Overview

QVR provides the base class QVRApp for Virtual Reality applications. An application implements the subset of QVRApp functions that it needs. See QVRApp for function descriptions.

To run a QVR application, the main() function creates and initializes a QVRManager instances and then calls QApplication::exec() as usual. See QVRManager for a minimal code example.

The QVRManager manages three basic types of objects: observers, processes, and windows:

  • Observers view the virtual scene. Often there is only one observer. Observers are configured via QVRObserverConfig and implemented as QVRObserver.
  • Processes all run the same application binary. The first process initially run by the user is the master process. Slave processes are automatically launched by QVRManager as needed. Each process is connected to one display which can have multiple screens attached. Processes can run on the same host or across a network. Often there is only the master process. Processes are configured via QVRProcessConfig and implemented as QVRProcess.
  • Windows belong to processes and appear on the display that their process is connected to. They can have different positions and sizes on different screens attached to that display. Each window shows a view for exactly one observer (typically that observer views multiple windows). Windows are configured via QVRWindowConfig and implemented as QVRWindow.

All QVR applications support a set of command line options. The most important option lets the user choose a configuration file. See QVRManager::QVRManager(). The same application binary can run on different Virtual Reality display setups by specifying different configuration files.

To get started, see the main descriptions of QVRManager and QVRApp, and then look at the source code of an example application to understand how it is implemented.

Configuration files

A configuration file defines the observers, processes, and windows that the QVRManager will manage.

Each observer, process, and window definition is mapped directly to the QVRObserverConfig, QVRProcessConfig, or QVRWindowConfig classes.

A configuration file starts with a list of observers and their properties.

After that, the list of processes starts. There is always at least one process: the master process. The master process is connected to the display that Qt initially uses by default; if a different display is configured, the master process will be relaunched automatically to take this into account. Slave processes typcially connect to different displays. Optionally, a launcher command can be specified, e.g. to run a slave process on a different host using ssh.

Each process definition contains a list of windows for that process. Since windows provide views into the virtual world, the geometry of the screen wall represented by a window must be known. This geometry is either given by screen wall center coordinates, or by coordinates for three of its corners.

Please see the configuration file examples distributed with QVR to understand how typical configurations look like.

Device definition (see QVRDevice and QVRDeviceConfig):

  • device <id>
    Start a new device definition with the given unique id.
  • tracking <none|static|oculus|openvr|vprn>
    Use the specified tracking method for this device.
  • buttons <none|static|gamepad|vprn|oculus|openvr>
    Use the specified method to query digital buttons for this device.
  • analogs <none|static|gamepad|vrpn|oculus|openvr>
    Use the specified method to query analog joystick elements for this device.

Observer definition (see QVRObserver and QVRObserverConfig):

  • observer <id>
    Start a new observer definition with the given unique id.
  • navigation <stationary|vrpn|wasdqe|custom> [parameters...]
    Set the navigation type and parameters.
  • navigation_position <x> <y> <z>
    Set the initial navigation position.
  • navigation_forward <x> <y> <z>
    Set the initial navigation forward (or viewing) direction.
  • navigation_up <x> <y> <z>
    Set the initial navigation up direction.
  • tracking <stationary|vrpn|oculus|custom> [parameters...]
    Set the tracking type and parameters.
  • eye_distance <meters>
    Set the interpupillary distance.
  • tracking_position <x> <y> <z>
    Set the initial tracking position.
  • tracking_forward <x> <y> <z>
    Set the initial tracking forward (or viewing) direction.
  • tracking_up <x> <y> <z>
    Set the initial tracking up direction.

Process definition (see QVRProcess and QVRProcessConfig):

  • process <id>
    Start a new process definition with the given unique id.
  • ipc <tcp-socket|local-socket|shared-memory|auto>
    Select the inter-process communication method.
  • address <ip-address>
    Set the IP address to bind the server to when using tcp-based inter-process communication.
  • launcher <prg-and-args>
    Launcher commando used to start this process.
  • display <name>
    Display that this process is connected to.
  • sync_to_vblank <true|false>
    Whether windows of this process are synchronized with the vertical refresh of the display.
  • decoupled_rendering <true|false>
    Whether the rendering of this slave process is decoupled from the master process.

Window definition (see QVRWindow and QVRWindowConfig):

  • window <id>
    Start a new window definition with the given unique id, within the current process definition.
  • observer <id>
    Set the observer that this window provides a view for.
  • output <center|left|right|stereo|red_cyan|green_magenta|amber_blue|oculus|openvr|googlevr>
    Set the output mode. For center, left, right, and stereo, you can set an additional output plugin.
  • display_screen <screen>
    Select the Qt screen index on the Qt display that this process is connected to.
  • fullscreen <true|false> Whether to show the window in fullscreen mode.
  • position <x> <y>
    Set the window position on the Qt screen in pixels.
  • size <w> <h>
    Set the window size on the Qt screen in pixels.
  • screen_is_fixed_to_observer <true|false>
    Whether the screen wall represented by this window is fixed to the observer, like a head-mounted display, or it is fixed in virtual world space.
  • screen_is_given_by_center <true|false>
    Whether the screen wall represented by this window is given by its center or by three of its corners.
  • screen_center <x> <y> <z>
    Set screen wall center coordinates.
  • screen_wall <blx> <bly> <blz> <brx> <bry> <brz> <tlx> <tly> <tlz>
    Set the screen wall geometry defined by three points: bottom left corner, bottom right corner, and top left corner.
  • render_resolution_factor <factor>
    Set the render resolution factor.

Implementation

The QVRManager creates an invisible main OpenGL context for each process. This context is used for all calls to QVRApp application functions: the application only has to deal with this one context. The rendering results are directed into a set of textures that cover all the windows of the process.

When all window textures have been rendered, they are put on screen by the actual visible windows who all have access to the textures from the main window. The windows themselves render in separate rendering threads. On buffer swap, only these rendering threads block. The main thread fills the waiting time with CPU work such as processing events and calling the QVRApp::update() function of the application.

The process initially started by the user is the master process. QVRManager launch slave processes as required by the configuration file, and it will handle all necessary synchronization and data exchange with these slave processes.