| /*! |
| |
| @page rift Oculus Rift guide |
| |
| @tableofcontents |
| |
| This guide is intended to fill in the gaps between the |
| [Oculus PC SDK documentation](https://developer.oculus.com/documentation/) and |
| the rest of the GLFW documentation and is not a replacement for either. It |
| requires you to use [native access](@ref native) and assumes a certain level of |
| proficiency with LibOVR, platform specific APIs and your chosen development |
| environment. |
| |
| While GLFW has no explicit support for LibOVR, it is tested with and tries to |
| interoperate well with it. |
| |
| @note Because of the speed of development of the Oculus SDK, this guide may |
| become outdated before the next release. If this is a local copy of the |
| documentation, you may want to check the GLFW website for updates. This |
| revision of the guide is written against version 0.4.4 of the SDK. |
| |
| |
| @section rift_include Including the LibOVR and GLFW header files |
| |
| Both the OpenGL LibOVR header and the GLFW native header need macros telling |
| them what OS you are building for. Because LibOVR only supports three major |
| desktop platforms, this can be solved with canonical predefined macros. |
| |
| @code |
| #if defined(_WIN32) |
| #define GLFW_EXPOSE_NATIVE_WIN32 |
| #define GLFW_EXPOSE_NATIVE_WGL |
| #define OVR_OS_WIN32 |
| #elif defined(__APPLE__) |
| #define GLFW_EXPOSE_NATIVE_COCOA |
| #define GLFW_EXPOSE_NATIVE_NSGL |
| #define OVR_OS_MAC |
| #elif defined(__linux__) |
| #define GLFW_EXPOSE_NATIVE_X11 |
| #define GLFW_EXPOSE_NATIVE_GLX |
| #define OVR_OS_LINUX |
| #endif |
| |
| #include <GLFW/glfw3.h> |
| #include <GLFW/glfw3native.h> |
| |
| #include <OVR_CAPI_GL.h> |
| @endcode |
| |
| Both the GLFW and LibOVR headers by default attempt to include the standard |
| OpenGL `GL/gl.h` header (`OpenGL/gl.h` on OS X). If you wish to use a different |
| standard header or an [extension loading library](@ref context_glext_auto), |
| include that header before these. |
| |
| |
| @section rift_init Initializing LibOVR and GLFW |
| |
| LibOVR needs to be initialized before GLFW. This means calling at least |
| `ovr_Initialize`, `ovrHmd_Create` and `ovrHmd_ConfigureTracking` before @ref |
| glfwInit. Similarly, LibOVR must be shut down after GLFW. This means calling |
| `ovrHmd_Destroy` and `ovr_Shutdown` after @ref glfwTerminate. |
| |
| |
| @section rift_direct Direct HMD mode |
| |
| Direct HMD mode is the recommended display mode for new applications, but the |
| Oculus Rift runtime currently (January 2015) only supports this mode on Windows. |
| In direct mode the HMD is not detectable as a GLFW monitor. |
| |
| |
| @subsection rift_direct_create Creating a window and context |
| |
| If the HMD is in direct mode you can use either a full screen or a windowed mode |
| window, but full screen is only recommended if there is a monitor that supports |
| the resolution of the HMD. Due to limitations in LibOVR, the size of the client |
| area of the window must equal the resolution of the HMD. |
| |
| If the resolution of the HMD is much larger than the regular monitor, the window |
| may be resized by the window manager on creation. One way to avoid this is to |
| make it undecorated with the [GLFW_DECORATED](@ref window_hints_wnd) window |
| hint. |
| |
| |
| @subsection rift_direct_attach Attaching the window to the HMD |
| |
| Once you have created the window and context, you need to attach the native |
| handle of the GLFW window to the HMD. |
| |
| @code |
| ovrHmd_AttachToWindow(hmd, glfwGetWin32Window(window), NULL, NULL); |
| @endcode |
| |
| |
| @section rift_extend Extend Desktop mode |
| |
| Extend desktop mode is a legacy display mode, but is still (January 2015) the |
| only available mode on OS X and Linux, as well as on Windows machines that for |
| technical reasons do not yet support direct HMD mode. |
| |
| |
| @subsection rift_extend_detect Detecting a HMD with GLFW |
| |
| If the HMD is in extend desktop mode you can deduce which GLFW monitor it |
| corresponds to and create a full screen window on that monitor. |
| |
| On Windows, the native display device name of a GLFW monitor corresponds to the |
| display device name of the detected HMD as stored, in the `DisplayDeviceName` |
| member of `ovrHmdDesc`. |
| |
| On OS X, the native display ID of a GLFW monitor corresponds to the display ID |
| of the detected HMD, as stored in the `DisplayId` member of `ovrHmdDesc`. |
| |
| At the time of writing (January 2015), the Oculus SDK does not support detecting |
| which monitor corresponds to the HMD in any sane fashion, but as long as the HMD |
| is set up and rotated properly it can be found via the screen position and |
| resolution provided by LibOVR. This method may instead find another monitor |
| that is mirroring the HMD, but this only matters if you intend to change its |
| video mode. |
| |
| @code |
| int i, count; |
| GLFWmonitor** monitors = glfwGetMonitors(&count); |
| |
| for (i = 0; i < count; i++) |
| { |
| #if defined(_WIN32) |
| if (strcmp(glfwGetWin32Monitor(monitors[i]), hmd->DisplayDeviceName) == 0) |
| return monitors[i]; |
| #elif defined(__APPLE__) |
| if (glfwGetCocoaMonitor(monitors[i]) == hmd->DisplayId) |
| return monitors[i]; |
| #elif defined(__linux__) |
| int xpos, ypos; |
| const GLFWvidmode* mode = glfwGetVideoMode(monitors[i]); |
| glfwGetMonitorPos(monitors[i], &xpos, &ypos); |
| |
| if (hmd->WindowsPos.x == xpos && |
| hmd->WindowsPos.y == ypos && |
| hmd->Resolution.w == mode->width && |
| hmd->Resolution.h == mode->height) |
| { |
| return monitors[i]; |
| } |
| #endif |
| } |
| @endcode |
| |
| |
| @subsection rift_extend_create Creating a window and context |
| |
| The window is created as a regular full screen window on the found monitor. It |
| is usually a good idea to create a |
| [windowed full screen](@ref window_windowed_full_screen) window, as the HMD will |
| very likely already be set to the correct video mode. However, in extend |
| desktop mode it behaves like a regular monitor and any supported video mode can |
| be requested. |
| |
| If other monitors are mirroring the HMD and you request a different video mode, |
| all monitors in the mirroring set will get the new video mode. |
| |
| |
| @section rift_render Rendering to the HMD |
| |
| @subsection rift_render_sdk SDK distortion rendering |
| |
| If you wish to use SDK distortion rendering you will need some information from |
| GLFW to configure the renderer. Below are the parts of the `ovrGLConfig` union |
| that need to be filled with from GLFW. Note that there are other fields that |
| also need to be filled for `ovrHmd_ConfigureRendering` to succeed. |
| |
| Before configuring SDK distortion rendering you should make your context |
| current. |
| |
| @code |
| int width, height; |
| union ovrGLConfig config; |
| |
| glfwGetFramebufferSize(window, &width, &height); |
| |
| config.OGL.Header.BackBufferSize.w = width; |
| config.OGL.Header.BackBufferSize.h = height; |
| #if defined(_WIN32) |
| config.OGL.Window = glfwGetWin32Window(window); |
| #elif defined(__APPLE__) |
| #elif defined(__linux__) |
| config.OGL.Disp = glfwGetX11Display(); |
| #endif |
| @endcode |
| |
| When using SDK distortion rendering you should not swap the buffers yourself, as |
| the HMD is updated by `ovrHmd_EndFrame`. |
| |
| |
| @subsection rift_render_custom Client distortion rendering |
| |
| With client distortion rendering you are in full control of the contents of the |
| HMD and should render and swap the buffers normally. |
| |
| */ |