Merge pull request #743 from kondrak/master

OculusVR: updated to SDK 1.3
This commit is contained in:
Branimir Karadžić
2016-04-02 17:36:01 -07:00
15 changed files with 535 additions and 486 deletions

View File

@@ -1274,6 +1274,144 @@ 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()
@@ -1304,7 +1442,6 @@ namespace bgfx { namespace gl
, m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
, m_backBufferFbo(0)
, m_msaaBackBufferFbo(0)
, m_ovrFbo(0)
{
memset(m_msaaBackBufferRbos, 0, sizeof(m_msaaBackBufferRbos) );
}
@@ -2107,10 +2244,9 @@ namespace bgfx { namespace gl
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
}
if (!m_ovr.swap(_hmd) )
{
m_glctx.swap();
}
m_ovr.swap(_hmd, true);
// need to swap GL render context even if OVR is enabled to get the mirror texture in the output
m_glctx.swap();
}
}
@@ -2397,10 +2533,6 @@ namespace bgfx { namespace gl
uint32_t width = m_resolution.m_width;
uint32_t height = m_resolution.m_height;
if (m_ovr.isEnabled() )
{
m_ovr.getSize(width, height);
}
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_backBufferFbo) );
GL_CHECK(glViewport(0, 0, width, height) );
@@ -2857,63 +2989,22 @@ namespace bgfx { namespace gl
void ovrPostReset()
{
#if BGFX_CONFIG_USE_OVR
if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
if (m_resolution.m_flags & (BGFX_RESET_HMD | BGFX_RESET_HMD_DEBUG))
{
ovrGLConfig config;
config.OGL.Header.API = ovrRenderAPI_OpenGL;
# if OVR_VERSION > OVR_VERSION_043
config.OGL.Header.BackBufferSize.w = m_resolution.m_width;
config.OGL.Header.BackBufferSize.h = m_resolution.m_height;
# else
config.OGL.Header.RTSize.w = m_resolution.m_width;
config.OGL.Header.RTSize.h = m_resolution.m_height;
# endif // OVR_VERSION > OVR_VERSION_043
config.OGL.Header.Multisample = 0;
config.OGL.Window = (HWND)g_platformData.nwh;
config.OGL.DC = GetDC(config.OGL.Window);
if (m_ovr.postReset(g_platformData.nwh, &config.Config, !!(m_resolution.m_flags & BGFX_RESET_HMD_DEBUG) ) )
if (m_ovr.postReset())
{
uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
const Memory* mem = alloc(size);
for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
{
// 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));
}
}
bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
bx::write(&writer, magic);
TextureCreate tc;
tc.m_flags = BGFX_TEXTURE_RT|( ((m_resolution.m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT);;
tc.m_width = m_ovr.m_rtSize.w;
tc.m_height = m_ovr.m_rtSize.h;
tc.m_sides = 0;
tc.m_depth = 0;
tc.m_numMips = 1;
tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
tc.m_cubeMap = false;
tc.m_mem = NULL;
bx::write(&writer, tc);
m_ovrRT.create(mem, tc.m_flags, 0);
release(mem);
m_ovrFbo = m_msaaBackBufferFbo;
GL_CHECK(glGenFramebuffers(1, &m_msaaBackBufferFbo) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, m_ovrRT.m_id
, 0
) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_ovrFbo) );
ovrGLTexture texture;
texture.OGL.Header.API = ovrRenderAPI_OpenGL;
texture.OGL.Header.TextureSize = m_ovr.m_rtSize;
texture.OGL.TexId = m_ovrRT.m_id;
m_ovr.postReset(texture.Texture);
// recreate mirror texture
m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorGL);
m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@@ -2923,14 +3014,6 @@ namespace bgfx { namespace gl
{
#if BGFX_CONFIG_USE_OVR
m_ovr.preReset();
if (m_ovr.isEnabled() )
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
GL_CHECK(glDeleteFramebuffers(1, &m_msaaBackBufferFbo) );
m_msaaBackBufferFbo = m_ovrFbo;
m_ovrFbo = 0;
m_ovrRT.destroy();
}
#endif // BGFX_CONFIG_USE_OVR
}
@@ -3354,8 +3437,6 @@ namespace bgfx { namespace gl
const char* m_glslVersion;
OVR m_ovr;
TextureGL m_ovrRT;
GLint m_ovrFbo;
};
RendererContextGL* s_renderGL;
@@ -3647,7 +3728,7 @@ namespace bgfx { namespace gl
}
m_numPredefined = 0;
m_numSamplers = 0;
m_numSamplers = 0;
BX_TRACE("Uniforms (%d):", activeUniforms);
for (int32_t ii = 0; ii < activeUniforms; ++ii)
@@ -5439,7 +5520,7 @@ namespace bgfx { namespace gl
_render->m_hmdInitialized = m_ovr.isInitialized();
const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
const bool hmdEnabled = m_ovr.isEnabled();
ViewState viewState(_render, hmdEnabled);
uint16_t programIdx = invalidHandle;
@@ -5489,12 +5570,13 @@ namespace bgfx { namespace gl
m_occlusionQuery.resolve(_render);
}
uint8_t eye = 0;
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
bool viewRestart = false;
uint8_t eye = 0;
uint8_t restartState = 0;
viewState.m_rect = _render->m_rect[0];
@@ -5576,6 +5658,9 @@ namespace bgfx { namespace gl
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
// commit previous eye to HMD and start rendering new frame
m_ovr.commitEye(eye);
m_ovr.renderEyeStart(eye);
}
else
{
@@ -5677,7 +5762,7 @@ namespace bgfx { namespace gl
const RenderCompute& compute = renderItem.compute;
ProgramGL& program = m_program[key.m_program];
GL_CHECK(glUseProgram(program.m_id) );
GL_CHECK(glUseProgram(program.m_id) );
GLbitfield barrier = 0;
for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii)