hmd_ovr.cpp 6.1 KB

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