From ace7083efa62246ff46e3a54dc171e9f44874fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Mon, 4 Apr 2016 22:57:54 -0700 Subject: [PATCH] Cleanup. --- src/hmd_ovr.h | 11 +- src/renderer_d3d11.cpp | 299 +++++++++++++++++++---------------------- src/renderer_d3d11.h | 19 +++ src/renderer_gl.cpp | 264 +++++++++++++++++------------------- src/renderer_gl.h | 22 +++ 5 files changed, 309 insertions(+), 306 deletions(-) diff --git a/src/hmd_ovr.h b/src/hmd_ovr.h index 525dcac90..090b68f36 100644 --- a/src/hmd_ovr.h +++ b/src/hmd_ovr.h @@ -31,8 +31,9 @@ namespace bgfx struct OVRBufferI { virtual ~OVRBufferI() {}; - virtual void onRender(const ovrSession &session) = 0; - virtual void destroy(const ovrSession &session) = 0; + virtual void init(const ovrSession& _session, int _eyeIdx) = 0; + virtual void onRender(const ovrSession& _session) = 0; + virtual void destroy(const ovrSession& _session) = 0; ovrSizei m_eyeTextureSize; ovrTextureSwapChain m_swapTextureChain; @@ -42,9 +43,9 @@ namespace bgfx struct OVRMirrorI { virtual ~OVRMirrorI() {}; - virtual void init(const ovrSession &session, int windowWidth, int windowHeight) = 0; - virtual void destroy(const ovrSession &session) = 0; - virtual void blit(const ovrSession &session) = 0; + virtual void init(const ovrSession& _session, int windowWidth, int windowHeight) = 0; + virtual void destroy(const ovrSession& _session) = 0; + virtual void blit(const ovrSession& _session) = 0; ovrMirrorTexture m_mirrorTexture; ovrMirrorTextureDesc m_mirrorDesc; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index d6fa7210f..c1f8f9664 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -601,166 +601,6 @@ namespace bgfx { namespace d3d11 static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1; #endif // USE_D3D11_DYNAMIC_LIB -#if BGFX_CONFIG_USE_OVR - // Oculus Rift eye buffer - struct OVRBufferD3D11 : public OVRBufferI - { - OVRBufferD3D11(const ovrSession& _session, int eyeIdx, ID3D11Device* _device, ID3D11DeviceContext* _deviceCtx) - { - m_device = _device; - m_deviceCtx = _deviceCtx; - ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session); - m_eyeTextureSize = ovr_GetFovTextureSize(_session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f); - - ovrTextureSwapChainDesc desc = {}; - desc.Type = ovrTexture_2D; - desc.ArraySize = 1; - desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; - desc.Width = m_eyeTextureSize.w; - desc.Height = m_eyeTextureSize.h; - desc.MipLevels = 1; - desc.SampleCount = 1; - desc.MiscFlags = ovrTextureMisc_DX_Typeless; - desc.BindFlags = ovrTextureBind_DX_RenderTarget; - desc.StaticImage = ovrFalse; - - ovrResult result = ovr_CreateTextureSwapChainDX(_session, _device, &desc, &m_swapTextureChain); - - if (!OVR_SUCCESS(result) ) - { - BX_CHECK(false, "Could not create D3D11 OVR swap texture"); - } - - memset(m_eyeRtv, 0, sizeof(m_eyeRtv) ); - int textureCount = 0; - ovr_GetTextureSwapChainLength(_session, m_swapTextureChain, &textureCount); - - for (int ii = 0; ii < textureCount; ++ii) - { - ID3D11Texture2D* tex = NULL; - ovr_GetTextureSwapChainBufferDX(_session, m_swapTextureChain, ii, IID_PPV_ARGS(&tex) ); - D3D11_RENDER_TARGET_VIEW_DESC rtvd = {}; - rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - - ID3D11RenderTargetView* rtv; - DX_CHECK(_device->CreateRenderTargetView(tex, &rtvd, &rtv) ); - m_eyeRtv[ii] = rtv; - DX_RELEASE(tex, 1); - } - - // setup depth buffer - D3D11_TEXTURE2D_DESC dbDesc; - dbDesc.Width = m_eyeTextureSize.w; - dbDesc.Height = m_eyeTextureSize.h; - dbDesc.MipLevels = 1; - dbDesc.ArraySize = 1; - dbDesc.Format = DXGI_FORMAT_D32_FLOAT; - dbDesc.SampleDesc.Count = 1; - dbDesc.SampleDesc.Quality = 0; - dbDesc.Usage = D3D11_USAGE_DEFAULT; - dbDesc.CPUAccessFlags = 0; - dbDesc.MiscFlags = 0; - dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - ID3D11Texture2D* tex; - DX_CHECK(_device->CreateTexture2D(&dbDesc, NULL, &tex) ); - DX_CHECK(_device->CreateDepthStencilView(tex, NULL, &m_depthBuffer) ); - DX_RELEASE(tex, 0); - } - - void onRender(const ovrSession& _session) - { - // Clear and set up rendertarget - int texIndex = 0; - ovr_GetTextureSwapChainCurrentIndex(_session, m_swapTextureChain, &texIndex); - - float black[] = { 0.f, 0.f, 0.f, 0.f }; // Important that alpha=0, if want pixels to be transparent, for manual layers - m_deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer); - m_deviceCtx->ClearRenderTargetView(m_eyeRtv[texIndex], black); - m_deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); - - D3D11_VIEWPORT D3Dvp; - D3Dvp.TopLeftX = 0; - D3Dvp.TopLeftY = 0; - D3Dvp.Width = (FLOAT)m_eyeTextureSize.w; - D3Dvp.Height = (FLOAT)m_eyeTextureSize.h; - D3Dvp.MinDepth = 0; - D3Dvp.MaxDepth = 1; - m_deviceCtx->RSSetViewports(1, &D3Dvp); - } - - void destroy(const ovrSession& _session) - { - for (uint32_t ii = 0; ii < BX_COUNTOF(m_eyeRtv); ++ii) - { - DX_RELEASE(m_eyeRtv[ii], 0); - } - - ovr_DestroyTextureSwapChain(_session, m_swapTextureChain); - m_depthBuffer->Release(); - } - - ID3D11Device* m_device; - ID3D11DeviceContext* m_deviceCtx; - ID3D11RenderTargetView* m_eyeRtv[4]; - ID3D11DepthStencilView* m_depthBuffer; - }; - - // Oculus Rift mirror - struct OVRMirrorD3D11 : public OVRMirrorI - { - OVRMirrorD3D11(ID3D11Device* _device, ID3D11DeviceContext* _deviceCtx, IDXGISwapChain* _swapChain) - : m_device(_device) - , m_deviceCtx(_deviceCtx) - , m_swapChain(_swapChain) - { - } - - void init(const ovrSession& _session, int _width, int _height) - { - m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; - m_mirrorDesc.Width = _width; - m_mirrorDesc.Height = _height; - ovrResult result = ovr_CreateMirrorTextureDX(_session, m_device, &m_mirrorDesc, &m_mirrorTexture); - - if (!OVR_SUCCESS(result) ) - { - BX_CHECK(false, "Could not create D3D11 OVR mirror texture"); - } - } - - void destroy(const ovrSession& session) - { - if (NULL != m_mirrorTexture) - { - ovr_DestroyMirrorTexture(session, m_mirrorTexture); - m_mirrorTexture = NULL; - } - } - - void blit(const ovrSession& session) - { - if (NULL != m_mirrorTexture) - { - ID3D11Texture2D* tex = NULL; - ovr_GetMirrorTextureBufferDX(session, m_mirrorTexture, IID_PPV_ARGS(&tex) ); - ID3D11Texture2D* backBuffer; - DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); - - m_deviceCtx->CopyResource(backBuffer, tex); - DX_CHECK(m_swapChain->Present(0, 0) ); - - DX_RELEASE(tex, 1); - DX_RELEASE(backBuffer, 0); - } - } - - ID3D11Device* m_device; - ID3D11DeviceContext* m_deviceCtx; - IDXGISwapChain* m_swapChain; - }; -#endif // BGFX_CONFIG_USE_OVR - struct RendererContextD3D11 : public RendererContextI { RendererContextD3D11() @@ -3246,12 +3086,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); // eye buffers need to be initialized only once during application lifetime if (!m_ovr.m_eyeBuffers[eyeIdx]) { - m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferD3D11(m_ovr.m_hmd, eyeIdx, m_device, m_deviceCtx) ); + m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferD3D11); + m_ovr.m_eyeBuffers[eyeIdx]->init(m_ovr.m_hmd, eyeIdx); } } // recreate mirror texture - m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorD3D11(m_device, m_deviceCtx, m_swapChain) ); + m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorD3D11); m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height); } } @@ -3705,6 +3546,140 @@ BX_PRAGMA_DIAGNOSTIC_POP(); agsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride); } +#if BGFX_CONFIG_USE_OVR + void OVRBufferD3D11::init(const ovrSession& _session, int _eyeIdx) + { + ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session); + m_eyeTextureSize = ovr_GetFovTextureSize(_session, (ovrEyeType)_eyeIdx, hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f); + + ovrTextureSwapChainDesc desc = {}; + desc.Type = ovrTexture_2D; + desc.ArraySize = 1; + desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + desc.Width = m_eyeTextureSize.w; + desc.Height = m_eyeTextureSize.h; + desc.MipLevels = 1; + desc.SampleCount = 1; + desc.MiscFlags = ovrTextureMisc_DX_Typeless; + desc.BindFlags = ovrTextureBind_DX_RenderTarget; + desc.StaticImage = ovrFalse; + + ovrResult result = ovr_CreateTextureSwapChainDX(_session, s_renderD3D11->m_device, &desc, &m_swapTextureChain); + + if (!OVR_SUCCESS(result) ) + { + BX_CHECK(false, "Could not create D3D11 OVR swap texture"); + } + + memset(m_eyeRtv, 0, sizeof(m_eyeRtv) ); + int textureCount = 0; + ovr_GetTextureSwapChainLength(_session, m_swapTextureChain, &textureCount); + + for (int ii = 0; ii < textureCount; ++ii) + { + ID3D11Texture2D* tex = NULL; + ovr_GetTextureSwapChainBufferDX(_session, m_swapTextureChain, ii, IID_PPV_ARGS(&tex) ); + D3D11_RENDER_TARGET_VIEW_DESC rtvd = {}; + rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + + ID3D11RenderTargetView* rtv; + DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(tex, &rtvd, &rtv) ); + m_eyeRtv[ii] = rtv; + DX_RELEASE(tex, 1); + } + + // setup depth buffer + D3D11_TEXTURE2D_DESC dbDesc; + dbDesc.Width = m_eyeTextureSize.w; + dbDesc.Height = m_eyeTextureSize.h; + dbDesc.MipLevels = 1; + dbDesc.ArraySize = 1; + dbDesc.Format = DXGI_FORMAT_D32_FLOAT; + dbDesc.SampleDesc.Count = 1; + dbDesc.SampleDesc.Quality = 0; + dbDesc.Usage = D3D11_USAGE_DEFAULT; + dbDesc.CPUAccessFlags = 0; + dbDesc.MiscFlags = 0; + dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + ID3D11Texture2D* tex; + DX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&dbDesc, NULL, &tex) ); + DX_CHECK(s_renderD3D11->m_device->CreateDepthStencilView(tex, NULL, &m_depthBuffer) ); + DX_RELEASE(tex, 0); + } + + void OVRBufferD3D11::onRender(const ovrSession& _session) + { + // Clear and set up rendertarget + int texIndex = 0; + ovr_GetTextureSwapChainCurrentIndex(_session, m_swapTextureChain, &texIndex); + + float black[] = { 0.f, 0.f, 0.f, 0.f }; // Important that alpha=0, if want pixels to be transparent, for manual layers + s_renderD3D11->m_deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer); + s_renderD3D11->m_deviceCtx->ClearRenderTargetView(m_eyeRtv[texIndex], black); + s_renderD3D11->m_deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); + + D3D11_VIEWPORT D3Dvp; + D3Dvp.TopLeftX = 0; + D3Dvp.TopLeftY = 0; + D3Dvp.Width = (FLOAT)m_eyeTextureSize.w; + D3Dvp.Height = (FLOAT)m_eyeTextureSize.h; + D3Dvp.MinDepth = 0; + D3Dvp.MaxDepth = 1; + s_renderD3D11->m_deviceCtx->RSSetViewports(1, &D3Dvp); + } + + void OVRBufferD3D11::destroy(const ovrSession& _session) + { + for (uint32_t ii = 0; ii < BX_COUNTOF(m_eyeRtv); ++ii) + { + DX_RELEASE(m_eyeRtv[ii], 0); + } + + ovr_DestroyTextureSwapChain(_session, m_swapTextureChain); + m_depthBuffer->Release(); + } + + void OVRMirrorD3D11::init(const ovrSession& _session, int _width, int _height) + { + m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + m_mirrorDesc.Width = _width; + m_mirrorDesc.Height = _height; + ovrResult result = ovr_CreateMirrorTextureDX(_session, s_renderD3D11->m_device, &m_mirrorDesc, &m_mirrorTexture); + + if (!OVR_SUCCESS(result) ) + { + BX_CHECK(false, "Could not create D3D11 OVR mirror texture"); + } + } + + void OVRMirrorD3D11::destroy(const ovrSession& session) + { + if (NULL != m_mirrorTexture) + { + ovr_DestroyMirrorTexture(session, m_mirrorTexture); + m_mirrorTexture = NULL; + } + } + + void OVRMirrorD3D11::blit(const ovrSession& _session) + { + if (NULL != m_mirrorTexture) + { + ID3D11Texture2D* tex = NULL; + ovr_GetMirrorTextureBufferDX(_session, m_mirrorTexture, IID_PPV_ARGS(&tex) ); + ID3D11Texture2D* backBuffer; + DX_CHECK(s_renderD3D11->m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); + + s_renderD3D11->m_deviceCtx->CopyResource(backBuffer, tex); + DX_CHECK(s_renderD3D11->m_swapChain->Present(0, 0) ); + + DX_RELEASE(tex, 1); + DX_RELEASE(backBuffer, 0); + } + } +#endif // BGFX_CONFIG_USE_OVR + struct UavFormat { DXGI_FORMAT format[3]; diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index c1b4917ff..753c8f80b 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -59,6 +59,25 @@ BX_PRAGMA_DIAGNOSTIC_POP() namespace bgfx { namespace d3d11 { +#if BGFX_CONFIG_USE_OVR + struct OVRBufferD3D11 : public OVRBufferI + { + virtual void init(const ovrSession& _session, int _eyeIdx) BX_OVERRIDE; + virtual void destroy(const ovrSession& _session) BX_OVERRIDE; + virtual void onRender(const ovrSession& _session) BX_OVERRIDE; + + ID3D11RenderTargetView* m_eyeRtv[4]; + ID3D11DepthStencilView* m_depthBuffer; + }; + + struct OVRMirrorD3D11 : public OVRMirrorI + { + virtual void init(const ovrSession& _session, int _width, int _height) BX_OVERRIDE; + virtual void destroy(const ovrSession& session) BX_OVERRIDE; + virtual void blit(const ovrSession& session) BX_OVERRIDE; + }; +#endif // BGFX_CONFIG_USE_OVR + struct BufferD3D11 { BufferD3D11() diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index edeabab46..9d87e06a3 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1274,144 +1274,6 @@ namespace bgfx { namespace gl BX_UNUSED(supported); } -#if BGFX_CONFIG_USE_OVR - - // Oculus Rift eye buffer - struct OVRBufferGL : public OVRBufferI - { - OVRBufferGL(const ovrSession& session, int eyeIdx) - { - ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); - m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f); - - ovrTextureSwapChainDesc desc = {}; - desc.Type = ovrTexture_2D; - desc.ArraySize = 1; - desc.Width = m_eyeTextureSize.w; - desc.Height = m_eyeTextureSize.h; - desc.MipLevels = 1; - desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; - desc.SampleCount = 1; - desc.StaticImage = ovrFalse; - - ovr_CreateTextureSwapChainGL(session, &desc, &m_swapTextureChain); - - int textureCount = 0; - ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount); - - for (int j = 0; j < textureCount; ++j) - { - GLuint chainTexId; - ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, j, &chainTexId); - GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId)); - - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - } - - GL_CHECK(glGenFramebuffers(1, &m_eyeFbo)); - - // create depth buffer - GL_CHECK(glGenTextures(1, &m_depthBuffer)); - GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - - GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); - } - - void onRender(const ovrSession& session) - { - // set the current eye texture in swap chain - int curIndex; - ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &curIndex); - ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, curIndex, &m_eyeTexId); - - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo)); - GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0)); - GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0)); - - GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h)); - GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - } - - void destroy(const ovrSession& session) - { - GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo)); - GL_CHECK(glDeleteTextures(1, &m_depthBuffer)); - - ovr_DestroyTextureSwapChain(session, m_swapTextureChain); - } - - GLuint m_eyeFbo; - GLuint m_eyeTexId; - GLuint m_depthBuffer; - }; - - // Oculus Rift mirror - struct OVRMirrorGL : public OVRMirrorI - { - void init(const ovrSession& session, int windowWidth, int windowHeight) - { - memset(&m_mirrorDesc, 0, sizeof(m_mirrorDesc)); - m_mirrorDesc.Width = windowWidth; - m_mirrorDesc.Height = windowHeight; - m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; - - ovr_CreateMirrorTextureGL(session, &m_mirrorDesc, &m_mirrorTexture); - - // Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes - if (!m_mirrorTexture) - return; - - // Configure the mirror read buffer - GLuint texId; - ovr_GetMirrorTextureBufferGL(session, m_mirrorTexture, &texId); - GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO)); - GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO)); - GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0)); - GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0)); - GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0)); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { - GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO)); - BX_CHECK(false, "Could not initialize VR buffers!"); - } - } - - void destroy(const ovrSession& session) - { - if (!m_mirrorTexture) - return; - - GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO)); - ovr_DestroyMirrorTexture(session, m_mirrorTexture); - m_mirrorTexture = NULL; - } - - void blit(const ovrSession& /*session*/) - { - if (!m_mirrorTexture) - return; - - // Blit mirror texture to back buffer - GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO)); - GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); - GLint w = m_mirrorDesc.Width; - GLint h = m_mirrorDesc.Height; - GL_CHECK(glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST)); - GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0)); - } - - GLuint m_mirrorFBO; - }; -#endif // BGFX_CONFIG_USE_OVR - struct RendererContextGL : public RendererContextI { RendererContextGL() @@ -2998,7 +2860,8 @@ namespace bgfx { namespace gl // eye buffers need to be initialized only once during application lifetime if (!m_ovr.m_eyeBuffers[eyeIdx]) { - m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferGL(m_ovr.m_hmd, eyeIdx)); + m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferGL); + m_ovr.m_eyeBuffers[eyeIdx]->init(m_ovr.m_hmd, eyeIdx); } } @@ -3455,6 +3318,129 @@ namespace bgfx { namespace gl s_renderGL = NULL; } +#if BGFX_CONFIG_USE_OVR + void OVRBufferGL::init(const ovrSession& session, int eyeIdx) + { + ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); + m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f); + + ovrTextureSwapChainDesc desc = {}; + desc.Type = ovrTexture_2D; + desc.ArraySize = 1; + desc.Width = m_eyeTextureSize.w; + desc.Height = m_eyeTextureSize.h; + desc.MipLevels = 1; + desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + desc.SampleCount = 1; + desc.StaticImage = ovrFalse; + + ovr_CreateTextureSwapChainGL(session, &desc, &m_swapTextureChain); + + int textureCount = 0; + ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount); + + for (int j = 0; j < textureCount; ++j) + { + GLuint chainTexId; + ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, j, &chainTexId); + GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId)); + + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + } + + GL_CHECK(glGenFramebuffers(1, &m_eyeFbo)); + + // create depth buffer + GL_CHECK(glGenTextures(1, &m_depthBuffer)); + GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + + GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); + } + + void OVRBufferGL::onRender(const ovrSession& session) + { + // set the current eye texture in swap chain + int curIndex; + ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &curIndex); + ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, curIndex, &m_eyeTexId); + + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo)); + GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0)); + GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0)); + + GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h)); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + } + + void OVRBufferGL::destroy(const ovrSession& session) + { + GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo)); + GL_CHECK(glDeleteTextures(1, &m_depthBuffer)); + + ovr_DestroyTextureSwapChain(session, m_swapTextureChain); + } + + void OVRMirrorGL::init(const ovrSession& session, int windowWidth, int windowHeight) + { + memset(&m_mirrorDesc, 0, sizeof(m_mirrorDesc)); + m_mirrorDesc.Width = windowWidth; + m_mirrorDesc.Height = windowHeight; + m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + + ovr_CreateMirrorTextureGL(session, &m_mirrorDesc, &m_mirrorTexture); + + // Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes + if (!m_mirrorTexture) + return; + + // Configure the mirror read buffer + GLuint texId; + ovr_GetMirrorTextureBufferGL(session, m_mirrorTexture, &texId); + GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO)); + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO)); + GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0)); + GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0)); + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0)); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO)); + BX_CHECK(false, "Could not initialize VR buffers!"); + } + } + + void OVRMirrorGL::destroy(const ovrSession& session) + { + if (!m_mirrorTexture) + return; + + GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO)); + ovr_DestroyMirrorTexture(session, m_mirrorTexture); + m_mirrorTexture = NULL; + } + + void OVRMirrorGL::blit(const ovrSession& /*session*/) + { + if (!m_mirrorTexture) + return; + + // Blit mirror texture to back buffer + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO)); + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); + GLint w = m_mirrorDesc.Width; + GLint h = m_mirrorDesc.Height; + GL_CHECK(glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST)); + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0)); + } +#endif // BGFX_CONFIG_USE_OVR + const char* glslTypeName(GLuint _type) { #define GLSL_TYPE(_ty) case _ty: return #_ty diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 3bed1f17c..6fbbe1619 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -901,6 +901,28 @@ namespace bgfx namespace bgfx { namespace gl { +#if BGFX_CONFIG_USE_OVR + struct OVRBufferGL : public OVRBufferI + { + virtual void init(const ovrSession& _session, int _eyeIdx) BX_OVERRIDE; + virtual void destroy(const ovrSession& _session) BX_OVERRIDE; + virtual void onRender(const ovrSession& _session) BX_OVERRIDE; + + GLuint m_eyeFbo; + GLuint m_eyeTexId; + GLuint m_depthBuffer; + }; + + struct OVRMirrorGL : public OVRMirrorI + { + virtual void init(const ovrSession& _session, int _width, int _height) BX_OVERRIDE; + virtual void destroy(const ovrSession& _session) BX_OVERRIDE; + virtual void blit(const ovrSession& _session) BX_OVERRIDE; + + GLuint m_mirrorFBO; + }; +#endif // BGFX_CONFIG_USE_OVR + void dumpExtensions(const char* _extensions); const char* glEnumName(GLenum _enum);