void initGl() { GlfwApp::initGl(); ovrFovPort eyeFovPorts[2]; for_each_eye([&](ovrEyeType eye){ ovrTextureHeader & eyeTextureHeader = textures[eye].Header; eyeFovPorts[eye] = hmd->DefaultEyeFov[eye]; eyeTextureHeader.TextureSize = ovrHmd_GetFovTextureSize(hmd, eye, hmd->DefaultEyeFov[eye], 1.0f); eyeTextureHeader.RenderViewport.Size = eyeTextureHeader.TextureSize; eyeTextureHeader.RenderViewport.Pos.x = 0; eyeTextureHeader.RenderViewport.Pos.y = 0; eyeTextureHeader.API = ovrRenderAPI_OpenGL; eyeFramebuffers[eye] = FramebufferWrapperPtr(new FramebufferWrapper()); eyeFramebuffers[eye]->init(ovr::toGlm(eyeTextureHeader.TextureSize)); ((ovrGLTexture&)textures[eye]).OGL.TexId = oglplus::GetName(eyeFramebuffers[eye]->color); }); ovrGLConfig cfg; memset(&cfg, 0, sizeof(ovrGLConfig)); cfg.OGL.Header.API = ovrRenderAPI_OpenGL; cfg.OGL.Header.Multisample = 1; /** * In the Direct3D examples in the Oculus SDK, they make the point that the * onscreen window size does not need to match the Rift resolution. However * this doesn't currently work in OpenGL, so we have to create the window at * the full resolution of the Rift and ensure that we use the same * size here when setting the BackBufferSize. */ cfg.OGL.Header.BackBufferSize = ovr::fromGlm(getSize()); ON_LINUX([&]{ cfg.OGL.Disp = (Display*)glfw::getNativeDisplay(getWindow()); }); int distortionCaps = 0 | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette; ON_LINUX([&]{ distortionCaps |= ovrDistortionCap_LinuxDevFullscreen; }); ovrEyeRenderDesc eyeRenderDescs[2]; int configResult = ovrHmd_ConfigureRendering(hmd, &cfg.Config, distortionCaps, eyeFovPorts, eyeRenderDescs); if (!configResult) { FAIL("Unable to configure SDK based distortion rendering"); } for_each_eye([&](ovrEyeType eye){ eyeOffsets[eye] = eyeRenderDescs[eye].HmdToEyeViewOffset; eyeProjections[eye] = ovr::toGlm( ovrMatrix4f_Projection(eyeFovPorts[eye], 0.01f, 1000.0f, true)); }); }
/** * Build a Direct HMD mode window, binding the OVR SDK to the native window object. */ GLFWwindow * createDirectHmdModeWindow(ovrHmd hmd, glm::uvec2 & outSize) { // On linux it's recommended to leave the screen in its default portrait orientation. // The SDK currently allows no mechanism to test if this is the case. // So in direct mode, we need to swap the x and y value. ON_LINUX([&] { std::swap(outSize.x, outSize.y); }); // In direct HMD mode, we always use the native resolution, because the // user has no control over it. // In direct mode, try to put the output window on a secondary screen // (for easier debugging, assuming your dev environment is on the primary) GLFWwindow * window = glfw::createSecondaryScreenWindow(outSize); // Attach the OVR SDK to the native window void * nativeWindowHandle = glfw::getNativeWindowHandle(window); if (nullptr != nativeWindowHandle) { ovrHmd_AttachToWindow(hmd, nativeWindowHandle, nullptr, nullptr); } // A bug in some versions of the SDK (0.4.x) prevents Direct Mode from // engaging properly unless you call the GetEyePoses function. { static ovrVector3f offsets[2]; static ovrPosef poses[2]; ovrHmd_GetEyePoses(hmd, 0, offsets, poses, nullptr); } return window; }
void * getNativeDisplay(GLFWwindow * window) { void * nativeDisplay = nullptr; ON_LINUX([&] { nativeDisplay = (void*)glfwGetX11Display(); }); return nativeDisplay; }
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); }); }