hmd_ovr.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #include "hmd_ovr.h"
  6. #if BGFX_CONFIG_USE_OVR
  7. namespace bgfx
  8. {
  9. #define _OVR_CHECK(_call) \
  10. BX_MACRO_BLOCK_BEGIN \
  11. ovrResult __result__ = _call; \
  12. BX_CHECK(OVR_SUCCESS(__result__), #_call " FAILED %d", __result__); \
  13. BX_MACRO_BLOCK_END
  14. #if BGFX_CONFIG_DEBUG
  15. # define OVR_CHECK(_call) _OVR_CHECK(_call)
  16. #endif // BGFX_CONFIG_DEBUG
  17. OVR::OVR()
  18. : m_hmd(NULL)
  19. , m_enabled(false)
  20. , m_mirror(NULL)
  21. , m_frameIndex(0)
  22. , m_sensorSampleTime(0)
  23. {
  24. memset(m_eyeBuffers, 0, sizeof(m_eyeBuffers));
  25. }
  26. OVR::~OVR()
  27. {
  28. BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
  29. }
  30. void OVR::init()
  31. {
  32. ovrResult result = ovr_Initialize(NULL);
  33. if (result != ovrSuccess)
  34. {
  35. BX_TRACE("Unable to create OVR device.");
  36. return;
  37. }
  38. ovrGraphicsLuid luid;
  39. result = ovr_Create(&m_hmd, &luid);
  40. if (result != ovrSuccess)
  41. {
  42. BX_TRACE("Unable to create OVR device.");
  43. return;
  44. }
  45. m_hmdDesc = ovr_GetHmdDesc(m_hmd);
  46. BX_TRACE("HMD: %s, %s, firmware: %d.%d"
  47. , m_hmdDesc.ProductName
  48. , m_hmdDesc.Manufacturer
  49. , m_hmdDesc.FirmwareMajor
  50. , m_hmdDesc.FirmwareMinor
  51. );
  52. ovrSizei sizeL = ovr_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmdDesc.DefaultEyeFov[0], 1.0f);
  53. ovrSizei sizeR = ovr_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmdDesc.DefaultEyeFov[1], 1.0f);
  54. m_hmdSize.w = sizeL.w + sizeR.w;
  55. m_hmdSize.h = bx::uint32_max(sizeL.h, sizeR.h);
  56. }
  57. void OVR::shutdown()
  58. {
  59. BX_CHECK(!m_enabled, "HMD not disabled.");
  60. for (uint32_t ii = 0; ii < 2; ++ii)
  61. {
  62. if (NULL != m_eyeBuffers[ii])
  63. {
  64. m_eyeBuffers[ii]->destroy(m_hmd);
  65. m_eyeBuffers[ii] = NULL;
  66. }
  67. }
  68. if (NULL != m_mirror)
  69. {
  70. m_mirror->destroy(m_hmd);
  71. m_mirror = NULL;
  72. }
  73. ovr_Destroy(m_hmd);
  74. m_hmd = NULL;
  75. ovr_Shutdown();
  76. }
  77. void OVR::getViewport(uint8_t _eye, Rect* _viewport)
  78. {
  79. _viewport->m_x = 0;
  80. _viewport->m_y = 0;
  81. _viewport->m_width = m_eyeBuffers[_eye]->m_eyeTextureSize.w;
  82. _viewport->m_height = m_eyeBuffers[_eye]->m_eyeTextureSize.h;
  83. }
  84. void OVR::renderEyeStart(uint8_t _eye)
  85. {
  86. m_eyeBuffers[_eye]->render(m_hmd);
  87. }
  88. bool OVR::postReset()
  89. {
  90. if (NULL == m_hmd)
  91. {
  92. return false;
  93. }
  94. for (uint32_t ii = 0; ii < 2; ++ii)
  95. {
  96. m_erd[ii] = ovr_GetRenderDesc(m_hmd, ovrEyeType(ii), m_hmdDesc.DefaultEyeFov[ii]);
  97. }
  98. m_enabled = true;
  99. return true;
  100. }
  101. void OVR::preReset()
  102. {
  103. if (m_enabled)
  104. {
  105. // on window resize this will recreate the mirror texture in ovrPostReset
  106. m_mirror->destroy(m_hmd);
  107. m_mirror = NULL;
  108. m_enabled = false;
  109. }
  110. }
  111. OVR::Enum OVR::swap(HMD& _hmd, bool originBottomLeft)
  112. {
  113. _hmd.flags = BGFX_HMD_NONE;
  114. if (NULL != m_hmd)
  115. {
  116. _hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
  117. _hmd.deviceWidth = m_hmdDesc.Resolution.w;
  118. _hmd.deviceHeight = m_hmdDesc.Resolution.h;
  119. }
  120. if (!m_enabled)
  121. {
  122. return NotEnabled;
  123. }
  124. ovrResult result;
  125. for (uint32_t ii = 0; ii < 2; ++ii)
  126. {
  127. result = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[ii]->m_textureSwapChain);
  128. if (!OVR_SUCCESS(result) )
  129. {
  130. return DeviceLost;
  131. }
  132. }
  133. _hmd.flags |= BGFX_HMD_RENDERING;
  134. // finish frame for current eye
  135. ovrViewScaleDesc viewScaleDesc;
  136. viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
  137. viewScaleDesc.HmdToEyeOffset[0] = m_hmdToEyeOffset[0];
  138. viewScaleDesc.HmdToEyeOffset[1] = m_hmdToEyeOffset[1];
  139. // create the main eye layer
  140. ovrLayerEyeFov eyeLayer;
  141. eyeLayer.Header.Type = ovrLayerType_EyeFov;
  142. eyeLayer.Header.Flags = originBottomLeft ? ovrLayerFlag_TextureOriginAtBottomLeft : 0;
  143. for (uint32_t ii = 0; ii < 2; ++ii)
  144. {
  145. eyeLayer.ColorTexture[ii] = m_eyeBuffers[ii]->m_textureSwapChain;
  146. eyeLayer.Viewport[ii].Pos.x = 0;
  147. eyeLayer.Viewport[ii].Pos.y = 0;
  148. eyeLayer.Viewport[ii].Size.w = m_eyeBuffers[ii]->m_eyeTextureSize.w;
  149. eyeLayer.Viewport[ii].Size.h = m_eyeBuffers[ii]->m_eyeTextureSize.h;
  150. eyeLayer.Fov[ii] = m_hmdDesc.DefaultEyeFov[ii];
  151. eyeLayer.RenderPose[ii] = m_pose[ii];
  152. eyeLayer.SensorSampleTime = m_sensorSampleTime;
  153. }
  154. // append all the layers to global list
  155. ovrLayerHeader* layerList = &eyeLayer.Header;
  156. result = ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
  157. if (!OVR_SUCCESS(result) )
  158. {
  159. return DeviceLost;
  160. }
  161. // perform mirror texture blit right after the entire frame is submitted to HMD
  162. m_mirror->blit(m_hmd);
  163. m_hmdToEyeOffset[0] = m_erd[0].HmdToEyeOffset;
  164. m_hmdToEyeOffset[1] = m_erd[1].HmdToEyeOffset;
  165. ovr_GetEyePoses(m_hmd, m_frameIndex, ovrTrue, m_hmdToEyeOffset, m_pose, &m_sensorSampleTime);
  166. getEyePose(_hmd);
  167. return Success;
  168. }
  169. void OVR::recenter()
  170. {
  171. if (NULL != m_hmd)
  172. {
  173. OVR_CHECK(ovr_RecenterTrackingOrigin(m_hmd) );
  174. }
  175. }
  176. void OVR::getEyePose(HMD& _hmd)
  177. {
  178. if (NULL != m_hmd)
  179. {
  180. for (uint32_t ii = 0; ii < 2; ++ii)
  181. {
  182. const ovrPosef& pose = m_pose[ii];
  183. HMD::Eye& eye = _hmd.eye[ii];
  184. eye.rotation[0] = pose.Orientation.x;
  185. eye.rotation[1] = pose.Orientation.y;
  186. eye.rotation[2] = pose.Orientation.z;
  187. eye.rotation[3] = pose.Orientation.w;
  188. eye.translation[0] = pose.Position.x;
  189. eye.translation[1] = pose.Position.y;
  190. eye.translation[2] = pose.Position.z;
  191. const ovrEyeRenderDesc& erd = m_erd[ii];
  192. eye.fov[0] = erd.Fov.UpTan;
  193. eye.fov[1] = erd.Fov.DownTan;
  194. eye.fov[2] = erd.Fov.LeftTan;
  195. eye.fov[3] = erd.Fov.RightTan;
  196. ovrMatrix4f eyeProj = ovrMatrix4f_Projection(m_erd[ii].Fov, 0.01f, 1000.0f, ovrProjection_LeftHanded);
  197. for (uint32_t jj = 0; jj < 4; ++jj)
  198. {
  199. for (uint32_t kk = 0; kk < 4; ++kk)
  200. {
  201. eye.projection[4 * jj + kk] = eyeProj.M[kk][jj];
  202. }
  203. }
  204. eye.viewOffset[0] = erd.HmdToEyeOffset.x;
  205. eye.viewOffset[1] = erd.HmdToEyeOffset.y;
  206. eye.viewOffset[2] = erd.HmdToEyeOffset.z;
  207. eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
  208. eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
  209. }
  210. }
  211. _hmd.width = uint16_t(m_hmdSize.w);
  212. _hmd.height = uint16_t(m_hmdSize.h);
  213. }
  214. } // namespace bgfx
  215. #endif // BGFX_CONFIG_USE_OVR