XMFLOAT4 Weapon::GetWeaponOffsetRotation() { XMVECTOR quat = XMQuaternionIdentity(); XMFLOAT3 direction = GetFloat3Value( Direction ); XMFLOAT3 aimPos; XMFLOAT3 pipePos; if (GetJointPosition("PipeAim", aimPos) && GetJointPosition("Pipe", pipePos)) { //handPos.y = pipePos.y; XMVECTOR directionV = XMLoadFloat3(&direction); XMVECTOR handPosV = XMLoadFloat3(&aimPos); XMVECTOR pipePosV = XMLoadFloat3(&pipePos); XMVECTOR offsetDirectionV = pipePosV - handPosV; XMVECTOR angleV = XMVector3AngleBetweenVectors(directionV, offsetDirectionV); float angle; XMStoreFloat(&angle, angleV); if (angle != 0) { XMVECTOR axis = XMVector3Cross(directionV, offsetDirectionV); quat = XMQuaternionRotationAxis(axis, angle); } } XMFLOAT4 result; XMStoreFloat4(&result, quat); return result; }
ModelLightingClass::ModelLightingClass(string barName, bool p_quad, const XMFLOAT3 & postion):Entity(), Position(postion), Rotation(0.0f, 0.0f, 0.0f), Scale(1.0f, 1.0f, 1.0f), Quaternion(XMQuaternionIdentity()) { m_vertexBuffer = 0; m_indexBuffer = 0; m_model = 0; m_bar = TwNewBar(barName.c_str()); string define = barName + " iconified=true alpha=200"; string group = barName + "/Rotation opened = false"; TwDefine(define.c_str()); TwAddVarRW(m_bar, "XRotation", TW_TYPE_FLOAT, &Rotation.x, " step=0.01 group=Rotation"); TwAddVarRW(m_bar, "YRotation", TW_TYPE_FLOAT, &Rotation.y, " step=0.01 group=Rotation"); TwAddVarRW(m_bar, "ZRotation", TW_TYPE_FLOAT, &Rotation.z, "min=0 max=6.28 step=0.01 group=Rotation"); TwDefine(group.c_str()); TwAddVarRW(m_bar, "XPosition", TW_TYPE_FLOAT, &Position.x, " step=0.1 group=Position"); TwAddVarRW(m_bar, "YPosition", TW_TYPE_FLOAT, &Position.y, " step=0.1 group=Position"); TwAddVarRW(m_bar, "ZPosition", TW_TYPE_FLOAT, &Position.z, " step=0.1 group=Position"); group = barName + "/Position opened = false"; TwDefine(group.c_str()); TwAddVarRW(m_bar, "XScale", TW_TYPE_FLOAT, &Scale.x, " step=0.01 group=Scale"); TwAddVarRW(m_bar, "YScale", TW_TYPE_FLOAT, &Scale.y, " step=0.01 group=Scale"); TwAddVarRW(m_bar, "ZScale", TW_TYPE_FLOAT, &Scale.z, " step=0.01 group=Scale"); group = barName + "/Scale opened = false"; TwDefine(group.c_str()); }
void GameEntity::init() { _scale = XMFLOAT4(1.0f, 1.0f, 1.0f, 0.0f); XMStoreFloat4(&_rotation, XMQuaternionIdentity()); _position = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f); _layer = 1; _color = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); }
void AaEntity::resetRotation() { dirtyWM=true; *quaternion = XMQuaternionIdentity(); if(hasPhysics) body->setGlobalPose(physx::PxTransform(body->getGlobalPose().p,physx::PxQuat::createIdentity())); }
void BoneModel::createBone(){ auto& bones = mBoneAssetDataPtr->GetFileData().GetBoneData().mBoneBuffer; auto& boneName = mBoneAssetDataPtr->GetFileData().GetBoneData().mBoneName; DWORD mBoneNum = bones.size(); mBone.clear(); mIk.clear(); mBone.resize(mBoneNum); DWORD ikCount = 0; for (DWORD i = 0; i < mBoneNum; i++){ auto& bone = bones[i]; mBone[i].mStrName = boneName[i]; mBone[i].mHierarchy.mIdxSelf = i; mBone[i].mHierarchy.mIdxParent = bone.parent_bidx; if (bone.parent_bidx >= (int)mBoneNum) mBone[i].mHierarchy.mIdxParent = UINT(-1); XMVECTOR head_pos = XMVectorSet(bone.bone_head_pos[0], bone.bone_head_pos[1], bone.bone_head_pos[2], 0.0f); XMVECTOR parent_pos = { 0, 0, 0, 1 }; if (mBone[i].mHierarchy.mIdxParent < (int)mBoneNum){ UINT p = mBone[i].mHierarchy.mIdxParent; parent_pos = XMVectorSet(bones[p].bone_head_pos[0], bones[p].bone_head_pos[1], bones[p].bone_head_pos[2], 0.0f); } XMVECTOR local_pos = XMVectorSubtract(head_pos, parent_pos); mBone[i].mPos = XMFLOAT3(XMVectorGetX(local_pos), XMVectorGetY(local_pos), XMVectorGetZ(local_pos)); mBone[i].mScale = XMFLOAT3(1.0f, 1.0f, 1.0f); XMVECTOR q = XMQuaternionIdentity(); mBone[i].mRot = XMFLOAT4(XMVectorGetX(q), XMVectorGetY(q), XMVectorGetZ(q), XMVectorGetW(q)); //ワールド行列計算 XMVECTOR scale = { 1, 1, 1, 1 }; mBone[i].mMtxPose = SRTMatrix(scale, q, local_pos); if (mBone[i].mHierarchy.mIdxParent < (int)mBoneNum){ mBone[i].mMtxPose = XMMatrixMultiply(mBone[i].mMtxPose, mBone[mBone[i].mHierarchy.mIdxParent].mMtxPose); } if (bone.bone_flag & pmx::t_bone::BIT_IK){ mBone[i].mIkBoneIdx = (WORD)bone.t_ik_data_idx; createIk(ikCount, i); ikCount++; } else{ mBone[i].mIkBoneIdx = 0; } mBone[i].mMtxPoseInit = mBone[i].mMtxPose; } }
void XM_CALLCONV PrimitveDrawer::DrawCylinder(FXMVECTOR P1, FXMVECTOR P2, float radius, FXMVECTOR Color) { auto center = 0.5f * XMVectorAdd(P1, P2); auto dir = XMVectorSubtract(P1, P2); auto scale = XMVector3Length(dir); scale = XMVectorSet(radius, XMVectorGetX(scale), radius, 1.0f); XMVECTOR rot; if (XMVector4Equal(dir, g_XMZero)) rot = XMQuaternionIdentity(); else rot = XMQuaternionRotationVectorToVector(g_XMIdentityR1, dir); XMMATRIX world = XMMatrixAffineTransformation(scale, g_XMZero, rot, center); m_pCylinder->Draw(world, ViewMatrix, ProjectionMatrix, Color); }
XMVECTOR HydraManager::getRotation(int controllerIndex) const { if (sixenseIsControllerEnabled(controllerIndex)) { XMVECTOR axis; float angle; XMQuaternionToAxisAngle(&axis, &angle, XMLoadFloat4(&XMFLOAT4(&mAcd.controllers[controllerIndex].rot_quat[0]))); axis = XMVectorSet(-XMVectorGetX(axis), XMVectorGetY(axis), -XMVectorGetZ(axis), 0.0f); XMVECTOR rotationQuat = XMQuaternionRotationAxis(axis, angle); return rotationQuat; } return XMQuaternionIdentity(); }
bool Skeleton::LoadFromFile(const char * filename) { bool ret = false; const Vector3 scaling(1, 1, 1); buffer buff; CHECK(LoadBinaryFile(buff, filename)); const char* data = (const char*)buff.ptr(); SkeletonFile::Head* head = (SkeletonFile::Head*)data; data += sizeof(SkeletonFile::Head); mBoneCount = head->boneCount; mInverseTMs.resize(mBoneCount); for (size_t i = 0; i < mBoneCount; ++i) { const char* name = (const char*)data; data += sizeof(char) * SkeletonFile::MaxBoneName; mBoneNames.insert(std::make_pair(name, i)); const Vector3& pos = *(const Vector3*)data; data += sizeof(Vector3); const Quat& rot = *(const Quat*)data; data += sizeof(Quat); XMVECTOR p = XMLoadFloat3((const XMFLOAT3*)&pos); XMVECTOR q = XMLoadFloat4((const XMFLOAT4*)&rot); XMVECTOR s = XMLoadFloat3((const XMFLOAT3*)&scaling); XMMATRIX m = XMMatrixAffineTransformation(s, XMQuaternionIdentity(), q, p); m = XMMatrixInverse(nullptr, m); XMStoreFloat4x4((XMFLOAT4X4*)&mInverseTMs[i], m); } ret = true; Exit0: return ret; }
// return true to retry later (e.g. after display lost) static bool MainLoop(bool retryCreate) { // Initialize these to nullptr here to handle device lost failures cleanly ovrMirrorTexture mirrorTexture = nullptr; OculusEyeTexture* pEyeRenderTexture[2] = { nullptr, nullptr }; Scene* roomScene = nullptr; Camera* mainCam = nullptr; ovrMirrorTextureDesc mirrorDesc = {}; ovrSession session; ovrGraphicsLuid luid; ovrResult result = ovr_Create(&session, &luid); if (!OVR_SUCCESS(result)) return retryCreate; ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); // Setup Device and Graphics // Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution if (!DIRECTX.InitDevice(hmdDesc.Resolution.w / 2, hmdDesc.Resolution.h / 2, reinterpret_cast<LUID*>(&luid))) goto Done; // Make the eye render buffers (caution if actual size < requested due to HW limits). ovrRecti eyeRenderViewport[2]; for (int eye = 0; eye < 2; ++eye) { ovrSizei idealSize = ovr_GetFovTextureSize(session, (ovrEyeType)eye, hmdDesc.DefaultEyeFov[eye], 1.0f); pEyeRenderTexture[eye] = new OculusEyeTexture(); if (!pEyeRenderTexture[eye]->Init(session, idealSize.w, idealSize.h, true)) { if (retryCreate) goto Done; FATALERROR("Failed to create eye texture."); } eyeRenderViewport[eye].Pos.x = 0; eyeRenderViewport[eye].Pos.y = 0; eyeRenderViewport[eye].Size = idealSize; if (!pEyeRenderTexture[eye]->TextureChain) { if (retryCreate) goto Done; FATALERROR("Failed to create texture."); } } // Create a mirror to see on the monitor. mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; mirrorDesc.Width = DIRECTX.WinSizeW; mirrorDesc.Height = DIRECTX.WinSizeH; result = ovr_CreateMirrorTextureDX(session, DIRECTX.CommandQueue, &mirrorDesc, &mirrorTexture); if (!OVR_SUCCESS(result)) { if (retryCreate) goto Done; FATALERROR("Failed to create mirror texture."); } // Create the room model roomScene = new Scene(false); // Create camera mainCam = new Camera(XMVectorSet(0.0f, 1.6f, 5.0f, 0), XMQuaternionIdentity()); // Setup VR components, filling out description ovrEyeRenderDesc eyeRenderDesc[2]; eyeRenderDesc[0] = ovr_GetRenderDesc(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0]); eyeRenderDesc[1] = ovr_GetRenderDesc(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1]); long long frameIndex = 0; bool drawMirror = true; DIRECTX.InitFrame(drawMirror); // Main loop while (DIRECTX.HandleMessages()) { ovrSessionStatus sessionStatus; ovr_GetSessionStatus(session, &sessionStatus); if (sessionStatus.ShouldQuit) { // Because the application is requested to quit, should not request retry retryCreate = false; break; } if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); if (sessionStatus.IsVisible) { XMVECTOR forward = XMVector3Rotate(XMVectorSet(0, 0, -0.05f, 0), mainCam->GetRotVec()); XMVECTOR right = XMVector3Rotate(XMVectorSet(0.05f, 0, 0, 0), mainCam->GetRotVec()); XMVECTOR mainCamPos = mainCam->GetPosVec(); XMVECTOR mainCamRot = mainCam->GetRotVec(); if (DIRECTX.Key['W'] || DIRECTX.Key[VK_UP]) mainCamPos = XMVectorAdd( mainCamPos, forward); if (DIRECTX.Key['S'] || DIRECTX.Key[VK_DOWN]) mainCamPos = XMVectorSubtract(mainCamPos, forward); if (DIRECTX.Key['D']) mainCamPos = XMVectorAdd( mainCamPos, right); if (DIRECTX.Key['A']) mainCamPos = XMVectorSubtract(mainCamPos, right); static float Yaw = 0; if (DIRECTX.Key[VK_LEFT]) mainCamRot = XMQuaternionRotationRollPitchYaw(0, Yaw += 0.02f, 0); if (DIRECTX.Key[VK_RIGHT]) mainCamRot = XMQuaternionRotationRollPitchYaw(0, Yaw -= 0.02f, 0); mainCam->SetPosVec(mainCamPos); mainCam->SetRotVec(mainCamRot); // Animate the cube static float cubeClock = 0; roomScene->Models[0]->Pos = XMFLOAT3(9 * sin(cubeClock), 3, 9 * cos(cubeClock += 0.015f)); // Get both eye poses simultaneously, with IPD offset already included. ovrPosef EyeRenderPose[2]; ovrVector3f HmdToEyeOffset[2] = { eyeRenderDesc[0].HmdToEyeOffset, eyeRenderDesc[1].HmdToEyeOffset }; double sensorSampleTime; // sensorSampleTime is fed into the layer later ovr_GetEyePoses(session, frameIndex, ovrTrue, HmdToEyeOffset, EyeRenderPose, &sensorSampleTime); // Render Scene to Eye Buffers for (int eye = 0; eye < 2; ++eye) { DIRECTX.SetActiveContext(eye == 0 ? DrawContext_EyeRenderLeft : DrawContext_EyeRenderRight); DIRECTX.SetActiveEye(eye); CD3DX12_RESOURCE_BARRIER resBar = CD3DX12_RESOURCE_BARRIER::Transition(pEyeRenderTexture[eye]->GetD3DResource(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); DIRECTX.CurrentFrameResources().CommandLists[DIRECTX.ActiveContext]->ResourceBarrier(1, &resBar); DIRECTX.SetAndClearRenderTarget(pEyeRenderTexture[eye]->GetRtv(), pEyeRenderTexture[eye]->GetDsv()); DIRECTX.SetViewport((float)eyeRenderViewport[eye].Pos.x, (float)eyeRenderViewport[eye].Pos.y, (float)eyeRenderViewport[eye].Size.w, (float)eyeRenderViewport[eye].Size.h); //Get the pose information in XM format XMVECTOR eyeQuat = XMVectorSet(EyeRenderPose[eye].Orientation.x, EyeRenderPose[eye].Orientation.y, EyeRenderPose[eye].Orientation.z, EyeRenderPose[eye].Orientation.w); XMVECTOR eyePos = XMVectorSet(EyeRenderPose[eye].Position.x, EyeRenderPose[eye].Position.y, EyeRenderPose[eye].Position.z, 0); // Get view and projection matrices for the Rift camera Camera finalCam(XMVectorAdd(mainCamPos, XMVector3Rotate(eyePos, mainCamRot)), XMQuaternionMultiply(eyeQuat, mainCamRot)); XMMATRIX view = finalCam.GetViewMatrix(); ovrMatrix4f p = ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.2f, 1000.0f, ovrProjection_None); XMMATRIX proj = XMMatrixSet(p.M[0][0], p.M[1][0], p.M[2][0], p.M[3][0], p.M[0][1], p.M[1][1], p.M[2][1], p.M[3][1], p.M[0][2], p.M[1][2], p.M[2][2], p.M[3][2], p.M[0][3], p.M[1][3], p.M[2][3], p.M[3][3]); XMMATRIX prod = XMMatrixMultiply(view, proj); roomScene->Render(&prod, 1, 1, 1, 1, true); resBar = CD3DX12_RESOURCE_BARRIER::Transition(pEyeRenderTexture[eye]->GetD3DResource(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); DIRECTX.CurrentFrameResources().CommandLists[DIRECTX.ActiveContext]->ResourceBarrier(1, &resBar); // Commit rendering to the swap chain pEyeRenderTexture[eye]->Commit(); // kick off eye render command lists before ovr_SubmitFrame() DIRECTX.SubmitCommandList(DIRECTX.ActiveContext); } // Initialize our single full screen Fov layer. ovrLayerEyeFov ld = {}; ld.Header.Type = ovrLayerType_EyeFov; ld.Header.Flags = 0; for (int eye = 0; eye < 2; ++eye) { ld.ColorTexture[eye] = pEyeRenderTexture[eye]->TextureChain; ld.Viewport[eye] = eyeRenderViewport[eye]; ld.Fov[eye] = hmdDesc.DefaultEyeFov[eye]; ld.RenderPose[eye] = EyeRenderPose[eye]; ld.SensorSampleTime = sensorSampleTime; } ovrLayerHeader* layers = &ld.Header; result = ovr_SubmitFrame(session, frameIndex, nullptr, &layers, 1); // exit the rendering loop if submit returns an error, will retry on ovrError_DisplayLost if (!OVR_SUCCESS(result)) goto Done; frameIndex++; } if (drawMirror) { DIRECTX.SetActiveContext(DrawContext_Final); DIRECTX.SetViewport(0.0f, 0.0f, (float)hmdDesc.Resolution.w / 2, (float)hmdDesc.Resolution.h / 2); // Render mirror ID3D12Resource* mirrorTexRes = nullptr; ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&mirrorTexRes)); //DIRECTX.SetAndClearRenderTarget(DIRECTX.CurrentFrameResources().SwapChainRtvHandle, nullptr, 1.0f, 0.5f, 0.0f, 1.0f); CD3DX12_RESOURCE_BARRIER preMirrorBlitBar[] = { CD3DX12_RESOURCE_BARRIER::Transition(DIRECTX.CurrentFrameResources().SwapChainBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_DEST), CD3DX12_RESOURCE_BARRIER::Transition(mirrorTexRes, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE) }; // Indicate that the back buffer will now be copied into DIRECTX.CurrentFrameResources().CommandLists[DIRECTX.ActiveContext]->ResourceBarrier(ARRAYSIZE(preMirrorBlitBar), preMirrorBlitBar); DIRECTX.CurrentFrameResources().CommandLists[DIRECTX.ActiveContext]->CopyResource(DIRECTX.CurrentFrameResources().SwapChainBuffer, mirrorTexRes); CD3DX12_RESOURCE_BARRIER resBar = CD3DX12_RESOURCE_BARRIER::Transition(mirrorTexRes, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); DIRECTX.CurrentFrameResources().CommandLists[DIRECTX.ActiveContext]->ResourceBarrier(1, &resBar); } DIRECTX.SubmitCommandListAndPresent(drawMirror); } // Release resources Done: delete mainCam; delete roomScene; if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture); for (int eye = 0; eye < 2; ++eye) { delete pEyeRenderTexture[eye]; } DIRECTX.ReleaseDevice(); ovr_Destroy(session); // Retry on ovrError_DisplayLost return retryCreate || (result == ovrError_DisplayLost); }
void BasicPlane::Update(float deltaTime) { XMVECTOR forward = XMVector3Rotate(XMVectorSet(0, 0, 1, 0), XMLoadFloat4(&gameObject->transform.rotation)); XMVECTOR right = XMVector3Rotate(XMVectorSet(1, 0, 0, 0), XMLoadFloat4(&gameObject->transform.rotation)); XMVECTOR up = XMVector3Rotate(XMVectorSet(0, 1, 0, 0), XMLoadFloat4(&gameObject->transform.rotation)); Vector3 velocityDirection = particleModel->velocity; velocityDirection.Normalize(); Vector3 velocityForwards = forward * particleModel->velocity.Dot(forward); //thrust const float maxPlaneThrust = 30 * particleModel->mass; const float thrustChangeSpeed = 5 * particleModel->mass; static float planeThrust = maxPlaneThrust * 0.0; if (GetAsyncKeyState(VK_HOME)) { planeThrust += thrustChangeSpeed * deltaTime; } if (GetAsyncKeyState(VK_DELETE)) { planeThrust -= thrustChangeSpeed * deltaTime; } planeThrust = fmax(0.0f, fmin(maxPlaneThrust, planeThrust)); particleModel->AddForce(forward * planeThrust); //lift and drag float lift; float percentVelocityForwards = particleModel->velocity.Length() < 1e-4 ? 0 : (velocityForwards.Length() / particleModel->velocity.Length()); lift = 100 * particleModel->velocity.LengthSquared() * (percentVelocityForwards); if (planeThrust > 0.25 * maxPlaneThrust) { planeThrust -= thrustChangeSpeed * 0.5 * deltaTime; } //float density = 0.5; //float area = 10; //float liftCoefficient = 0.8f; //lift = 0.5 * density * particleModel->velocity.LengthSquared() * area * liftCoefficient; particleModel->AddForce(up * lift); float drag; drag = 300 * particleModel->velocity.LengthSquared() * (percentVelocityForwards * 0.2 + (1.0 - percentVelocityForwards) * 1.0); //float dragCoefficient = 0.1f; //drag = dragCoefficient * area * density * (particleModel->velocity.LengthSquared() / 2); particleModel->AddForce(-velocityDirection * drag); //rotate const float planeRotateSpeed = XMConvertToRadians(20 * deltaTime); XMVECTOR rotate = XMQuaternionIdentity(); if (GetAsyncKeyState(VK_RIGHT)) { rotate = XMQuaternionMultiply(rotate, XMQuaternionRotationNormal(forward, -planeRotateSpeed)); } else if (GetAsyncKeyState(VK_LEFT)) { rotate = XMQuaternionMultiply(rotate, XMQuaternionRotationNormal(forward, planeRotateSpeed)); } if (GetAsyncKeyState(VK_UP)) { rotate = XMQuaternionMultiply(rotate, XMQuaternionRotationNormal(right, -planeRotateSpeed)); } else if (GetAsyncKeyState(VK_DOWN)) { rotate = XMQuaternionMultiply(rotate, XMQuaternionRotationNormal(right, planeRotateSpeed)); } gameObject->transform.rotation *= rotate; }
void Player::Update(float time) { m_MoveBackForward = 0.0f; m_MoveLeftRight = 0.0f; m_MoveUpDown = 0.0f; m_Yaw = 0.0f; if (m_Input->IsPressed(INPUT_UP)) m_MoveBackForward += (speed * time); if (m_Input->IsPressed(INPUT_DOWN)) m_MoveBackForward -= (speed * time); if (m_Input->IsPressed(INPUT_RIGHT)) { m_MoveLeftRight -= (speed * time); } if (m_Input->IsPressed(INPUT_LEFT)) { m_MoveLeftRight += (speed * time); } if (m_Input->IsPressed(INPUT_RAISE)) { m_MoveUpDown += (speed * time); } if (m_Input->IsPressed(INPUT_LOWER)) { m_MoveUpDown -= (speed * time); } if (m_Input->IsPressed(INPUT_ROTATELEFT)) { //m_Yaw += (speed * time); m_FacingVector.z += (0.01f * time); } if (m_Input->IsPressed(INPUT_ROTATERIGHT)) { //m_Yaw -= (speed * time); m_FacingVector.z -= (0.01f * time); } m_MouseDelta = m_Input->GetMouseDelta(); m_Position.x += m_MoveBackForward; m_Position.z += m_MoveLeftRight; m_Position.y += m_MoveUpDown; //m_Yaw += m_MouseDelta.x * (time * speed); //m_Pitch += m_MouseDelta.y * (time * speed); XMVECTOR posss = XMVECTOR{ 1.0f,1.0f,1.0f }; XMVECTOR tt = XMQuaternionIdentity(); //XMVECTOR test = XMLoadFloat3(&m_FacingVector); //XMVector3Rotate() //XMMATRIX TEMPER = XMMatrixRotationRollPitchYaw(XMConvertToRadians( m_Yaw*time*speed), XMConvertToRadians(m_Yaw*time*speed), XMConvertToRadians(m_Yaw*time*speed)); //XMVector3Transform(test, TEMPER); ////XMVector3Normalize(test); //XMStoreFloat3(&m_FacingVector, test); }
D3DCamera::D3DCamera() { m_position = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); m_rotation = XMQuaternionIdentity(); }
// return true to retry later (e.g. after display lost) static bool MainLoop(bool retryCreate) { // Initialize these to nullptr here to handle device lost failures cleanly ovrTexture * mirrorTexture = nullptr; OculusTexture * pEyeRenderTexture[2] = { nullptr, nullptr }; DepthBuffer * pEyeDepthBuffer[2] = { nullptr, nullptr }; Scene * roomScene = nullptr; Camera * mainCam = nullptr; D3D11_TEXTURE2D_DESC td = {}; ovrHmd HMD; ovrGraphicsLuid luid; ovrResult result = ovr_Create(&HMD, &luid); if (!OVR_SUCCESS(result)) return retryCreate; ovrHmdDesc hmdDesc = ovr_GetHmdDesc(HMD); // ------------------------------------------------------------------- // Add: Make Instance that CL Eye Camera Capture Class CLEyeCameraCapture* cam[2] = { NULL }; // Query for number of connected camera int numCams = CLEyeGetCameraCount(); if (numCams == 0) { printf_s("No PS3Eye Camera detected\n"); goto Done; } printf_s("Found %d cameras\n", numCams); for (int iCam = 0; iCam < numCams; iCam++) { char windowName[64]; // Query unique camera uuid GUID guid = CLEyeGetCameraUUID(iCam); printf("Camera %d GUID: [%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x]\n", iCam + 1, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); sprintf_s(windowName, "Camera Window %d", iCam + 1); // Create camera capture object cam[iCam] = new CLEyeCameraCapture(windowName, guid, CLEYE_COLOR_RAW, CLEYE_VGA, 30); cam[iCam]->StartCapture(); } // ------------------------------------------------------------------- // Setup Device and Graphics // Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution if (!DIRECTX.InitDevice(hmdDesc.Resolution.w / 2, hmdDesc.Resolution.h / 2, reinterpret_cast<LUID*>(&luid))) goto Done; // Make the eye render buffers (caution if actual size < requested due to HW limits). ovrRecti eyeRenderViewport[2]; for (int eye = 0; eye < 2; ++eye) { ovrSizei idealSize = ovr_GetFovTextureSize(HMD, (ovrEyeType)eye, hmdDesc.DefaultEyeFov[eye], 1.0f); pEyeRenderTexture[eye] = new OculusTexture(); if (!pEyeRenderTexture[eye]->Init(HMD, idealSize.w, idealSize.h)) { if (retryCreate) goto Done; VALIDATE(OVR_SUCCESS(result), "Failed to create eye texture."); } pEyeDepthBuffer[eye] = new DepthBuffer(DIRECTX.Device, idealSize.w, idealSize.h); eyeRenderViewport[eye].Pos.x = 0; eyeRenderViewport[eye].Pos.y = 0; eyeRenderViewport[eye].Size = idealSize; if (!pEyeRenderTexture[eye]->TextureSet) { if (retryCreate) goto Done; VALIDATE(false, "Failed to create texture."); } } // Create a mirror to see on the monitor. td.ArraySize = 1; td.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; td.Width = DIRECTX.WinSizeW; td.Height = DIRECTX.WinSizeH; td.Usage = D3D11_USAGE_DEFAULT; td.SampleDesc.Count = 1; td.MipLevels = 1; result = ovr_CreateMirrorTextureD3D11(HMD, DIRECTX.Device, &td, 0, &mirrorTexture); if (!OVR_SUCCESS(result)) { if (retryCreate) goto Done; VALIDATE(false, "Failed to create mirror texture."); } // Create the room model roomScene = new Scene(false); // Create camera mainCam = new Camera(&XMVectorSet(0.0f, 1.6f, 5.0f, 0), &XMQuaternionIdentity()); // Setup VR components, filling out description ovrEyeRenderDesc eyeRenderDesc[2]; eyeRenderDesc[0] = ovr_GetRenderDesc(HMD, ovrEye_Left, hmdDesc.DefaultEyeFov[0]); eyeRenderDesc[1] = ovr_GetRenderDesc(HMD, ovrEye_Right, hmdDesc.DefaultEyeFov[1]); bool isVisible = true; DCB portConfig; portConfig.BaudRate = 115200; portConfig.Parity = EVENPARITY; g_seriPort.Start("\\\\.\\COM3", &portConfig); // Main loop while (DIRECTX.HandleMessages()) { XMVECTOR forward = XMVector3Rotate(XMVectorSet(0, 0, -0.05f, 0), mainCam->Rot); XMVECTOR right = XMVector3Rotate(XMVectorSet(0.05f, 0, 0, 0), mainCam->Rot); if (DIRECTX.Key['W'] || DIRECTX.Key[VK_UP]) mainCam->Pos = XMVectorAdd(mainCam->Pos, forward); if (DIRECTX.Key['S'] || DIRECTX.Key[VK_DOWN]) mainCam->Pos = XMVectorSubtract(mainCam->Pos, forward); if (DIRECTX.Key['D']) mainCam->Pos = XMVectorAdd(mainCam->Pos, right); if (DIRECTX.Key['A']) mainCam->Pos = XMVectorSubtract(mainCam->Pos, right); static float Yaw = 0; if (DIRECTX.Key[VK_LEFT]) mainCam->Rot = XMQuaternionRotationRollPitchYaw(0, Yaw += 0.02f, 0); if (DIRECTX.Key[VK_RIGHT]) mainCam->Rot = XMQuaternionRotationRollPitchYaw(0, Yaw -= 0.02f, 0); // Animate the cube static float cubeClock = 0; roomScene->Models[0]->Pos = XMFLOAT3(9 * sin(cubeClock), 3, 9 * cos(cubeClock += 0.015f)); // Get both eye poses simultaneously, with IPD offset already included. ovrPosef EyeRenderPose[2]; ovrVector3f HmdToEyeViewOffset[2] = { eyeRenderDesc[0].HmdToEyeViewOffset, eyeRenderDesc[1].HmdToEyeViewOffset }; double frameTime = ovr_GetPredictedDisplayTime(HMD, 0); // Keeping sensorSampleTime as close to ovr_GetTrackingState as possible - fed into the layer double sensorSampleTime = ovr_GetTimeInSeconds(); ovrTrackingState hmdState = ovr_GetTrackingState(HMD, frameTime, ovrTrue); ovr_CalcEyePoses(hmdState.HeadPose.ThePose, HmdToEyeViewOffset, EyeRenderPose); // -------------------------------------------------------------------------- // Add: Get Head Yaw Roll Pitch float hmdPitch = 0.0f; float hmdRoll = 0.0f; float hmdYaw = 0.0f; OVR::Posef HeadPose = hmdState.HeadPose.ThePose; HeadPose.Rotation.GetEulerAngles<OVR::Axis_Y, OVR::Axis_X, OVR::Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll); SetPos(2, ServoRoll(hmdYaw)); SetPos(3, ServoRoll(hmdPitch)); // -------------------------------------------------------------------------- // Render Scene to Eye Buffers if (isVisible) { for (int eye = 0; eye < 2; ++eye) { // Increment to use next texture, just before writing pEyeRenderTexture[eye]->AdvanceToNextTexture(); // Clear and set up rendertarget int texIndex = pEyeRenderTexture[eye]->TextureSet->CurrentIndex; DIRECTX.SetAndClearRenderTarget(pEyeRenderTexture[eye]->TexRtv[texIndex], pEyeDepthBuffer[eye]); DIRECTX.SetViewport((float)eyeRenderViewport[eye].Pos.x, (float)eyeRenderViewport[eye].Pos.y, (float)eyeRenderViewport[eye].Size.w, (float)eyeRenderViewport[eye].Size.h); //Get the pose information in XM format XMVECTOR eyeQuat = XMVectorSet(EyeRenderPose[eye].Orientation.x, EyeRenderPose[eye].Orientation.y, EyeRenderPose[eye].Orientation.z, EyeRenderPose[eye].Orientation.w); XMVECTOR eyePos = XMVectorSet(EyeRenderPose[eye].Position.x, EyeRenderPose[eye].Position.y, EyeRenderPose[eye].Position.z, 0); // Get view and projection matrices for the Rift camera XMVECTOR CombinedPos = XMVectorAdd(mainCam->Pos, XMVector3Rotate(eyePos, mainCam->Rot)); Camera finalCam(&CombinedPos, &(XMQuaternionMultiply(eyeQuat,mainCam->Rot))); XMMATRIX view = finalCam.GetViewMatrix(); ovrMatrix4f p = ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.2f, 1000.0f, ovrProjection_RightHanded); XMMATRIX proj = XMMatrixSet(p.M[0][0], p.M[1][0], p.M[2][0], p.M[3][0], p.M[0][1], p.M[1][1], p.M[2][1], p.M[3][1], p.M[0][2], p.M[1][2], p.M[2][2], p.M[3][2], p.M[0][3], p.M[1][3], p.M[2][3], p.M[3][3]); XMMATRIX prod = XMMatrixMultiply(view, proj); roomScene->Render(&prod, 1, 1, 1, 1, true); } } // Initialize our single full screen Fov layer. ovrLayerEyeFov ld = {}; ld.Header.Type = ovrLayerType_EyeFov; ld.Header.Flags = 0; for (int eye = 0; eye < 2; ++eye) { ld.ColorTexture[eye] = pEyeRenderTexture[eye]->TextureSet; ld.Viewport[eye] = eyeRenderViewport[eye]; ld.Fov[eye] = hmdDesc.DefaultEyeFov[eye]; ld.RenderPose[eye] = EyeRenderPose[eye]; ld.SensorSampleTime = sensorSampleTime; } ovrLayerHeader* layers = &ld.Header; result = ovr_SubmitFrame(HMD, 0, nullptr, &layers, 1); // exit the rendering loop if submit returns an error, will retry on ovrError_DisplayLost if (!OVR_SUCCESS(result)) goto Done; isVisible = (result == ovrSuccess); // Render mirror ovrD3D11Texture* tex = (ovrD3D11Texture*)mirrorTexture; DIRECTX.Context->CopyResource(DIRECTX.BackBuffer, tex->D3D11.pTexture); DIRECTX.SwapChain->Present(0, 0); } // Release resources Done: delete mainCam; delete roomScene; if (mirrorTexture) ovr_DestroyMirrorTexture(HMD, mirrorTexture); for (int eye = 0; eye < 2; ++eye) { delete pEyeRenderTexture[eye]; delete pEyeDepthBuffer[eye]; } DIRECTX.ReleaseDevice(); ovr_Destroy(HMD); g_seriPort.End(); for (int iCam = 0; iCam < numCams; iCam++) { cam[iCam]->StopCapture(); delete cam[iCam]; } // Retry on ovrError_DisplayLost return retryCreate || OVR_SUCCESS(result) || (result == ovrError_DisplayLost); }
Quaternion() { XMStoreFloat4A(this, XMQuaternionIdentity()); }
/** * Utility/Rotations.cpp * (c) Jonathan Capps * Created 11 Oct. 2011 */ #include <Windows.h> #include <xnamath.h> extern const XMVECTOR IDENTITY_QUAT = XMQuaternionIdentity(); extern const XMVECTOR QUARTER_TURN = XMQuaternionRotationAxis( XMVectorSet( 0.0f, 0.0f, -1.0f, 0.0f ), XM_PIDIV2 ); extern const XMVECTOR HALF_TURN = XMQuaternionRotationAxis( XMVectorSet( 0.0f, 0.0f, -1.0f, 0.0f ), XM_PI ); extern const XMVECTOR THREE_QUARTER_TURN = XMQuaternionRotationAxis( XMVectorSet( 0.0f, 0.0f, -1.0f, 0.0f ), 3.0f * XM_PIDIV2 ); extern const XMVECTOR TOP_JOIN = XMQuaternionRotationRollPitchYaw( 0.0f, -XM_PIDIV2, 0.0f ); extern const XMVECTOR SIDE_JOIN = XMQuaternionRotationRollPitchYaw( -XM_PIDIV2, -XM_PIDIV2, 0.0f );
void MainLoop() { Layer[0] = new VRLayer(Session); // Make a duplicate of the left eye texture, and a place to save renderpose ovrPosef extraRenderPose; OculusTexture extraRenderTexture; if (!extraRenderTexture.Init(Session, Layer[0]->pEyeRenderTexture[0]->SizeW, Layer[0]->pEyeRenderTexture[0]->SizeH)) return; //Need to commit it at least once here, or its possible when going into '1' //to have the SDK use it before any texture has been committed extraRenderTexture.Commit(); while (HandleMessages()) { // Keep a clock of what's happening static int clock = 0; ++clock; // Adjust speed, because we only want movement at certain junctures float speed = 1; if (DIRECTX.Key['1']) { if ((clock % 2) != 0) speed = 0; else speed *= 2; } ActionFromInput(speed); // Get Eye poses, but into a temporary buffer, ovrPosef tempEyeRenderPose[2]; Layer[0]->GetEyePoses(tempEyeRenderPose); // Now find out player yaw at this time XMVECTOR playerOrientation = MainCam->Rot; // And, we're going to store the player orientations from when we render static XMVECTOR playerOrientationAtRender[2]; static XMVECTOR extraOrientationAtRender; for (int eye = 0; eye < 2; ++eye) { if (DIRECTX.Key['1']) { // Don't do this eye if ((clock & 1) != eye) continue; // This situation, use the extra buffer, and we're done if (((clock % 4) == 2) && (eye == 0)) { extraRenderPose = tempEyeRenderPose[eye]; extraOrientationAtRender = playerOrientation; auto rtv = extraRenderTexture.GetRTV(); Layer[0]->RenderSceneToEyeBuffer(MainCam, RoomScene, eye, rtv, &extraRenderPose); extraRenderTexture.Commit(); continue; } } // Otherwise, operate as usual Layer[0]->EyeRenderPose[eye] = tempEyeRenderPose[eye]; playerOrientationAtRender[eye] = playerOrientation; Layer[0]->RenderSceneToEyeBuffer(MainCam, RoomScene, eye); } // If this situation is true, then want to use left texture and pose XMVECTOR diffQuat[2] = { XMQuaternionIdentity(), XMQuaternionIdentity() }; if ((DIRECTX.Key['1']) && (((clock % 4) == 0) || ((clock % 4) == 3))) { if (!DIRECTX.Key['2']) diffQuat[0] = XMQuaternionMultiply(XMQuaternionInverse(extraOrientationAtRender), playerOrientation); if (!DIRECTX.Key['2']) diffQuat[1] = XMQuaternionMultiply(XMQuaternionInverse(playerOrientationAtRender[1]), playerOrientation); Layer[0]->PrepareLayerHeader(&extraRenderTexture, &extraRenderPose, diffQuat); } else { if (!DIRECTX.Key['2']) diffQuat[0] = XMQuaternionMultiply(XMQuaternionInverse(playerOrientationAtRender[0]), playerOrientation); if (!DIRECTX.Key['2']) diffQuat[1] = XMQuaternionMultiply(XMQuaternionInverse(playerOrientationAtRender[1]), playerOrientation); Layer[0]->PrepareLayerHeader(0, 0, diffQuat); } DistortAndPresent(1); } }
// return true to retry later (e.g. after display lost) static bool MainLoop(bool retryCreate) { // Initialize these to nullptr here to handle device lost failures cleanly ovrMirrorTexture mirrorTexture = nullptr; OculusTexture * pEyeRenderTexture = nullptr; DepthBuffer * pEyeDepthBuffer = nullptr; Scene * roomScene = nullptr; Camera * mainCam = nullptr; ovrMirrorTextureDesc desc = {}; bool isVisible = true; long long frameIndex = 0; bool useInstancing = false; const int repeatDrawing = 1; ovrSession session; ovrGraphicsLuid luid; ovrResult result = ovr_Create(&session, &luid); if (!OVR_SUCCESS(result)) return retryCreate; ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); // Setup Device and Graphics // Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution if (!DIRECTX.InitDevice(hmdDesc.Resolution.w / 2, hmdDesc.Resolution.h / 2, reinterpret_cast<LUID*>(&luid))) goto Done; ovrRecti eyeRenderViewport[2]; // Make a single eye texture { ovrSizei eyeTexSizeL = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0], 1.0f); ovrSizei eyeTexSizeR = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1], 1.0f); ovrSizei textureSize; textureSize.w = eyeTexSizeL.w + eyeTexSizeR.w; textureSize.h = max(eyeTexSizeL.h, eyeTexSizeR.h); pEyeRenderTexture = new OculusTexture(); if (!pEyeRenderTexture->Init(session, textureSize.w, textureSize.h)) { if (retryCreate) goto Done; VALIDATE(OVR_SUCCESS(result), "Failed to create eye texture."); } pEyeDepthBuffer = new DepthBuffer(DIRECTX.Device, textureSize.w, textureSize.h); // set viewports eyeRenderViewport[0].Pos.x = 0; eyeRenderViewport[0].Pos.y = 0; eyeRenderViewport[0].Size = eyeTexSizeL; eyeRenderViewport[1].Pos.x = eyeTexSizeL.w; eyeRenderViewport[1].Pos.y = 0; eyeRenderViewport[1].Size = eyeTexSizeR; } if (!pEyeRenderTexture->TextureChain) { if (retryCreate) goto Done; VALIDATE(false, "Failed to create texture."); } // Create a mirror to see on the monitor. desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; desc.Width = DIRECTX.WinSizeW; desc.Height = DIRECTX.WinSizeH; result = ovr_CreateMirrorTextureDX(session, DIRECTX.Device, &desc, &mirrorTexture); if (!OVR_SUCCESS(result)) { if (retryCreate) goto Done; VALIDATE(false, "Failed to create mirror texture."); } // Create the room model roomScene = new Scene(false); // Create camera mainCam = new Camera(&XMVectorSet(0.0f, 1.6f, 5.0f, 0), &XMQuaternionIdentity()); // Setup VR components, filling out description ovrEyeRenderDesc eyeRenderDesc[2]; eyeRenderDesc[0] = ovr_GetRenderDesc(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0]); eyeRenderDesc[1] = ovr_GetRenderDesc(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1]); // Main loop while (DIRECTX.HandleMessages()) { XMVECTOR forward = XMVector3Rotate(XMVectorSet(0, 0, -0.05f, 0), mainCam->Rot); XMVECTOR right = XMVector3Rotate(XMVectorSet(0.05f, 0, 0, 0), mainCam->Rot); XMVECTOR up = XMVector3Rotate(XMVectorSet(0, 0.05f, 0, 0), mainCam->Rot); if (DIRECTX.Key['W'] || DIRECTX.Key[VK_UP]) mainCam->Pos = XMVectorAdd(mainCam->Pos, forward); if (DIRECTX.Key['S'] || DIRECTX.Key[VK_DOWN]) mainCam->Pos = XMVectorSubtract(mainCam->Pos, forward); if (DIRECTX.Key['D']) mainCam->Pos = XMVectorAdd(mainCam->Pos, right); if (DIRECTX.Key['A']) mainCam->Pos = XMVectorSubtract(mainCam->Pos, right); if (DIRECTX.Key['Q']) mainCam->Pos = XMVectorAdd(mainCam->Pos, up); if (DIRECTX.Key['E']) mainCam->Pos = XMVectorSubtract(mainCam->Pos, up); static float Yaw = 0; if (DIRECTX.Key[VK_LEFT]) mainCam->Rot = XMQuaternionRotationRollPitchYaw(0, Yaw += 0.02f, 0); if (DIRECTX.Key[VK_RIGHT]) mainCam->Rot = XMQuaternionRotationRollPitchYaw(0, Yaw -= 0.02f, 0); if (DIRECTX.Key['P']) ovr_SetInt(session, OVR_PERF_HUD_MODE, int(ovrPerfHud_AppRenderTiming)); else ovr_SetInt(session, OVR_PERF_HUD_MODE, int(ovrPerfHud_Off)); useInstancing = DIRECTX.Key['I']; // Animate the cube static float cubeClock = 0; roomScene->Models[0]->Pos = XMFLOAT3(9 * sin(cubeClock), 3, 9 * cos(cubeClock += 0.015f)); // Get both eye poses simultaneously, with IPD offset already included. ovrPosef EyeRenderPose[2]; ovrVector3f HmdToEyeOffset[2] = { eyeRenderDesc[0].HmdToEyeOffset, eyeRenderDesc[1].HmdToEyeOffset }; double sensorSampleTime; // sensorSampleTime is fed into the layer later ovr_GetEyePoses(session, frameIndex, ovrTrue, HmdToEyeOffset, EyeRenderPose, &sensorSampleTime); // Render scene to eye texture if (isVisible) { DIRECTX.SetAndClearRenderTarget(pEyeRenderTexture->GetRTV(), pEyeDepthBuffer); // calculate eye transforms XMMATRIX viewProjMatrix[2]; for (int eye = 0; eye < 2; ++eye) { //Get the pose information in XM format XMVECTOR eyeQuat = XMLoadFloat4((XMFLOAT4 *)&EyeRenderPose[eye].Orientation.x); XMVECTOR eyePos = XMVectorSet(EyeRenderPose[eye].Position.x, EyeRenderPose[eye].Position.y, EyeRenderPose[eye].Position.z, 0); // Get view and projection matrices for the Rift camera XMVECTOR CombinedPos = XMVectorAdd(mainCam->Pos, XMVector3Rotate(eyePos, mainCam->Rot)); Camera finalCam(&CombinedPos, &(XMQuaternionMultiply(eyeQuat, mainCam->Rot))); XMMATRIX view = finalCam.GetViewMatrix(); ovrMatrix4f p = ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.1f, 100.0f, ovrProjection_None); XMMATRIX proj = XMMatrixSet(p.M[0][0], p.M[1][0], p.M[2][0], p.M[3][0], p.M[0][1], p.M[1][1], p.M[2][1], p.M[3][1], p.M[0][2], p.M[1][2], p.M[2][2], p.M[3][2], p.M[0][3], p.M[1][3], p.M[2][3], p.M[3][3]); if (useInstancing) { // scale and offset projection matrix to shift image to correct part of texture for each eye XMMATRIX scale = XMMatrixScaling(0.5f, 1.0f, 1.0f); XMMATRIX translate = XMMatrixTranslation((eye==0) ? -0.5f : 0.5f, 0.0f, 0.0f); proj = XMMatrixMultiply(proj, scale); proj = XMMatrixMultiply(proj, translate); } viewProjMatrix[eye] = XMMatrixMultiply(view, proj); } if (useInstancing) { // use instancing for stereo DIRECTX.SetViewport(0.0f, 0.0f, (float)eyeRenderViewport[0].Size.w + eyeRenderViewport[1].Size.w, (float)eyeRenderViewport[0].Size.h); // render scene for (int i = 0; i < repeatDrawing; i++) roomScene->RenderInstanced(&viewProjMatrix[0], 1, 1, 1, 1, true); } else { // non-instanced path for (int eye = 0; eye < 2; ++eye) { // set viewport DIRECTX.SetViewport((float)eyeRenderViewport[eye].Pos.x, (float)eyeRenderViewport[eye].Pos.y, (float)eyeRenderViewport[eye].Size.w, (float)eyeRenderViewport[eye].Size.h); // render scene for (int i = 0; i < repeatDrawing; i++) roomScene->Render(&viewProjMatrix[eye], 1, 1, 1, 1, true); } } // Commit rendering to the swap chain pEyeRenderTexture->Commit(); } // Initialize our single full screen Fov layer. ovrLayerEyeFov ld = {}; ld.Header.Type = ovrLayerType_EyeFov; ld.Header.Flags = 0; ld.SensorSampleTime = sensorSampleTime; for (int eye = 0; eye < 2; ++eye) { ld.ColorTexture[eye] = pEyeRenderTexture->TextureChain; ld.Viewport[eye] = eyeRenderViewport[eye]; ld.Fov[eye] = hmdDesc.DefaultEyeFov[eye]; ld.RenderPose[eye] = EyeRenderPose[eye]; } ovrLayerHeader* layers = &ld.Header; result = ovr_SubmitFrame(session, frameIndex, nullptr, &layers, 1); // exit the rendering loop if submit returns an error, will retry on ovrError_DisplayLost if (!OVR_SUCCESS(result)) goto Done; isVisible = (result == ovrSuccess); // Render mirror ID3D11Texture2D* tex = nullptr; ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&tex)); DIRECTX.Context->CopyResource(DIRECTX.BackBuffer, tex); tex->Release(); DIRECTX.SwapChain->Present(0, 0); frameIndex++; } // Release resources Done: delete mainCam; delete roomScene; if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture); delete pEyeRenderTexture; delete pEyeDepthBuffer; DIRECTX.ReleaseDevice(); ovr_Destroy(session); // Retry on ovrError_DisplayLost return retryCreate || OVR_SUCCESS(result) || (result == ovrError_DisplayLost); }