mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-18 13:03:05 +01:00
The new platform agnositic class bgfx::VR manages the functionality that is shared across the various VR platforms. The individual platform renderers no longer need to interface with the internal VR tpyes (OVRRenderI) directly This greatly simplifies the OVR object's surface area which is now provided by the VRImplI interface. bgfx::VR now manages core lifecycle issues of the headset. The notable renderer API changes are the separation of sensor sampling and rendering. We need these separate so we can control the timing (later commit) of camera sampling with finer granularity than at the start of the video frame.
206 lines
3.7 KiB
C++
206 lines
3.7 KiB
C++
/*
|
|
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
|
|
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
|
*/
|
|
|
|
#include "hmd.h"
|
|
|
|
namespace bgfx
|
|
{
|
|
VR::VR()
|
|
: m_framesUntilReconnect(0)
|
|
, m_enabled(false)
|
|
{
|
|
}
|
|
|
|
void VR::init(VRImplI* _impl)
|
|
{
|
|
if (!_impl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!_impl->init())
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_impl = _impl;
|
|
m_impl->connect(&m_desc);
|
|
if (!m_impl->isConnected())
|
|
{
|
|
connectFailed();
|
|
return;
|
|
}
|
|
|
|
m_hmdSize.m_w = m_desc.m_eyeSize[0].m_w + m_desc.m_eyeSize[1].m_w;
|
|
m_hmdSize.m_h = bx::uint32_max(m_desc.m_eyeSize[0].m_h, m_desc.m_eyeSize[1].m_h);
|
|
}
|
|
|
|
void VR::shutdown()
|
|
{
|
|
if (!m_impl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_impl->destroySwapChain();
|
|
if (m_impl->isConnected())
|
|
{
|
|
m_impl->disconnect();
|
|
}
|
|
|
|
m_impl->shutdown();
|
|
m_impl = NULL;
|
|
m_enabled = false;
|
|
}
|
|
|
|
void VR::renderEyeStart(uint8_t _eye, Rect* _viewport)
|
|
{
|
|
BX_CHECK(m_enabled, "VR::renderEyeStart called while not enabled - render usage error");
|
|
|
|
_viewport->m_x = 0;
|
|
_viewport->m_y = 0;
|
|
_viewport->m_width = m_desc.m_eyeSize[_eye].m_w;
|
|
_viewport->m_height = m_desc.m_eyeSize[_eye].m_h;
|
|
|
|
m_impl->renderEyeStart(m_desc, _eye);
|
|
}
|
|
|
|
void VR::recenter()
|
|
{
|
|
if (m_impl)
|
|
{
|
|
m_impl->recenter();
|
|
}
|
|
}
|
|
|
|
void VR::preReset()
|
|
{
|
|
if (m_impl)
|
|
{
|
|
m_impl->destroyMirror();
|
|
}
|
|
|
|
m_enabled = false;
|
|
}
|
|
|
|
void VR::postReset(int _msaaSamples, int _mirrorWidth, int _mirrorHeight)
|
|
{
|
|
if (m_impl && m_impl->createSwapChain(m_desc, _msaaSamples, _mirrorWidth, _mirrorHeight))
|
|
{
|
|
m_enabled = true;
|
|
}
|
|
}
|
|
|
|
void VR::flip()
|
|
{
|
|
if (!m_impl || !m_enabled)
|
|
{
|
|
return;
|
|
}
|
|
else if (!m_impl->isConnected() && !tryReconnect())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!m_impl->submitSwapChain(m_desc))
|
|
{
|
|
m_impl->destroySwapChain();
|
|
m_impl->disconnect();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void VR::swap(HMD& _hmd)
|
|
{
|
|
_hmd.flags = BGFX_HMD_NONE;
|
|
|
|
if (!m_impl)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_hmd.flags = BGFX_HMD_DEVICE_RESOLUTION;
|
|
_hmd.deviceWidth = m_desc.m_deviceSize.m_w;
|
|
_hmd.deviceHeight = m_desc.m_deviceSize.m_h;
|
|
_hmd.width = m_hmdSize.m_w;
|
|
_hmd.height = m_hmdSize.m_h;
|
|
|
|
if (!m_impl->updateTracking(_hmd))
|
|
{
|
|
m_impl->destroySwapChain();
|
|
m_impl->disconnect();
|
|
}
|
|
|
|
if (!m_impl->isConnected())
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (int eye = 0; eye < 2; ++eye)
|
|
{
|
|
_hmd.eye[eye].fov[0] = m_desc.m_eyeFov[eye].m_up;
|
|
_hmd.eye[eye].fov[1] = m_desc.m_eyeFov[eye].m_down;
|
|
_hmd.eye[eye].fov[2] = m_desc.m_eyeFov[eye].m_left;
|
|
_hmd.eye[eye].fov[3] = m_desc.m_eyeFov[eye].m_right;
|
|
}
|
|
|
|
m_impl->updateInput(_hmd);
|
|
if (m_enabled)
|
|
{
|
|
_hmd.flags |= BGFX_HMD_RENDERING;
|
|
}
|
|
}
|
|
|
|
bool VR::tryReconnect()
|
|
{
|
|
if (!m_impl)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
BX_CHECK(!m_impl->isConnected(), "VR::tryReconnect called when already connected. Usage error");
|
|
|
|
--m_framesUntilReconnect;
|
|
if (m_framesUntilReconnect > 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_framesUntilReconnect = 90;
|
|
m_impl->connect(&m_desc);
|
|
if (!m_impl->isConnected())
|
|
{
|
|
connectFailed();
|
|
return false;
|
|
}
|
|
|
|
m_hmdSize.m_w = m_desc.m_eyeSize[0].m_w + m_desc.m_eyeSize[1].m_w;
|
|
m_hmdSize.m_h = bx::uint32_max(m_desc.m_eyeSize[0].m_h, m_desc.m_eyeSize[1].m_h);
|
|
return true;
|
|
}
|
|
|
|
void VR::connectFailed()
|
|
{
|
|
// sane defaults
|
|
m_desc.m_deviceSize.m_w = 2160;
|
|
m_desc.m_deviceSize.m_h = 1200;
|
|
m_desc.m_deviceType = 0;
|
|
m_desc.m_refreshRate = 90.0f;
|
|
m_desc.m_neckOffset[0] = 0.0805f;
|
|
m_desc.m_neckOffset[1] = 0.075f;
|
|
|
|
for (int eye = 0; eye < 2; ++eye)
|
|
{
|
|
m_desc.m_eyeFov[eye].m_up = 1.32928634f;
|
|
m_desc.m_eyeFov[eye].m_down = 1.32928634f;
|
|
}
|
|
m_desc.m_eyeFov[0].m_left = 1.05865765f;
|
|
m_desc.m_eyeFov[0].m_right = 1.09236801f;
|
|
m_desc.m_eyeFov[1].m_left = 1.09236801f;
|
|
m_desc.m_eyeFov[1].m_right = 1.05865765f;
|
|
}
|
|
|
|
} // namesapce bgfx
|