ovr.cpp 5.8 KB

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