void VR_Disable() { int i; if( !vr_initialized ) return; for( i = 0; i < 2; i++ ) { DeleteFBO(eyes[i].fbo); } ovrHmd_DestroyMirrorTexture(hmd, (ovrTexture*)mirror_texture); ovrHmd_Destroy(hmd); ovr_Shutdown(); vr_initialized = false; }
void FOculusRiftHMD::D3D11Bridge::Reset_RenderThread() { if (MirrorTexture) { ovrHmd_DestroyMirrorTexture(Hmd, MirrorTexture); MirrorTextureRHI = nullptr; MirrorTexture = nullptr; } if (ColorTextureSet) { ColorTextureSet->ReleaseResources(Hmd); ColorTextureSet = nullptr; } Hmd = nullptr; if (RenderContext.IsValid()) { RenderContext->bFrameBegun = false; SetRenderContext(nullptr); } }
void FOculusRiftHMD::D3D11Bridge::BeginRendering(FHMDViewExtension& InRenderContext, const FTexture2DRHIRef& RT) { check(IsInRenderingThread()); SetRenderContext(&InRenderContext); FGameFrame* CurrentFrame = GetRenderFrame(); check(CurrentFrame); FSettings* FrameSettings = CurrentFrame->GetSettings(); check(FrameSettings); const uint32 RTSizeX = RT->GetSizeX(); const uint32 RTSizeY = RT->GetSizeY(); const FVector2D ActualMirrorWindowSize = CurrentFrame->WindowSize; // detect if mirror texture needs to be re-allocated or freed if (Hmd && MirrorTextureRHI && (bNeedReAllocateMirrorTexture || Hmd != RenderContext->Hmd || (FrameSettings->Flags.bMirrorToWindow && ( FrameSettings->MirrorWindowMode != FSettings::eMirrorWindow_Distorted || ActualMirrorWindowSize != FVector2D(MirrorTextureRHI->GetSizeX(), MirrorTextureRHI->GetSizeY()))) || !FrameSettings->Flags.bMirrorToWindow )) { check(MirrorTexture); ovrHmd_DestroyMirrorTexture(Hmd, MirrorTexture); MirrorTexture = nullptr; MirrorTextureRHI = nullptr; bNeedReAllocateMirrorTexture = false; } // need to allocate a mirror texture? if (FrameSettings->Flags.bMirrorToWindow && FrameSettings->MirrorWindowMode == FSettings::eMirrorWindow_Distorted && !MirrorTextureRHI && ActualMirrorWindowSize.X != 0 && ActualMirrorWindowSize.Y != 0) { D3D11_TEXTURE2D_DESC dsDesc; dsDesc.Width = ActualMirrorWindowSize.X; dsDesc.Height = ActualMirrorWindowSize.Y; dsDesc.MipLevels = 1; dsDesc.ArraySize = 1; dsDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; dsDesc.SampleDesc.Count = 1; dsDesc.SampleDesc.Quality = 0; dsDesc.Usage = D3D11_USAGE_DEFAULT; dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; dsDesc.CPUAccessFlags = 0; dsDesc.MiscFlags = 0; ID3D11Device* D3DDevice = (ID3D11Device*)RHIGetNativeDevice(); ovrHmd_CreateMirrorTextureD3D11(Hmd, D3DDevice, &dsDesc, &MirrorTexture); if (!MirrorTexture) { UE_LOG(LogHMD, Error, TEXT("Can't create a mirror texture")); return; } UE_LOG(LogHMD, Log, TEXT("Allocated a new mirror texture (size %d x %d)"), ActualMirrorWindowSize.X, ActualMirrorWindowSize.Y); ovrD3D11Texture D3DMirrorTexture; D3DMirrorTexture.Texture = *MirrorTexture; MirrorTextureRHI = D3D11CreateTexture2DAlias( static_cast<FD3D11DynamicRHI*>(GDynamicRHI), D3DMirrorTexture.D3D11.pTexture, D3DMirrorTexture.D3D11.pSRView, dsDesc.Width, dsDesc.Height, 0, dsDesc.MipLevels, /*ActualMSAACount=*/ 1, (EPixelFormat)PF_B8G8R8A8, TexCreate_RenderTargetable); bNeedReAllocateMirrorTexture = false; } }
///@brief Called once a GL context has been set up. void OVRSDK06AppSkeleton::initVR(bool swapBackBufferDims) { if (m_Hmd == NULL) return; for (int i = 0; i < 2; ++i) { if (m_pTexSet[i]) { ovrHmd_DestroySwapTextureSet(m_Hmd, m_pTexSet[i]); m_pTexSet[i] = nullptr; } } // Set up eye fields of view ovrLayerEyeFov& layer = m_layerEyeFov; layer.Header.Type = ovrLayerType_EyeFov; layer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; // Create eye render target textures and FBOs for (ovrEyeType eye = ovrEyeType::ovrEye_Left; eye < ovrEyeType::ovrEye_Count; eye = static_cast<ovrEyeType>(eye + 1)) { const ovrFovPort& fov = layer.Fov[eye] = m_Hmd->MaxEyeFov[eye]; const ovrSizei& size = layer.Viewport[eye].Size = ovrHmd_GetFovTextureSize(m_Hmd, eye, fov, 1.f); layer.Viewport[eye].Pos = { 0, 0 }; LOG_INFO("Eye %d tex : %dx%d @ (%d,%d)", eye, size.w, size.h, layer.Viewport[eye].Pos.x, layer.Viewport[eye].Pos.y); ovrEyeRenderDesc & erd = m_eyeRenderDescs[eye]; erd = ovrHmd_GetRenderDesc(m_Hmd, eye, m_Hmd->MaxEyeFov[eye]); ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(erd.Fov, .1f, 10000.f, ovrProjection_RightHanded); m_eyeProjections[eye] = glm::transpose(glm::make_mat4(&ovrPerspectiveProjection.M[0][0])); m_eyeOffsets[eye] = erd.HmdToEyeViewOffset; // Allocate the frameBuffer that will hold the scene, and then be // re-rendered to the screen with distortion if (!OVR_SUCCESS(ovrHmd_CreateSwapTextureSetGL(m_Hmd, GL_RGBA, size.w, size.h, &m_pTexSet[eye]))) { LOG_ERROR("Unable to create swap textures"); return; } ovrSwapTextureSet& swapSet = *m_pTexSet[eye]; for (int i = 0; i < swapSet.TextureCount; ++i) { const ovrGLTexture& ovrTex = (ovrGLTexture&)swapSet.Textures[i]; glBindTexture(GL_TEXTURE_2D, ovrTex.OGL.TexId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } // Manually assemble swap FBO m_swapFBO.w = size.w; m_swapFBO.h = size.h; glGenFramebuffers(1, &m_swapFBO.id); glBindFramebuffer(GL_FRAMEBUFFER, m_swapFBO.id); const int idx = 0; const ovrGLTextureData* pGLData = reinterpret_cast<ovrGLTextureData*>(&swapSet.Textures[idx]); m_swapFBO.tex = pGLData->TexId; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_swapFBO.tex, 0); m_swapFBO.depth = 0; glGenRenderbuffers(1, &m_swapFBO.depth); glBindRenderbuffer(GL_RENDERBUFFER, m_swapFBO.depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.w, size.h); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_swapFBO.depth); // Check status { const GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOG_ERROR("Framebuffer status incomplete: %d %x", status, status); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); layer.ColorTexture[eye] = m_pTexSet[eye]; } // Mirror texture for displaying to desktop window if (m_pMirrorTex) { ovrHmd_DestroyMirrorTexture(m_Hmd, m_pMirrorTex); } const ovrEyeType eye = ovrEyeType::ovrEye_Left; const ovrFovPort& fov = layer.Fov[eye] = m_Hmd->MaxEyeFov[eye]; const ovrSizei& size = layer.Viewport[eye].Size = ovrHmd_GetFovTextureSize(m_Hmd, eye, fov, 1.f); ovrResult result = ovrHmd_CreateMirrorTextureGL(m_Hmd, GL_RGBA, size.w, size.h, &m_pMirrorTex); if (!OVR_SUCCESS(result)) { LOG_ERROR("Unable to create mirror texture"); return; } // Manually assemble mirror FBO m_mirrorFBO.w = size.w; m_mirrorFBO.h = size.h; glGenFramebuffers(1, &m_mirrorFBO.id); glBindFramebuffer(GL_FRAMEBUFFER, m_mirrorFBO.id); const ovrGLTextureData* pMirrorGLData = reinterpret_cast<ovrGLTextureData*>(m_pMirrorTex); m_mirrorFBO.tex = pMirrorGLData->TexId; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_mirrorFBO.tex, 0); // Check status { const GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOG_ERROR("Framebuffer status incomplete: %d %x", status, status); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_DEPTH_TEST); }