From a2153729be4d4a98e19f789033b76197fd87cdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 2 Nov 2014 00:06:18 -0700 Subject: [PATCH] Added HMD recenter support. Updated examples to support HMD. --- examples/01-cubes/cubes.cpp | 74 +++++++++++---------- examples/02-metaballs/metaballs.cpp | 37 +++++++++-- examples/04-mesh/mesh.cpp | 37 +++++++++-- examples/05-instancing/instancing.cpp | 37 +++++++++-- examples/06-bump/bump.cpp | 39 ++++++++--- examples/12-lod/lod.cpp | 35 ++++++++-- examples/14-shadowvolumes/shadowvolumes.cpp | 30 ++++++--- examples/common/entry/entry.cpp | 10 +-- include/bgfxdefines.h | 1 + src/renderer_d3d11.cpp | 15 ++++- src/renderer_gl.cpp | 11 ++- 11 files changed, 239 insertions(+), 87 deletions(-) diff --git a/examples/01-cubes/cubes.cpp b/examples/01-cubes/cubes.cpp index 54b297c2..c54d0ba2 100644 --- a/examples/01-cubes/cubes.cpp +++ b/examples/01-cubes/cubes.cpp @@ -95,44 +95,10 @@ int _main_(int /*_argc*/, char** /*_argv*/) // Create program from shaders. bgfx::ProgramHandle program = loadProgram("vs_cubes", "fs_cubes"); - float at[3] = { 0.0f, 0.0f, 0.0f }; - float eye[3] = { 0.0f, 0.0f, -35.0f }; - int64_t timeOffset = bx::getHPCounter(); while (!entry::processEvents(width, height, debug, reset) ) { - float view[16]; - bx::mtxLookAt(view, eye, at); - - // Set view and projection matrix for view 0. - const bgfx::HMD* hmd = bgfx::getHMD(); - if (NULL != hmd) - { - float proj[16]; - bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); - bgfx::setViewTransform(0, view, proj); - - // Set view 0 default viewport. - // - // Use HMD's width/height since HMD's internal frame buffer size - // might be much larger than window size. - bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); - } - else - { - float proj[16]; - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); - bgfx::setViewTransform(0, view, proj); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, width, height); - } - - // This dummy draw call is here to make sure that view 0 is cleared - // if no other draw calls are submitted to view 0. - bgfx::submit(0); - int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; @@ -148,10 +114,48 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Rendering simple static mesh."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); + float at[3] = { 0.0f, 0.0f, 0.0f }; + float eye[3] = { 0.0f, 0.0f, -35.0f }; + + // Set view and projection matrix for view 0. + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } + + // This dummy draw call is here to make sure that view 0 is cleared + // if no other draw calls are submitted to view 0. + bgfx::submit(0); + // Submit 11x11 cubes. for (uint32_t yy = 0; yy < 11; ++yy) { - for (uint32_t xx = 0; xx < 11; ++xx) + for (uint32_t xx = 0; xx < yy; ++xx) { float mtx[16]; bx::mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); diff --git a/examples/02-metaballs/metaballs.cpp b/examples/02-metaballs/metaballs.cpp index 6aaf355e..96f9a1cd 100644 --- a/examples/02-metaballs/metaballs.cpp +++ b/examples/02-metaballs/metaballs.cpp @@ -542,16 +542,39 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/02-metaball"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Rendering with transient buffers and embedding shaders."); - float at[3] = { 0.0f, 0.0f, 0.0f }; + float at[3] = { 0.0f, 0.0f, 0.0f }; float eye[3] = { 0.0f, 0.0f, -50.0f }; - float view[16]; - float proj[16]; - bx::mtxLookAt(view, eye, at); - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); - // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } // Stats. uint32_t numVertices = 0; diff --git a/examples/04-mesh/mesh.cpp b/examples/04-mesh/mesh.cpp index ca2bbf0c..6b222a8e 100644 --- a/examples/04-mesh/mesh.cpp +++ b/examples/04-mesh/mesh.cpp @@ -60,16 +60,39 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Loading meshes."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); - float at[3] = { 0.0f, 1.0f, 0.0f }; + float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.5f }; - float view[16]; - float proj[16]; - bx::mtxLookAt(view, eye, at); - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); - // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } float mtx[16]; bx::mtxRotateXY(mtx diff --git a/examples/05-instancing/instancing.cpp b/examples/05-instancing/instancing.cpp index 71ec7b1e..7c709c2b 100644 --- a/examples/05-instancing/instancing.cpp +++ b/examples/05-instancing/instancing.cpp @@ -130,16 +130,39 @@ int _main_(int /*_argc*/, char** /*_argv*/) } else { - float at[3] = { 0.0f, 0.0f, 0.0f }; + float at[3] = { 0.0f, 0.0f, 0.0f }; float eye[3] = { 0.0f, 0.0f, -35.0f }; - float view[16]; - float proj[16]; - bx::mtxLookAt(view, eye, at); - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); - // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } const uint16_t instanceStride = 80; const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(121, instanceStride); diff --git a/examples/06-bump/bump.cpp b/examples/06-bump/bump.cpp index 340dafac..f3fb7001 100644 --- a/examples/06-bump/bump.cpp +++ b/examples/06-bump/bump.cpp @@ -190,13 +190,39 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Loading textures."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); - float at[3] = { 0.0f, 0.0f, 0.0f }; + float at[3] = { 0.0f, 0.0f, 0.0f }; float eye[3] = { 0.0f, 0.0f, -7.0f }; - float view[16]; - float proj[16]; - bx::mtxLookAt(view, eye, at); - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + // Set view and projection matrix for view 0. + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } float lightPosRadius[4][4]; for (uint32_t ii = 0; ii < numLights; ++ii) @@ -219,9 +245,6 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR, numLights); - // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); - const uint16_t instanceStride = 64; const uint16_t numInstances = 3; diff --git a/examples/12-lod/lod.cpp b/examples/12-lod/lod.cpp index e1f3a503..5b7cba30 100644 --- a/examples/12-lod/lod.cpp +++ b/examples/12-lod/lod.cpp @@ -158,14 +158,37 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::dbgTextPrintf(0, 4, transitions ? 0x2f : 0x1f, transitions ? "Transitions on" : "Transitions off"); eye[2] = -distance; - - float view[16]; - float proj[16]; - bx::mtxLookAt(view, eye, at); - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float view[16]; + bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); + + float proj[16]; + bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + // + // Use HMD's width/height since HMD's internal frame buffer size + // might be much larger than window size. + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); + } + else + { + float view[16]; + bx::mtxLookAt(view, eye, at); + + float proj[16]; + bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + bgfx::setViewTransform(0, view, proj); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + } float mtx[16]; bx::mtxScale(mtx, 0.1f, 0.1f, 0.1f); diff --git a/examples/14-shadowvolumes/shadowvolumes.cpp b/examples/14-shadowvolumes/shadowvolumes.cpp index d120920d..b704b110 100644 --- a/examples/14-shadowvolumes/shadowvolumes.cpp +++ b/examples/14-shadowvolumes/shadowvolumes.cpp @@ -217,11 +217,6 @@ void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _wid } } -inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far) -{ - bx::mtxProj(_result, _fovy, _aspect, _near, _far, s_oglNdc); -} - void mtxBillboard(float* __restrict _result , const float* __restrict _view , const float* __restrict _pos @@ -2166,7 +2161,6 @@ int _main_(int /*_argc*/, char** /*_argv*/) const float aspect = float(viewState.m_width)/float(viewState.m_height); const float nearPlane = 1.0f; const float farPlane = 1000.0f; - mtxProj(viewState.m_proj, fov, aspect, nearPlane, farPlane); float initialPos[3] = { 3.0f, 20.0f, -58.0f }; cameraCreate(); @@ -2178,10 +2172,10 @@ int _main_(int /*_argc*/, char** /*_argv*/) while (!entry::processEvents(viewState.m_width, viewState.m_height, debug, reset, &mouseState) ) { // Respond properly on resize. - if (oldWidth != viewState.m_width + if (oldWidth != viewState.m_width || oldHeight != viewState.m_height) { - oldWidth = viewState.m_width; + oldWidth = viewState.m_width; oldHeight = viewState.m_height; bgfx::destroyFrameBuffer(s_stencilFb); @@ -2204,7 +2198,25 @@ int _main_(int /*_argc*/, char** /*_argv*/) // Update camera. cameraUpdate(deltaTime, mouseState.m_mx, mouseState.m_my, !!mouseState.m_buttons[entry::MouseButton::Right]); - cameraGetViewMtx(viewState.m_view); + + // Set view and projection matrix for view 0. + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd) + { + float eye[3]; + cameraGetPosition(eye); + + bx::mtxQuatTranslationHMD(viewState.m_view, hmd->eye[0].rotation, eye); + bx::mtxProj(viewState.m_proj, hmd->eye[0].fov, nearPlane, farPlane, s_oglNdc); + + viewState.m_width = hmd->width; + viewState.m_height = hmd->height; + } + else + { + cameraGetViewMtx(viewState.m_view); + bx::mtxProj(viewState.m_proj, fov, aspect, nearPlane, farPlane, s_oglNdc); + } imguiBeginFrame(mouseState.m_mx , mouseState.m_my diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index 4ee37e37..210588cc 100644 --- a/examples/common/entry/entry.cpp +++ b/examples/common/entry/entry.cpp @@ -65,10 +65,11 @@ namespace entry { if (_argc > 1) { - if (setOrToggle(s_reset, "vsync", BGFX_RESET_VSYNC, 1, _argc, _argv) - || setOrToggle(s_reset, "hmd", BGFX_RESET_HMD, 1, _argc, _argv) - || setOrToggle(s_reset, "hmddbg", BGFX_RESET_HMD_DEBUG, 1, _argc, _argv) - || setOrToggle(s_reset, "msaa", BGFX_RESET_MSAA_X16, 1, _argc, _argv) ) + if (setOrToggle(s_reset, "vsync", BGFX_RESET_VSYNC, 1, _argc, _argv) + || setOrToggle(s_reset, "hmd", BGFX_RESET_HMD, 1, _argc, _argv) + || setOrToggle(s_reset, "hmddbg", BGFX_RESET_HMD_DEBUG, 1, _argc, _argv) + || setOrToggle(s_reset, "hmdrecenter", BGFX_RESET_HMD_RECENTER, 1, _argc, _argv) + || setOrToggle(s_reset, "msaa", BGFX_RESET_MSAA_X16, 1, _argc, _argv) ) { return 0; } @@ -116,6 +117,7 @@ namespace entry { entry::Key::F1, entry::Modifier::LeftShift, 1, cmd, "graphics stats 0\ngraphics text 0" }, { entry::Key::F3, entry::Modifier::None, 1, cmd, "graphics wireframe" }, { entry::Key::F4, entry::Modifier::None, 1, cmd, "graphics hmd" }, + { entry::Key::F4, entry::Modifier::LeftShift, 1, cmd, "graphics hmdrecenter" }, { entry::Key::F7, entry::Modifier::None, 1, cmd, "graphics vsync" }, { entry::Key::F8, entry::Modifier::None, 1, cmd, "graphics msaa" }, { entry::Key::Print, entry::Modifier::None, 1, cmd, "graphics screenshot" }, diff --git a/include/bgfxdefines.h b/include/bgfxdefines.h index 99ebe31b..5e0d31c4 100644 --- a/include/bgfxdefines.h +++ b/include/bgfxdefines.h @@ -266,6 +266,7 @@ #define BGFX_RESET_CAPTURE UINT32_C(0x00000100) #define BGFX_RESET_HMD UINT32_C(0x00000200) #define BGFX_RESET_HMD_DEBUG UINT32_C(0x00000400) +#define BGFX_RESET_HMD_RECENTER UINT32_C(0x00000800) /// #define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000000001) diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 9344d9bd..2dfcf4e2 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1280,17 +1280,21 @@ RENDERDOC_IMPORT void updateResolution(const Resolution& _resolution) { + bool recenter = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER); + uint32_t flags = _resolution.m_flags & ~BGFX_RESET_HMD_RECENTER; + if ( (uint32_t)m_scd.BufferDesc.Width != _resolution.m_width || (uint32_t)m_scd.BufferDesc.Height != _resolution.m_height - || m_flags != _resolution.m_flags) + || m_flags != flags) { - bool resize = (m_flags&BGFX_RESET_MSAA_MASK) == (_resolution.m_flags&BGFX_RESET_MSAA_MASK); - m_flags = _resolution.m_flags; + bool resize = (m_flags&BGFX_RESET_MSAA_MASK) == (flags&BGFX_RESET_MSAA_MASK); + m_flags = flags; m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height); m_textVideoMem.clear(); m_resolution = _resolution; + m_resolution.m_flags = flags; m_scd.BufferDesc.Width = _resolution.m_width; m_scd.BufferDesc.Height = _resolution.m_height; @@ -1323,6 +1327,11 @@ RENDERDOC_IMPORT postReset(); } + + if (recenter) + { + m_ovr.recenter(); + } } void setShaderConstant(uint8_t _flags, uint16_t _regIndex, const void* _val, uint16_t _numRegs) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index a218a2a1..769f1609 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1702,14 +1702,18 @@ namespace bgfx void updateResolution(const Resolution& _resolution) { + bool recenter = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER); + uint32_t flags = _resolution.m_flags & ~BGFX_RESET_HMD_RECENTER; + if (m_resolution.m_width != _resolution.m_width || m_resolution.m_height != _resolution.m_height - || m_resolution.m_flags != _resolution.m_flags) + || m_resolution.m_flags != flags) { m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height); m_textVideoMem.clear(); m_resolution = _resolution; + m_resolution.m_flags = flags; uint32_t msaa = (m_resolution.m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT; msaa = bx::uint32_min(m_maxMsaa, msaa == 0 ? 0 : 1<