/**
   * Build an OpenGL window, respecting the Rift's current display mode choice of
   * extended or direct HMD.
   */
  GLFWwindow * createRiftRenderingWindow(ovrHmd hmd, glm::uvec2 & outSize, glm::ivec2 & outPosition) {
    bool extendedMode = true;

    outPosition = glm::ivec2(hmd->WindowsPos.x, hmd->WindowsPos.y);
    outSize = glm::uvec2(hmd->Resolution.w, hmd->Resolution.h);

    // The ovrHmdCap_ExtendDesktop is currently only reported reliably on Windows
    ON_WINDOWS([&] {
      extendedMode = (ovrHmdCap_ExtendDesktop & hmd->HmdCaps);
    });

    return extendedMode
      ? createExtendedModeWindow(outSize, outPosition)
      : createDirectHmdModeWindow(hmd, outSize);
  }
 void * getNativeWindowHandle(GLFWwindow * window)
 {
     void * nativeWindowHandle = nullptr;
     ON_WINDOWS([&]
     {
         nativeWindowHandle = (void*)glfwGetWin32Window(window);
     });
     ON_LINUX([&]
     {
         nativeWindowHandle = (void*)glfwGetX11Window(window);
     });
     ON_MAC([&]
     {
         nativeWindowHandle = (void*)glfwGetCocoaWindow(window);
     });
     return nativeWindowHandle;
 }
void RiftRenderingApp::initializeRiftRendering() {
    ovrGLConfig cfg;
    memset(&cfg, 0, sizeof(cfg));
    cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
    cfg.OGL.Header.BackBufferSize = ovr::fromGlm(hmdNativeResolution);
    cfg.OGL.Header.Multisample = 1;

    ON_WINDOWS([&]{
      cfg.OGL.Window = (HWND)getNativeWindow();
    });

    int distortionCaps = 0
      | ovrDistortionCap_Vignette
      | ovrDistortionCap_Overdrive
      | ovrDistortionCap_TimeWarp;

    ON_LINUX([&]{
      distortionCaps |= ovrDistortionCap_LinuxDevFullscreen;
    });

    ovrEyeRenderDesc eyeRenderDescs[2];
    int configResult = ovrHmd_ConfigureRendering(hmd, &cfg.Config,
      distortionCaps, hmd->MaxEyeFov, eyeRenderDescs);
    assert(configResult);

    for_each_eye([&](ovrEyeType eye){
      const ovrEyeRenderDesc & erd = eyeRenderDescs[eye];
      ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(erd.Fov, 0.01f, 100000.0f, true);
      projections[eye] = ovr::toGlm(ovrPerspectiveProjection);
      eyeOffsets[eye] = erd.HmdToEyeViewOffset;
    });

    // Allocate the frameBuffer that will hold the scene, and then be
    // re-rendered to the screen with distortion
    glm::uvec2 frameBufferSize = ovr::toGlm(eyeTextures[0].Header.TextureSize);
    for_each_eye([&](ovrEyeType eye) {
      eyeFramebuffers[eye] = FramebufferWrapperPtr(new FramebufferWrapper());
      eyeFramebuffers[eye]->init(frameBufferSize);
      ((ovrGLTexture&)(eyeTextures[eye])).OGL.TexId =
        oglplus::GetName(eyeFramebuffers[eye]->color);
    });
  }