ovr.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * Copyright 2011-2015 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "ovr.h"
  6. #if BGFX_CONFIG_USE_OVR
  7. namespace bgfx
  8. {
  9. OVR::OVR()
  10. : m_hmd(NULL)
  11. , m_initialized(false)
  12. , m_debug(false)
  13. {
  14. }
  15. OVR::~OVR()
  16. {
  17. BX_CHECK(!m_initialized, "OVR not shutdown properly.");
  18. }
  19. void OVR::init()
  20. {
  21. m_initialized = !!ovr_Initialize();
  22. }
  23. void OVR::shutdown()
  24. {
  25. BX_CHECK(NULL == m_hmd, "HMD not destroyed.");
  26. ovr_Shutdown();
  27. m_initialized = false;
  28. }
  29. bool OVR::postReset(void* _nwh, ovrRenderAPIConfig* _config, bool _debug)
  30. {
  31. if (_debug)
  32. {
  33. switch (_config->Header.API)
  34. {
  35. #if BGFX_CONFIG_RENDERER_DIRECT3D9
  36. case ovrRenderAPI_D3D9:
  37. {
  38. ovrD3D9ConfigData* data = (ovrD3D9ConfigData*)_config;
  39. # if OVR_VERSION > OVR_VERSION_043
  40. m_rtSize = data->Header.BackBufferSize;
  41. # else
  42. m_rtSize = data->Header.RTSize;
  43. # endif // OVR_VERSION > OVR_VERSION_043
  44. }
  45. break;
  46. #endif // BGFX_CONFIG_RENDERER_DIRECT3D9
  47. #if BGFX_CONFIG_RENDERER_DIRECT3D11
  48. case ovrRenderAPI_D3D11:
  49. {
  50. ovrD3D11ConfigData* data = (ovrD3D11ConfigData*)_config;
  51. # if OVR_VERSION > OVR_VERSION_043
  52. m_rtSize = data->Header.BackBufferSize;
  53. # else
  54. m_rtSize = data->Header.RTSize;
  55. # endif // OVR_VERSION > OVR_VERSION_043
  56. }
  57. break;
  58. #endif // BGFX_CONFIG_RENDERER_DIRECT3D11
  59. #if BGFX_CONFIG_RENDERER_OPENGL
  60. case ovrRenderAPI_OpenGL:
  61. {
  62. ovrGLConfigData* data = (ovrGLConfigData*)_config;
  63. # if OVR_VERSION > OVR_VERSION_043
  64. m_rtSize = data->Header.BackBufferSize;
  65. # else
  66. m_rtSize = data->Header.RTSize;
  67. # endif // OVR_VERSION > OVR_VERSION_043
  68. }
  69. break;
  70. #endif // BGFX_CONFIG_RENDERER_OPENGL
  71. default:
  72. BX_CHECK(false, "You should not be here!");
  73. break;
  74. }
  75. m_debug = true;
  76. return false;
  77. }
  78. if (!m_initialized)
  79. {
  80. return false;
  81. }
  82. if (!_debug)
  83. {
  84. m_hmd = ovrHmd_Create(0);
  85. }
  86. if (NULL == m_hmd)
  87. {
  88. m_hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
  89. BX_WARN(NULL != m_hmd, "Unable to initialize OVR.");
  90. if (NULL == m_hmd)
  91. {
  92. return false;
  93. }
  94. }
  95. BX_TRACE("HMD: %s, %s, firmware: %d.%d"
  96. , m_hmd->ProductName
  97. , m_hmd->Manufacturer
  98. , m_hmd->FirmwareMajor
  99. , m_hmd->FirmwareMinor
  100. );
  101. ovrBool result;
  102. result = ovrHmd_AttachToWindow(m_hmd, _nwh, NULL, NULL);
  103. if (!result) { goto ovrError; }
  104. ovrFovPort eyeFov[2] = { m_hmd->DefaultEyeFov[0], m_hmd->DefaultEyeFov[1] };
  105. result = ovrHmd_ConfigureRendering(m_hmd
  106. , _config
  107. , 0
  108. | ovrDistortionCap_Chromatic
  109. | ovrDistortionCap_Vignette
  110. | ovrDistortionCap_TimeWarp
  111. | ovrDistortionCap_Overdrive
  112. | ovrDistortionCap_NoRestore
  113. , eyeFov
  114. , m_erd
  115. );
  116. if (!result) { goto ovrError; }
  117. ovrHmd_SetEnabledCaps(m_hmd
  118. , 0
  119. | ovrHmdCap_LowPersistence
  120. | ovrHmdCap_DynamicPrediction
  121. );
  122. result = ovrHmd_ConfigureTracking(m_hmd
  123. , 0
  124. | ovrTrackingCap_Orientation
  125. | ovrTrackingCap_MagYawCorrection
  126. | ovrTrackingCap_Position
  127. , 0
  128. );
  129. if (!result)
  130. {
  131. ovrError:
  132. BX_TRACE("Failed to initialize OVR.");
  133. ovrHmd_Destroy(m_hmd);
  134. m_hmd = NULL;
  135. return false;
  136. }
  137. ovrSizei sizeL = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmd->DefaultEyeFov[0], 1.0f);
  138. ovrSizei sizeR = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmd->DefaultEyeFov[1], 1.0f);
  139. m_rtSize.w = sizeL.w + sizeR.w;
  140. m_rtSize.h = bx::uint32_max(sizeL.h, sizeR.h);
  141. m_warning = true;
  142. return true;
  143. }
  144. void OVR::postReset(const ovrTexture& _texture)
  145. {
  146. if (NULL != m_hmd)
  147. {
  148. m_texture[0] = _texture;
  149. m_texture[1] = _texture;
  150. ovrRecti rect;
  151. rect.Pos.x = 0;
  152. rect.Pos.y = 0;
  153. rect.Size.w = m_rtSize.w/2;
  154. rect.Size.h = m_rtSize.h;
  155. m_texture[0].Header.RenderViewport = rect;
  156. rect.Pos.x += rect.Size.w;
  157. m_texture[1].Header.RenderViewport = rect;
  158. m_timing = ovrHmd_BeginFrame(m_hmd, 0);
  159. }
  160. }
  161. void OVR::preReset()
  162. {
  163. if (NULL != m_hmd)
  164. {
  165. ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
  166. ovrHmd_Destroy(m_hmd);
  167. m_hmd = NULL;
  168. }
  169. m_debug = false;
  170. }
  171. bool OVR::swap()
  172. {
  173. if (NULL == m_hmd)
  174. {
  175. return false;
  176. }
  177. ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
  178. if (m_warning)
  179. {
  180. m_warning = !ovrHmd_DismissHSWDisplay(m_hmd);
  181. }
  182. m_timing = ovrHmd_BeginFrame(m_hmd, 0);
  183. #if OVR_VERSION > OVR_VERSION_042
  184. m_pose[0] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Left);
  185. m_pose[1] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Right);
  186. #else
  187. m_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);
  188. m_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);
  189. #endif // OVR_VERSION > OVR_VERSION_042
  190. return true;
  191. }
  192. void OVR::recenter()
  193. {
  194. if (NULL != m_hmd)
  195. {
  196. ovrHmd_RecenterPose(m_hmd);
  197. }
  198. }
  199. void OVR::getEyePose(HMD& _hmd)
  200. {
  201. if (NULL != m_hmd)
  202. {
  203. ovrEyeType eye[2] = { ovrEye_Left, ovrEye_Right };
  204. for (int ii = 0; ii < 2; ++ii)
  205. {
  206. ovrPosef& pose = m_pose[ii];
  207. #if OVR_VERSION > OVR_VERSION_042
  208. pose = ovrHmd_GetHmdPosePerEye(m_hmd, eye[ii]);
  209. #else
  210. pose = ovrHmd_GetEyePose(m_hmd, eye[ii]);
  211. #endif // OVR_VERSION > OVR_VERSION_042
  212. HMD::Eye& eye = _hmd.eye[ii];
  213. eye.rotation[0] = pose.Orientation.x;
  214. eye.rotation[1] = pose.Orientation.y;
  215. eye.rotation[2] = pose.Orientation.z;
  216. eye.rotation[3] = pose.Orientation.w;
  217. eye.translation[0] = pose.Position.x;
  218. eye.translation[1] = pose.Position.y;
  219. eye.translation[2] = pose.Position.z;
  220. const ovrEyeRenderDesc& erd = m_erd[ii];
  221. eye.fov[0] = erd.Fov.UpTan;
  222. eye.fov[1] = erd.Fov.DownTan;
  223. eye.fov[2] = erd.Fov.LeftTan;
  224. eye.fov[3] = erd.Fov.RightTan;
  225. #if OVR_VERSION > OVR_VERSION_042
  226. eye.viewOffset[0] = erd.HmdToEyeViewOffset.x;
  227. eye.viewOffset[1] = erd.HmdToEyeViewOffset.y;
  228. eye.viewOffset[2] = erd.HmdToEyeViewOffset.z;
  229. #else
  230. eye.viewOffset[0] = erd.ViewAdjust.x;
  231. eye.viewOffset[1] = erd.ViewAdjust.y;
  232. eye.viewOffset[2] = erd.ViewAdjust.z;
  233. #endif // OVR_VERSION > OVR_VERSION_042
  234. eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
  235. eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
  236. }
  237. }
  238. else
  239. {
  240. for (int ii = 0; ii < 2; ++ii)
  241. {
  242. _hmd.eye[ii].rotation[0] = 0.0f;
  243. _hmd.eye[ii].rotation[1] = 0.0f;
  244. _hmd.eye[ii].rotation[2] = 0.0f;
  245. _hmd.eye[ii].rotation[3] = 1.0f;
  246. _hmd.eye[ii].translation[0] = 0.0f;
  247. _hmd.eye[ii].translation[1] = 0.0f;
  248. _hmd.eye[ii].translation[2] = 0.0f;
  249. _hmd.eye[ii].fov[0] = 1.32928634f;
  250. _hmd.eye[ii].fov[1] = 1.32928634f;
  251. _hmd.eye[ii].fov[2] = 0 == ii ? 1.05865765f : 1.09236801f;
  252. _hmd.eye[ii].fov[3] = 0 == ii ? 1.09236801f : 1.05865765f;
  253. _hmd.eye[ii].viewOffset[0] = 0 == ii ? 0.0355070010f : -0.0375000015f;
  254. _hmd.eye[ii].viewOffset[1] = 0.0f;
  255. _hmd.eye[ii].viewOffset[2] = 0 == ii ? 0.00150949787f : -0.00150949787f;
  256. _hmd.eye[ii].pixelsPerTanAngle[0] = 1;
  257. _hmd.eye[ii].pixelsPerTanAngle[1] = 1;
  258. }
  259. }
  260. _hmd.width = uint16_t(m_rtSize.w);
  261. _hmd.height = uint16_t(m_rtSize.h);
  262. }
  263. } // namespace bgfx
  264. #endif // BGFX_CONFIG_USE_OVR