新增 HoloLens 第一代 (全像攝影遠端處理)

如果您不熟悉全像攝影遠端功能,建議您 閱讀我們的概觀

重要

本檔說明如何建立 HoloLens 1 的主應用程式。 HoloLens (第 1 代主機應用程式) 必須使用 NuGet 套件1.x.x版。這表示針對 HoloLens 1 撰寫的主機應用程式與HoloLens 2不相容,反之亦然。

HoloLens 2

使用全像攝影遠端處理的 HoloLens 開發人員必須更新其應用程式,使其與HoloLens 2相容。 這需要新版本的全像攝影遠端 NuGet 套件。 連線至 HoloLens 2 上的全像攝影遠端 NuGet 套件時,請務必使用 2.0.0.0 版或更新版本的 NuGet 套件。 否則連線會失敗。

注意

您可以在這裡找到HoloLens 2特定的指引。

將全像攝影遠端功能新增至桌面或 UWP 應用程式

此頁面說明如何將全像攝影遠端功能新增至桌面或 UWP 應用程式。

全像攝影遠端功能可讓您的應用程式以全像攝影內容裝載于桌上型電腦或 UWP 裝置上的 HoloLens 為目標,例如 Xbox One。 您也可以存取更多系統資源,以便將遠端 沉浸式檢視 整合到現有的桌上型電腦軟體中。 遠端主機應用程式會從 HoloLens 接收輸入資料流程、在虛擬沉浸式檢視中轉譯內容,並將內容框架串流回 HoloLens。 連線是使用標準 Wi-Fi 進行。 若要使用遠端處理,請使用 NuGet 套件將全像攝影遠端新增至桌面或 UWP 應用程式,然後撰寫程式碼來處理連線並轉譯沉浸式檢視。 協助程式程式庫包含在程式碼範例中,可簡化處理裝置連線的工作。

一般遠端連線的延遲時間最低為 50 毫秒。 播放機應用程式可以即時報告延遲。

注意

本文中的程式碼片段目前示範如何使用 C++/CX,而不是 C++17 相容的 C++/WinRT,如 C++ 全像攝影專案範本所示。 雖然您必須翻譯程式碼,但概念對等於 C++/WinRT 專案。

取得遠端 NuGet 套件

請遵循下列步驟來取得全像攝影遠端處理的 NuGet 套件,並從您的專案新增參考:

  1. 移至 Visual Studio 中的專案。
  2. 以滑鼠右鍵按一下專案節點,然後選取 [管理 NuGet 套件...
  3. 在出現的面板中,選取 [ 流覽 ],然後搜尋 [全像攝影遠端處理]。
  4. 選取 [Microsoft.Holographic.Remoting] ,然後選取 [ 安裝]。
  5. 如果出現 [預覽 ] 對話方塊,請選取 [確定]。
  6. 當 [授權合約] 對話方塊出現時,選取 [ 我接受 ]。

建立 HolographicStreamerHelpers

首先,我們需要將 HolographicStreamerHelpers 的實例新增至將處理遠端處理的類別。

#include <HolographicStreamerHelpers.h>

   private:
       Microsoft::Holographic::HolographicStreamerHelpers^ m_streamerHelpers;

您也需要追蹤線上狀態。 如果您想要轉譯預覽,您需要有紋理才能將其複製到其中。 您也需要一些專案,例如線上狀態鎖定、儲存 HoloLens 的 IP 位址等。

private:
       Microsoft::Holographic::HolographicStreamerHelpers^ m_streamerHelpers;

       Microsoft::WRL::Wrappers::SRWLock                   m_connectionStateLock;

       RemotingHostSample::AppView^                        m_appView;
       Platform::String^                                   m_ipAddress;
       Microsoft::Holographic::HolographicStreamerHelpers^ m_streamerHelpers;

       Microsoft::WRL::Wrappers::CriticalSection           m_deviceLock;
       Microsoft::WRL::ComPtr<IDXGISwapChain1>             m_swapChain;
       Microsoft::WRL::ComPtr<ID3D11Texture2D>             m_spTexture;

初始化 HolographicStreamerHelpers 並聯機至 HoloLens

若要連線到 HoloLens 裝置,請建立 HolographicStreamerHelpers 的實例,並聯機到目標 IP 位址。 您必須設定視訊畫面大小以符合 HoloLens 顯示寬度和高度,因為全像攝影遠端程式庫預期編碼器和解碼器解析度完全相符。

m_streamerHelpers = ref new HolographicStreamerHelpers();
       m_streamerHelpers->CreateStreamer(m_d3dDevice);

       // We currently need to stream at 720p because that's the resolution of our remote display.
       // There is a check in the holographic streamer that makes sure the remote and local
       // resolutions match. The default streamer resolution is 1080p.
       m_streamerHelpers->SetVideoFrameSize(1280, 720);

       try
       {
           m_streamerHelpers->Connect(m_ipAddress->Data(), 8001);
       }
       catch (Platform::Exception^ ex)
       {
           DebugLog(L"Connect failed with hr = 0x%08X", ex->HResult);
       }

裝置連線是非同步。 您的應用程式需要提供事件處理常式,以便連接、中斷連線和框架傳送事件。

OnConnected 事件可以更新 UI、開始轉譯等等。 在我們的桌面程式碼範例中,我們會使用「已連線」訊息來更新視窗標題。

m_streamerHelpers->OnConnected += ref new ConnectedEvent(
           [this]()
           {
               UpdateWindowTitle();
           });

OnDisconnected 事件可以處理重新連線、UI 更新等等。 在此範例中,如果發生暫時性失敗,我們會重新連線。

Platform::WeakReference streamerHelpersWeakRef = Platform::WeakReference(m_streamerHelpers);
       m_streamerHelpers->OnDisconnected += ref new DisconnectedEvent(
           [this, streamerHelpersWeakRef](_In_ HolographicStreamerConnectionFailureReason failureReason)
           {
               DebugLog(L"Disconnected with reason %d", failureReason);
               UpdateWindowTitle();

               // Reconnect if this is a transient failure.
               if (failureReason == HolographicStreamerConnectionFailureReason::Unreachable ||
                   failureReason == HolographicStreamerConnectionFailureReason::ConnectionLost)
               {
                   DebugLog(L"Reconnecting...");

                   try
                   {
                       auto helpersResolved = streamerHelpersWeakRef.Resolve<HolographicStreamerHelpers>();
                       if (helpersResolved)
                       {
                           helpersResolved->Connect(m_ipAddress->Data(), 8001);
                       }
                       else
                       {
                           DebugLog(L"Failed to reconnect because a disconnect has already occurred.\n");
                       }
                   }
                   catch (Platform::Exception^ ex)
                   {
                       DebugLog(L"Connect failed with hr = 0x%08X", ex->HResult);
                   }
               }
               else
               {
                   DebugLog(L"Disconnected with unrecoverable error, not attempting to reconnect.");
               }
           });

當遠端元件準備好傳送框架時,您的應用程式有機會在 SendFrameEvent 中複製它。 在這裡,我們會將框架複製到交換鏈結,以便在預覽視窗中顯示它。

m_streamerHelpers->OnSendFrame += ref new SendFrameEvent(
           [this](_In_ const ComPtr<ID3D11Texture2D>& spTexture, _In_ FrameMetadata metadata)
           {
               if (m_showPreview)
               {
                   ComPtr<ID3D11Device1> spDevice = m_appView->GetDeviceResources()->GetD3DDevice();
                   ComPtr<ID3D11DeviceContext> spContext = m_appView->GetDeviceResources()->GetD3DDeviceContext();

                   ComPtr<ID3D11Texture2D> spBackBuffer;
                   ThrowIfFailed(m_swapChain->GetBuffer(0, IID_PPV_ARGS(&spBackBuffer)));

                   spContext->CopySubresourceRegion(
                       spBackBuffer.Get(), // dest
                       0,                  // dest subresource
                       0, 0, 0,            // dest x, y, z
                       spTexture.Get(),    // source
                       0,                  // source subresource
                       nullptr);           // source box, null means the entire resource

                   DXGI_PRESENT_PARAMETERS parameters = { 0 };
                   ThrowIfFailed(m_swapChain->Present1(1, 0, &parameters));
               }
           });

轉譯全像攝影內容

若要使用遠端轉譯內容,您可以在桌面或 UWP 應用程式中設定虛擬 IFrameworkView,並從遠端處理全像攝影畫面。 所有 Windows 全像攝影 API 都以此檢視的方式使用,但設定方式稍有不同。

全像攝影空間和語音元件不是自行建立,而是來自 HolographicRemotingHelpers 類別:

m_appView->Initialize(m_streamerHelpers->HolographicSpace, m_streamerHelpers->RemoteSpeech);

您不需要在 Run 方法中使用更新迴圈,而是從傳統型或 UWP 應用程式的主要迴圈提供刻度更新。 這可讓您的桌面或 UWP 應用程式保持控制訊息處理。

void DesktopWindow::Tick()
   {
       auto lock = m_deviceLock.Lock();
       m_appView->Tick();

       // display preview, etc.
   }

全像攝影應用程式檢視的 Tick () 方法會完成更新、繪製、呈現迴圈的一個反復專案。

void AppView::Tick()
   {
       if (m_main)
       {
           // When running on Windows Holographic, we can use the holographic rendering system.
           HolographicFrame^ holographicFrame = m_main->Update();

           if (holographicFrame && m_main->Render(holographicFrame))
           {
               // The holographic frame has an API that presents the swap chain for each
               // holographic camera.
               m_deviceResources->Present(holographicFrame);
           }
       }
   }

全像攝影應用程式檢視更新、轉譯和呈現迴圈與在 HoloLens 上執行時完全相同,不同之處在于您可以存取桌上型電腦上的系統資源數量更大。 您可以轉譯更多三角形、擁有更多繪圖階段、執行更多物理功能,以及使用 x64 進程載入需要超過 2 GB RAM 的內容。

中斷連線並結束遠端會話

若要中斷連線 - 例如,當使用者按一下 UI 按鈕以中斷連線時 - 在 HolographicStreamerHelpers 上呼叫 Disconnect () ,然後釋放物件。

void DesktopWindow::DisconnectFromRemoteDevice()
   {
       // Disconnecting from the remote device can change the connection state.
       auto exclusiveLock = m_connectionStateLock.LockExclusive();

       if (m_streamerHelpers != nullptr)
       {
           m_streamerHelpers->Disconnect();

           // Reset state
           m_streamerHelpers = nullptr;
       }
   }

取得遠端播放程式

Windows 全像攝影遠端播放程式會以遠端主機應用程式的端點的形式在 Windows 應用程式市集中提供。 若要取得 Windows 全像攝影遠端播放程式,請從 HoloLens 流覽 Windows 應用程式市集、搜尋遠端處理,然後下載應用程式。 遠端播放套裝程式含一項功能,可在螢幕上顯示統計資料,這在偵錯遠端主機應用程式時很有用。

附注和資源

全像攝影應用程式檢視需要一種方式,才能提供您的應用程式 Direct3D 裝置,這必須用來初始化全像攝影空間。 您的應用程式應該使用此 Direct3D 裝置來複製及顯示預覽畫面。

internal:
       const std::shared_ptr<DX::DeviceResources>& GetDeviceResources()
       {
           return m_deviceResources;
       }

程式碼範例: 有完整的 全像攝影遠端程式碼範例 可供使用,其中包含與桌面 Win32、UWP DirectX 和 UWP 與 XAML 遠端處理主項目目相容的全像攝影應用程式檢視。

偵錯注意事項: 全像攝影遠端程式庫可能會擲回第一次發生例外狀況。 這些例外狀況可能會顯示在偵錯會話中,視目前使用中的 Visual Studio 例外狀況設定而定。 全像攝影遠端程式庫會在內部攔截這些例外狀況,而且可以忽略。

另請參閱