2014-10-29 01:08:55 -04:00
|
|
|
/*
|
2015-04-15 01:05:20 -04:00
|
|
|
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
|
|
|
|
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
|
|
|
*/
|
2014-10-29 01:08:55 -04:00
|
|
|
|
|
|
|
#include "ovr.h"
|
|
|
|
|
|
|
|
#if BGFX_CONFIG_USE_OVR
|
|
|
|
|
|
|
|
namespace bgfx
|
|
|
|
{
|
2015-06-04 21:08:08 -04:00
|
|
|
#if OVR_VERSION <= OVR_VERSION_050
|
|
|
|
static const int s_eyeBuffer = 100;
|
|
|
|
#else
|
|
|
|
static const int s_eyeBuffer = 8;
|
|
|
|
#endif // OVR_VERSION...
|
|
|
|
|
2014-10-29 01:08:55 -04:00
|
|
|
OVR::OVR()
|
|
|
|
: m_hmd(NULL)
|
2015-06-02 20:00:36 -04:00
|
|
|
, m_isenabled(false)
|
2014-11-13 00:26:28 -05:00
|
|
|
, m_debug(false)
|
2014-10-29 01:08:55 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
OVR::~OVR()
|
|
|
|
{
|
2015-06-02 20:00:36 -04:00
|
|
|
BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void OVR::init()
|
|
|
|
{
|
2015-06-02 20:00:36 -04:00
|
|
|
bool initialized = !!ovr_Initialize();
|
|
|
|
BX_WARN(initialized, "Unable to create OVR device.");
|
|
|
|
if (!initialized)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_hmd = ovrHmd_Create(0);
|
|
|
|
if (NULL == m_hmd)
|
|
|
|
{
|
|
|
|
m_hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
|
|
|
|
BX_WARN(NULL != m_hmd, "Unable to create OVR device.");
|
|
|
|
if (NULL == m_hmd)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BX_TRACE("HMD: %s, %s, firmware: %d.%d"
|
|
|
|
, m_hmd->ProductName
|
|
|
|
, m_hmd->Manufacturer
|
|
|
|
, m_hmd->FirmwareMajor
|
|
|
|
, m_hmd->FirmwareMinor
|
|
|
|
);
|
|
|
|
|
|
|
|
ovrSizei sizeL = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmd->DefaultEyeFov[0], 1.0f);
|
|
|
|
ovrSizei sizeR = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmd->DefaultEyeFov[1], 1.0f);
|
2015-06-04 21:08:08 -04:00
|
|
|
m_rtSize.w = sizeL.w + sizeR.w + s_eyeBuffer;
|
2015-06-02 20:00:36 -04:00
|
|
|
m_rtSize.h = bx::uint32_max(sizeL.h, sizeR.h);
|
|
|
|
m_warning = true;
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void OVR::shutdown()
|
|
|
|
{
|
2015-06-02 20:00:36 -04:00
|
|
|
BX_CHECK(!m_isenabled, "HMD not disabled.");
|
|
|
|
ovrHmd_Destroy(m_hmd);
|
|
|
|
m_hmd = NULL;
|
2014-10-29 01:08:55 -04:00
|
|
|
ovr_Shutdown();
|
|
|
|
}
|
|
|
|
|
2015-06-05 05:00:26 -04:00
|
|
|
void OVR::getViewport(uint8_t _eye, Rect* _viewport)
|
|
|
|
{
|
|
|
|
_viewport->m_width = (m_rtSize.w - s_eyeBuffer)/2;
|
|
|
|
_viewport->m_height = m_rtSize.h;
|
|
|
|
_viewport->m_x = _eye * (m_rtSize.w + s_eyeBuffer + 1)/2;
|
|
|
|
_viewport->m_y = 0;
|
|
|
|
}
|
|
|
|
|
2014-10-29 01:08:55 -04:00
|
|
|
bool OVR::postReset(void* _nwh, ovrRenderAPIConfig* _config, bool _debug)
|
|
|
|
{
|
2014-11-13 00:26:28 -05:00
|
|
|
if (_debug)
|
|
|
|
{
|
|
|
|
switch (_config->Header.API)
|
|
|
|
{
|
|
|
|
#if BGFX_CONFIG_RENDERER_DIRECT3D11
|
|
|
|
case ovrRenderAPI_D3D11:
|
|
|
|
{
|
|
|
|
ovrD3D11ConfigData* data = (ovrD3D11ConfigData*)_config;
|
2014-12-21 21:55:33 -05:00
|
|
|
# if OVR_VERSION > OVR_VERSION_043
|
2014-12-05 22:17:59 -05:00
|
|
|
m_rtSize = data->Header.BackBufferSize;
|
2014-12-21 21:55:33 -05:00
|
|
|
# else
|
|
|
|
m_rtSize = data->Header.RTSize;
|
|
|
|
# endif // OVR_VERSION > OVR_VERSION_043
|
2014-11-13 00:26:28 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif // BGFX_CONFIG_RENDERER_DIRECT3D11
|
|
|
|
|
|
|
|
#if BGFX_CONFIG_RENDERER_OPENGL
|
|
|
|
case ovrRenderAPI_OpenGL:
|
|
|
|
{
|
|
|
|
ovrGLConfigData* data = (ovrGLConfigData*)_config;
|
2014-12-21 21:55:33 -05:00
|
|
|
# if OVR_VERSION > OVR_VERSION_043
|
2014-12-05 22:17:59 -05:00
|
|
|
m_rtSize = data->Header.BackBufferSize;
|
2014-12-21 21:55:33 -05:00
|
|
|
# else
|
|
|
|
m_rtSize = data->Header.RTSize;
|
|
|
|
# endif // OVR_VERSION > OVR_VERSION_043
|
2014-11-13 00:26:28 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
|
|
|
|
2015-04-27 22:38:48 -04:00
|
|
|
case ovrRenderAPI_None:
|
2014-11-13 00:26:28 -05:00
|
|
|
default:
|
|
|
|
BX_CHECK(false, "You should not be here!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_debug = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-29 01:08:55 -04:00
|
|
|
if (NULL == m_hmd)
|
|
|
|
{
|
2015-06-02 20:00:36 -04:00
|
|
|
return false;
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
|
|
|
|
2015-06-02 20:00:36 -04:00
|
|
|
m_isenabled = true;
|
2014-12-21 21:55:33 -05:00
|
|
|
|
2014-10-29 01:08:55 -04:00
|
|
|
ovrBool result;
|
|
|
|
result = ovrHmd_AttachToWindow(m_hmd, _nwh, NULL, NULL);
|
|
|
|
if (!result) { goto ovrError; }
|
|
|
|
|
|
|
|
ovrFovPort eyeFov[2] = { m_hmd->DefaultEyeFov[0], m_hmd->DefaultEyeFov[1] };
|
|
|
|
result = ovrHmd_ConfigureRendering(m_hmd
|
|
|
|
, _config
|
|
|
|
, 0
|
2015-03-28 20:34:47 -04:00
|
|
|
#if OVR_VERSION < OVR_VERSION_050
|
|
|
|
| ovrDistortionCap_Chromatic // permanently enabled >= v5.0
|
|
|
|
#endif
|
2014-10-29 01:08:55 -04:00
|
|
|
| ovrDistortionCap_Vignette
|
|
|
|
| ovrDistortionCap_TimeWarp
|
|
|
|
| ovrDistortionCap_Overdrive
|
2014-11-13 00:26:28 -05:00
|
|
|
| ovrDistortionCap_NoRestore
|
2015-04-17 14:03:04 -04:00
|
|
|
| ovrDistortionCap_HqDistortion
|
2014-10-29 01:08:55 -04:00
|
|
|
, eyeFov
|
|
|
|
, m_erd
|
|
|
|
);
|
|
|
|
if (!result) { goto ovrError; }
|
|
|
|
|
|
|
|
ovrHmd_SetEnabledCaps(m_hmd
|
|
|
|
, 0
|
|
|
|
| ovrHmdCap_LowPersistence
|
|
|
|
| ovrHmdCap_DynamicPrediction
|
|
|
|
);
|
|
|
|
|
|
|
|
result = ovrHmd_ConfigureTracking(m_hmd
|
|
|
|
, 0
|
|
|
|
| ovrTrackingCap_Orientation
|
|
|
|
| ovrTrackingCap_MagYawCorrection
|
|
|
|
| ovrTrackingCap_Position
|
|
|
|
, 0
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
ovrError:
|
|
|
|
BX_TRACE("Failed to initialize OVR.");
|
2015-06-02 20:00:36 -04:00
|
|
|
m_isenabled = false;
|
2014-10-29 01:08:55 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_warning = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-12-11 01:44:00 -05:00
|
|
|
void OVR::postReset(const ovrTexture& _texture)
|
2014-10-29 01:08:55 -04:00
|
|
|
{
|
|
|
|
if (NULL != m_hmd)
|
|
|
|
{
|
|
|
|
m_texture[0] = _texture;
|
|
|
|
m_texture[1] = _texture;
|
|
|
|
|
|
|
|
ovrRecti rect;
|
|
|
|
rect.Pos.x = 0;
|
|
|
|
rect.Pos.y = 0;
|
2015-06-04 21:08:08 -04:00
|
|
|
rect.Size.w = (m_rtSize.w - s_eyeBuffer)/2;
|
2014-10-29 01:08:55 -04:00
|
|
|
rect.Size.h = m_rtSize.h;
|
|
|
|
|
|
|
|
m_texture[0].Header.RenderViewport = rect;
|
|
|
|
|
2015-06-04 21:08:08 -04:00
|
|
|
rect.Pos.x += rect.Size.w + s_eyeBuffer;
|
2014-10-29 01:08:55 -04:00
|
|
|
m_texture[1].Header.RenderViewport = rect;
|
|
|
|
|
|
|
|
m_timing = ovrHmd_BeginFrame(m_hmd, 0);
|
2015-04-17 14:03:41 -04:00
|
|
|
#if OVR_VERSION > OVR_VERSION_042
|
|
|
|
m_pose[0] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Left);
|
|
|
|
m_pose[1] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Right);
|
|
|
|
#else
|
|
|
|
m_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);
|
|
|
|
m_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);
|
|
|
|
#endif // OVR_VERSION > OVR_VERSION_042
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OVR::preReset()
|
|
|
|
{
|
2015-06-02 20:00:36 -04:00
|
|
|
if (m_isenabled)
|
2014-10-29 01:08:55 -04:00
|
|
|
{
|
|
|
|
ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
|
2015-06-02 20:00:36 -04:00
|
|
|
ovrHmd_AttachToWindow(m_hmd, NULL, NULL, NULL);
|
|
|
|
ovrHmd_ConfigureRendering(m_hmd, NULL, 0, NULL, NULL);
|
|
|
|
m_isenabled = false;
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
2014-11-13 00:26:28 -05:00
|
|
|
|
|
|
|
m_debug = false;
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
|
|
|
|
2015-04-15 23:59:00 -04:00
|
|
|
bool OVR::swap(HMD& _hmd)
|
2014-10-29 01:08:55 -04:00
|
|
|
{
|
2015-06-02 20:00:36 -04:00
|
|
|
_hmd.flags = BGFX_HMD_NONE;
|
|
|
|
|
|
|
|
if (NULL != m_hmd)
|
|
|
|
{
|
|
|
|
_hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
|
|
|
|
_hmd.deviceWidth = m_hmd->Resolution.w;
|
|
|
|
_hmd.deviceHeight = m_hmd->Resolution.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_isenabled)
|
2014-10-29 01:08:55 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-06-02 20:00:36 -04:00
|
|
|
_hmd.flags |= BGFX_HMD_RENDERING;
|
2014-10-29 01:08:55 -04:00
|
|
|
ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
|
|
|
|
|
|
|
|
if (m_warning)
|
|
|
|
{
|
|
|
|
m_warning = !ovrHmd_DismissHSWDisplay(m_hmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_timing = ovrHmd_BeginFrame(m_hmd, 0);
|
|
|
|
|
2015-04-16 00:52:31 -04:00
|
|
|
#if OVR_VERSION > OVR_VERSION_042
|
|
|
|
m_pose[0] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Left);
|
|
|
|
m_pose[1] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Right);
|
|
|
|
#else
|
|
|
|
m_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);
|
|
|
|
m_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);
|
|
|
|
#endif // OVR_VERSION > OVR_VERSION_042
|
|
|
|
|
|
|
|
getEyePose(_hmd);
|
|
|
|
|
2014-10-29 01:08:55 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OVR::recenter()
|
|
|
|
{
|
|
|
|
if (NULL != m_hmd)
|
|
|
|
{
|
|
|
|
ovrHmd_RecenterPose(m_hmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OVR::getEyePose(HMD& _hmd)
|
|
|
|
{
|
|
|
|
if (NULL != m_hmd)
|
|
|
|
{
|
|
|
|
for (int ii = 0; ii < 2; ++ii)
|
|
|
|
{
|
2015-04-16 00:52:31 -04:00
|
|
|
const ovrPosef& pose = m_pose[ii];
|
2014-10-29 01:08:55 -04:00
|
|
|
HMD::Eye& eye = _hmd.eye[ii];
|
|
|
|
eye.rotation[0] = pose.Orientation.x;
|
|
|
|
eye.rotation[1] = pose.Orientation.y;
|
|
|
|
eye.rotation[2] = pose.Orientation.z;
|
|
|
|
eye.rotation[3] = pose.Orientation.w;
|
|
|
|
eye.translation[0] = pose.Position.x;
|
|
|
|
eye.translation[1] = pose.Position.y;
|
|
|
|
eye.translation[2] = pose.Position.z;
|
|
|
|
|
|
|
|
const ovrEyeRenderDesc& erd = m_erd[ii];
|
|
|
|
eye.fov[0] = erd.Fov.UpTan;
|
|
|
|
eye.fov[1] = erd.Fov.DownTan;
|
|
|
|
eye.fov[2] = erd.Fov.LeftTan;
|
|
|
|
eye.fov[3] = erd.Fov.RightTan;
|
2014-12-21 21:55:33 -05:00
|
|
|
#if OVR_VERSION > OVR_VERSION_042
|
2014-11-08 23:57:47 -05:00
|
|
|
eye.viewOffset[0] = erd.HmdToEyeViewOffset.x;
|
|
|
|
eye.viewOffset[1] = erd.HmdToEyeViewOffset.y;
|
|
|
|
eye.viewOffset[2] = erd.HmdToEyeViewOffset.z;
|
2014-12-21 21:55:33 -05:00
|
|
|
#else
|
|
|
|
eye.viewOffset[0] = erd.ViewAdjust.x;
|
|
|
|
eye.viewOffset[1] = erd.ViewAdjust.y;
|
|
|
|
eye.viewOffset[2] = erd.ViewAdjust.z;
|
|
|
|
#endif // OVR_VERSION > OVR_VERSION_042
|
2014-10-29 01:08:55 -04:00
|
|
|
eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
|
|
|
|
eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-11-13 00:26:28 -05:00
|
|
|
for (int ii = 0; ii < 2; ++ii)
|
|
|
|
{
|
|
|
|
_hmd.eye[ii].rotation[0] = 0.0f;
|
|
|
|
_hmd.eye[ii].rotation[1] = 0.0f;
|
|
|
|
_hmd.eye[ii].rotation[2] = 0.0f;
|
|
|
|
_hmd.eye[ii].rotation[3] = 1.0f;
|
|
|
|
_hmd.eye[ii].translation[0] = 0.0f;
|
|
|
|
_hmd.eye[ii].translation[1] = 0.0f;
|
|
|
|
_hmd.eye[ii].translation[2] = 0.0f;
|
|
|
|
_hmd.eye[ii].fov[0] = 1.32928634f;
|
|
|
|
_hmd.eye[ii].fov[1] = 1.32928634f;
|
|
|
|
_hmd.eye[ii].fov[2] = 0 == ii ? 1.05865765f : 1.09236801f;
|
|
|
|
_hmd.eye[ii].fov[3] = 0 == ii ? 1.09236801f : 1.05865765f;
|
|
|
|
_hmd.eye[ii].viewOffset[0] = 0 == ii ? 0.0355070010f : -0.0375000015f;
|
|
|
|
_hmd.eye[ii].viewOffset[1] = 0.0f;
|
|
|
|
_hmd.eye[ii].viewOffset[2] = 0 == ii ? 0.00150949787f : -0.00150949787f;
|
|
|
|
_hmd.eye[ii].pixelsPerTanAngle[0] = 1;
|
|
|
|
_hmd.eye[ii].pixelsPerTanAngle[1] = 1;
|
|
|
|
}
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
2014-11-13 00:26:28 -05:00
|
|
|
|
|
|
|
_hmd.width = uint16_t(m_rtSize.w);
|
|
|
|
_hmd.height = uint16_t(m_rtSize.h);
|
2014-10-29 01:08:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace bgfx
|
|
|
|
|
|
|
|
#endif // BGFX_CONFIG_USE_OVR
|