如果你是全息遠端服務的新手,或許想 閱讀我們的概述。
重要事項
本文件描述了為 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 套件用於全息遠端管理,並加入專案的參考資料:
- 進入 Visual Studio 的專案。
- 右鍵點擊專案節點,選擇 管理 NuGet 套件......
- 在出現的面板中 ,選擇瀏覽 ,然後搜尋「Holographic Remoting」。
- 選擇 Microsoft.Holographic.Remoting ,然後選擇 安裝。
- 如果出現 預覽 對話框,請選擇 確定。
- 當出現授權協議對話框時,選擇 「我接受 」。
建立全息串流幫手
首先,我們需要在處理遠端存取的類別中加入一個 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, ¶meters));
}
});
渲染全息內容
要用遠端處理渲染內容,你可以在桌面或 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 函式庫內部偵測這些例外,可以忽略。