共用方式為


第一代 HoloLens (新增全息遠端)

如果你是全息遠端服務的新手,或許想 閱讀我們的概述

重要事項

本文件描述了為 HoloLens 1 建立主機應用程式的過程。 HoloLens (第一) 代主機應用程式必須使用 NuGet 套件版本 1.x.x。這表示為 HoloLens 1 撰寫的主機應用程式與 HoloLens 2 不相容,反之亦然。

HoloLens 2

使用 Holographic Remoting 的 HoloLens 開發者需要更新他們的應用程式,使其與 HoloLens 2 相容。 它需要全新版本的全息遠端 NuGet 套件。 連接 HoloLens 2 的全息遠端 NuGet 時,務必使用 Holographic Remoting NuGet 套件的 2.0.0.0 版本或以上。 否則,連線就會中斷。

注意事項

針對 HoloLens 2 的具體指引可在此處找到。

在你的桌面或 UWP 應用程式中加入全息遠端功能

本頁說明如何將全息遠端存取加入桌面或 UWP 應用程式。

全息遠端化讓你的應用程式能針對桌面電腦或 UWP 裝置(如 Xbox One)上的全息鏡頭進行全息投影。 你也能使用更多系統資源,使遠端 沉浸式檢視 能整合到現有的桌上型電腦軟體中。 遠端主機應用程式會接收來自 HoloLens 的輸入資料流,將內容渲染成虛擬沉浸式視角,並將內容幀串流回 HoloLens。 連線是透過標準 Wi-Fi 連線。 要使用遠端存取,可以用 NuGet 套件將全息遠端功能加入桌面或 UWP 應用程式,然後寫程式碼處理連線並呈現沉浸式視圖。 範例程式碼中包含輔助函式庫,簡化了處理裝置連線的任務。

典型的遠端連線延遲最低可達 50 毫秒。 玩家應用程式可以即時回報延遲。

注意事項

本文中的程式碼片段目前展示使用 C++/CX,而非 C++ 全息專案範本中使用的符合 C++17 標準的 C++/WinRT。 這些概念在 C++/WinRT 專案中相當,但你需要翻譯程式碼。

取得遠端的 NuGet 套件

請依照以下步驟取得 NuGet 套件用於全息遠端管理,並加入專案的參考資料:

  1. 進入 Visual Studio 的專案。
  2. 右鍵點擊專案節點,選擇 管理 NuGet 套件......
  3. 在出現的面板中 ,選擇瀏覽 ,然後搜尋「Holographic Remoting」。
  4. 選擇 Microsoft.Holographic.Remoting ,然後選擇 安裝
  5. 如果出現 預覽 對話框,請選擇 確定
  6. 當出現授權協議對話框時,選擇 「我接受 」。

建立全息串流幫手

首先,我們需要在處理遠端存取的類別中加入一個 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 顯示寬度和高度相符,因為 Holographic Remoting 函式庫預期編碼器和解碼器的解析度必須完全匹配。

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 應用程式的主迴圈提供 tick 更新。 它讓你的桌面或 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 程序載入需要超過 2GB 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 Holographic 遠端播放播放器,請從 HoloLens 到 Windows 應用程式商店,搜尋「遠端」並下載該應用程式。 遠端播放播放器包含在螢幕上顯示統計數據的功能,這在除錯遠端主機應用程式時非常有用。

註釋與資源

全息應用程式視圖需要一種方式,提供你的應用程式 Direct3D 裝置,必須用來初始化全息空間。 你的應用程式應該使用這個 Direct3D 裝置來複製並顯示預覽畫面。

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

程式碼範例: 完整的 全息遠端化程式碼範例 可供參考。 它包含一個全息應用程式檢視,與桌面 Win32、UWP DirectX 及 XAML 的 UWP 遠端管理主機專案相容。

除錯說明: Holographic Remoting 函式庫可能會提供首次機會例外。 這些例外可能在除錯工作階段中可見,視當時啟用的 Visual Studio 例外設定而定。 Holographic Remoting 函式庫內部偵測這些例外,可以忽略。

另請參閱