| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /*
- * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
- */
- #include "ovr.h"
- #if BGFX_CONFIG_USE_OVR
- namespace bgfx
- {
- OVR::OVR()
- : m_hmd(NULL)
- , m_isenabled(false)
- , m_mirror(NULL)
- , m_hmdFrameReady(-1)
- , m_frameIndex(0)
- , m_sensorSampleTime(0)
- {
- memset(m_eyeBuffers, 0, sizeof(m_eyeBuffers));
- }
- OVR::~OVR()
- {
- BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
- }
- void OVR::init()
- {
- ovrResult initialized = ovr_Initialize(NULL);
- ovrGraphicsLuid luid;
- BX_WARN(initialized == ovrSuccess, "Unable to create OVR device.");
-
- if (initialized != ovrSuccess)
- {
- return;
- }
- initialized = ovr_Create(&m_hmd, &luid);
- if (initialized != ovrSuccess)
- {
- BX_WARN(initialized == ovrSuccess, "Unable to create OVR device.");
- return;
- }
- m_hmdDesc = ovr_GetHmdDesc(m_hmd);
- BX_TRACE("HMD: %s, %s, firmware: %d.%d"
- , m_hmdDesc.ProductName
- , m_hmdDesc.Manufacturer
- , m_hmdDesc.FirmwareMajor
- , m_hmdDesc.FirmwareMinor
- );
- ovrSizei sizeL = ovr_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmdDesc.DefaultEyeFov[0], 1.0f);
- ovrSizei sizeR = ovr_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmdDesc.DefaultEyeFov[1], 1.0f);
- m_hmdSize.w = sizeL.w + sizeR.w;
- m_hmdSize.h = bx::uint32_max(sizeL.h, sizeR.h);
- }
- void OVR::shutdown()
- {
- BX_CHECK(!m_isenabled, "HMD not disabled.");
- for (int i = 0; i < 2; i++)
- {
- if (m_eyeBuffers[i])
- {
- m_eyeBuffers[i]->destroy(m_hmd);
- BX_DELETE(g_allocator, m_eyeBuffers[i]);
- }
- }
- if (m_mirror)
- {
- m_mirror->destroy(m_hmd);
- BX_DELETE(g_allocator, m_mirror);
- }
- ovr_Destroy(m_hmd);
- m_hmd = NULL;
- ovr_Shutdown();
- }
- void OVR::getViewport(uint8_t _eye, Rect* _viewport)
- {
- _viewport->m_x = 0;
- _viewport->m_y = 0;
- _viewport->m_width = m_eyeBuffers[_eye]->m_eyeTextureSize.w;
- _viewport->m_height = m_eyeBuffers[_eye]->m_eyeTextureSize.h;
- }
- void OVR::renderEyeStart(uint8_t _eye)
- {
- m_eyeBuffers[_eye]->onRender(m_hmd);
- }
- bool OVR::postReset()
- {
- if (NULL == m_hmd)
- {
- return false;
- }
- for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
- {
- m_erd[eyeIdx] = ovr_GetRenderDesc(m_hmd, (ovrEyeType)eyeIdx, m_hmdDesc.DefaultEyeFov[eyeIdx]);
- }
- m_isenabled = true;
- return true;
- }
- void OVR::preReset()
- {
- if (m_isenabled)
- {
- // on window resize this will recreate the mirror texture in ovrPostReset
- m_mirror->destroy(m_hmd);
- BX_DELETE(g_allocator, m_mirror);
- m_mirror = NULL;
- m_isenabled = false;
- }
- }
- void OVR::commitEye(uint8_t _eye)
- {
- if (m_isenabled)
- {
- m_hmdFrameReady = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[_eye]->m_swapTextureChain);
- }
- }
- bool OVR::swap(HMD& _hmd, bool originBottomLeft)
- {
- _hmd.flags = BGFX_HMD_NONE;
- if (NULL != m_hmd)
- {
- _hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
- _hmd.deviceWidth = m_hmdDesc.Resolution.w;
- _hmd.deviceHeight = m_hmdDesc.Resolution.h;
- }
- if (!m_isenabled || !OVR_SUCCESS(m_hmdFrameReady))
- {
- return false;
- }
- _hmd.flags |= BGFX_HMD_RENDERING;
- // finish frame for current eye
- ovrViewScaleDesc viewScaleDesc;
- viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
- viewScaleDesc.HmdToEyeOffset[0] = m_hmdToEyeOffset[0];
- viewScaleDesc.HmdToEyeOffset[1] = m_hmdToEyeOffset[1];
- // create the main eye layer
- ovrLayerEyeFov eyeLayer;
- eyeLayer.Header.Type = ovrLayerType_EyeFov;
- eyeLayer.Header.Flags = originBottomLeft ? ovrLayerFlag_TextureOriginAtBottomLeft : 0;
- for (int eye = 0; eye < ovrEye_Count; eye++)
- {
- eyeLayer.ColorTexture[eye] = m_eyeBuffers[eye]->m_swapTextureChain;
- eyeLayer.Viewport[eye].Pos.x = 0;
- eyeLayer.Viewport[eye].Pos.y = 0;
- eyeLayer.Viewport[eye].Size.w = m_eyeBuffers[eye]->m_eyeTextureSize.w;
- eyeLayer.Viewport[eye].Size.h = m_eyeBuffers[eye]->m_eyeTextureSize.h;
- eyeLayer.Fov[eye] = m_hmdDesc.DefaultEyeFov[eye];
- eyeLayer.RenderPose[eye] = m_pose[eye];
- eyeLayer.SensorSampleTime = m_sensorSampleTime;
- }
- // append all the layers to global list
- ovrLayerHeader* layerList = &eyeLayer.Header;
- ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
- // perform mirror texture blit right after the entire frame is submitted to HMD
- m_mirror->blit(m_hmd);
- m_hmdToEyeOffset[0] = m_erd[0].HmdToEyeOffset;
- m_hmdToEyeOffset[1] = m_erd[1].HmdToEyeOffset;
- ovr_GetEyePoses(m_hmd, m_frameIndex, ovrTrue, m_hmdToEyeOffset, m_pose, &m_sensorSampleTime);
- getEyePose(_hmd);
- return true;
- }
- void OVR::recenter()
- {
- if (NULL != m_hmd)
- {
- ovr_RecenterTrackingOrigin(m_hmd);
- }
- }
- void OVR::getEyePose(HMD& _hmd)
- {
- if (NULL != m_hmd)
- {
- for (int ii = 0; ii < 2; ++ii)
- {
- const ovrPosef& pose = m_pose[ii];
- 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;
- ovrMatrix4f eyeProj = ovrMatrix4f_Projection(m_erd[ii].Fov, 0.01f, 1000.0f, ovrProjection_LeftHanded);
- for (int jj = 0; jj < 4; ++jj)
- {
- for (int kk = 0; kk < 4; ++kk)
- {
- eye.projection[4 * jj + kk] = eyeProj.M[kk][jj];
- }
- }
- eye.viewOffset[0] = erd.HmdToEyeOffset.x;
- eye.viewOffset[1] = erd.HmdToEyeOffset.y;
- eye.viewOffset[2] = erd.HmdToEyeOffset.z;
- eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
- eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
- }
- }
- _hmd.width = uint16_t(m_hmdSize.w);
- _hmd.height = uint16_t(m_hmdSize.h);
- }
- } // namespace bgfx
- #endif // BGFX_CONFIG_USE_OVR
|