Developing with OpenXR and Monado

After installing the OpenXR SDK and Monado with the Getting Started Guide it is time to develop an OpenXR application.

The OpenXR SDK

On Archlinux, the OpenXR loader installs these files

Other distributions may use different paths like /usr/lib/x86_64-linux-gnu/....

The OpenXR headers

To start developing for OpenXR only those components are necessary. Similar to how Vulkan applications are developed by including Khronos’ Vulkan headers and linking to Khronos’ Vulkan loader, OpenXR applications include Khronos’ OpenXR headers and link to Khronos’ OpenXR loader. Just like compiling a Vulkan application does not require any Vulkan driver to be installed, compiling an OpenXR application does not require any OpenXR runtime to be installed.

Khronos has not released a reference implementation for OpenXR, so for actually running an OpenXR application some vendor’s OpenXR runtime (for example Monado) has to be installed.

Setting up the project

CMake

Here is a minimal cmake example to compile an example executable that can include OpenXR headers and links to the OpenXR loader.

cmake_minimum_required(VERSION 3.0.0)
project(Example)

add_executable(example main.c)

find_package(OpenXR REQUIRED)
if(OpenXR_FOUND)
  target_include_directories(example PRIVATE OpenXR::Headers)
  target_link_libraries(example PRIVATE OpenXR::openxr_loader)
else()
  MESSAGE(FATAL_ERROR "Please verify your OpenXR SDK installation")
endif()

As an alternative you can use OpenXR’s pkg-config file with CMake’s FindPkgConfig module.

cmake_minimum_required(VERSION 3.0.0)
project(Example)

add_executable(example main.c)

INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(OpenXR REQUIRED openxr)
if(OpenXR_FOUND)
  target_link_libraries(example PRIVATE ${OpenXR_LIBRARIES})
  target_include_directories(example PRIVATE ${OpenXR_HEADERS})
else()
  MESSAGE(FATAL_ERROR "Please verify your OpenXR SDK installation")
endif()

If you prefer using your own FindOpenXR.cmake file, the xrtraits utility has an example.

meson

Meson uses pkg-config by default for its dependency() mechanism.

project('Example', ['c'])

openxr_dep = dependency('openxr')
executable('example', ['main.c'], dependencies: [openxr_dep])

Application

With this project setup you can start including the <openxr/openx.h> header and start calling OpenXR functions.

As a starting point, here is a minimal C example for starting an OpenGL application on Linux with the xlib graphics binding.

// openxr_platform.h does not include all its dependencies, we have to include some headers before it
#include <string.h>
#include <X11/Xlib.h>
#include <GL/glx.h>

// before including openxr_platform.h we have to define which platform specific parts we want enabled
#define XR_USE_PLATFORM_XLIB
#define XR_USE_GRAPHICS_API_OPENGL
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>

int main()
{
  char *extensions[] = { XR_KHR_OPENGL_ENABLE_EXTENSION_NAME };
  int extension_count = sizeof(extensions) / sizeof(extensions[0]);

  XrInstanceCreateInfo instanceCreateInfo = {
    .type = XR_TYPE_INSTANCE_CREATE_INFO,
    .next = NULL,
    .createFlags = 0,
    .enabledExtensionCount = extension_count,
    .enabledExtensionNames = (const char * const *) extensions,
    .enabledApiLayerCount = 0,
    .applicationInfo =  {
      .applicationVersion = 1,
      .engineVersion = 0,
      .apiVersion = XR_CURRENT_API_VERSION,
    },
  };

  strncpy(instanceCreateInfo.applicationInfo.applicationName, "Example Application", XR_MAX_APPLICATION_NAME_SIZE);
  strncpy(instanceCreateInfo.applicationInfo.engineName, "Example Engine", XR_MAX_APPLICATION_NAME_SIZE);

  XrInstance instance;
  xrCreateInstance(&instanceCreateInfo, &instance);
  return 0;
}

Explaining the entire basic OpenXR API is no short task. Instead, the commented OpenXR-Simple-Example tries to be as straightforward as possible in dealing with the OpenXR API.

You can also look at the list of open source examples and applications or a recording of the OpenXR Master Class at Laval Virtual.

Your most important reference of course will be the OpenXR specification: https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html