Added HMD recenter support. Updated examples to support HMD.

This commit is contained in:
Branimir Karadžić 2014-11-02 00:06:18 -07:00
parent 748da31049
commit a2153729be
11 changed files with 239 additions and 87 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -159,13 +159,36 @@ int _main_(int /*_argc*/, char** /*_argv*/)
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);

View file

@ -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

View file

@ -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" },

View file

@ -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)

View file

@ -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)

View file

@ -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<<msaa);
@ -1720,6 +1724,11 @@ namespace bgfx
ovrPreReset();
ovrPostReset();
}
if (recenter)
{
m_ovr.recenter();
}
}
uint32_t setFrameBuffer(FrameBufferHandle _fbh, uint32_t _height, bool _msaa = true)