Branimir Karadžić 9 years ago
parent
commit
ace7083efa
5 changed files with 309 additions and 306 deletions
  1. 6 5
      src/hmd_ovr.h
  2. 137 162
      src/renderer_d3d11.cpp
  3. 19 0
      src/renderer_d3d11.h
  4. 125 139
      src/renderer_gl.cpp
  5. 22 0
      src/renderer_gl.h

+ 6 - 5
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;

+ 137 - 162
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];

+ 19 - 0
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()

+ 125 - 139
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

+ 22 - 0
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);