共用方式為


取得 HolographicSpace

注意

本文與舊版 WinRT 原生 API 相關。 針對新的原生應用程式項目,我們建議使用 OpenXR API

HolographicSpace 類別是全像攝影世界中的入口網站。 它會控制沈浸式轉譯、提供相機數據,以及提供空間推理 API 的存取權。 您將為 UWP 應用程式的 CoreWindow 或 Win32 應用程式的 HWND 建立一個。

設定全像攝影空間

建立全像攝影空間對像是建立 Windows Mixed Reality 應用程式的第一個步驟。 傳統 Windows 應用程式會轉譯成針對其應用程式檢視的核心視窗所建立的 Direct3D 交換鏈結。 此交換鏈結會顯示至全像攝影UI中的平板。 若要讓應用程式檢視全像攝影而非 2D 平板,請為其核心視窗建立全像攝影空間,而不是交換鏈結。 呈現此全像攝影空間所建立的全像攝影畫面,讓您的 app 進入全螢幕轉譯模式。

針對從全像攝影 DirectX 11 App (通用 Windows) 範本開始的 UWP 應用程式,請在 AppView.cpp 的 SetWindow 方法中尋找此程式代碼:

m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);

如果您要從 BasicHologram Win32 範例開始建置 Win32 應用程式,請查看 App::CreateWindowAndHolographicSpace 以取得 HWND 範例。 然後,您可以建立相關聯的 HolographicSpace,將它轉換成沉浸式 HWND:

void App::CreateWindowAndHolographicSpace(HINSTANCE hInstance, int nCmdShow)
{
    // Store the instance handle in our class variable.
    m_hInst = hInstance;

    // Create the window for the HolographicSpace.
    hWnd = CreateWindowW(
        m_szWindowClass, 
        m_szTitle,
        WS_VISIBLE,
        CW_USEDEFAULT, 
        0, 
        CW_USEDEFAULT, 
        0, 
        nullptr, 
        nullptr, 
        hInstance, 
        nullptr);

    if (!hWnd)
    {
        winrt::check_hresult(E_FAIL);
    }

    {
        // Use WinRT factory to create the holographic space.
        using namespace winrt::Windows::Graphics::Holographic;
        winrt::com_ptr<IHolographicSpaceInterop> holographicSpaceInterop =
            winrt::get_activation_factory<HolographicSpace, IHolographicSpaceInterop>();
        winrt::com_ptr<ABI::Windows::Graphics::Holographic::IHolographicSpace> spHolographicSpace;
        winrt::check_hresult(holographicSpaceInterop->CreateForWindow(
            hWnd, __uuidof(ABI::Windows::Graphics::Holographic::IHolographicSpace),
            winrt::put_abi(spHolographicSpace)));

        if (!spHolographicSpace)
        {
            winrt::check_hresult(E_FAIL);
        }

        // Store the holographic space.
        m_holographicSpace = spHolographicSpace.as<HolographicSpace>();
    }

    // The DeviceResources class uses the preferred DXGI adapter ID from the holographic
    // space (when available) to create a Direct3D device. The HolographicSpace
    // uses this ID3D11Device to create and manage device-based resources such as
    // swap chains.
    m_deviceResources->SetHolographicSpace(m_holographicSpace);

    // The main class uses the holographic space for updates and rendering.
    m_main->SetHolographicSpace(hWnd, m_holographicSpace);

    // Show the window. This will activate the holographic view and switch focus
    // to the app in Windows Mixed Reality.
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
}

當您取得 UWP CoreWindow 或 Win32 HWND 的 HolographicSpace 之後,HolographicSpace 就可以處理全像攝影相機、建立座標系統,以及執行全像攝影轉譯。 目前的全像攝影空間會用於 DirectX 範本中的多個位置:

  • DeviceResources 類別必須從 HolographicSpace 物件取得一些資訊,才能建立 Direct3D 裝置。 這是與全像攝影顯示器相關聯的 DXGI 配接器標識碼。 HolographicSpace 類別會使用您應用程式的 Direct3D 11 裝置來建立和管理裝置型資源,例如每個全像攝影相機的後台緩衝區。 如果您有興趣瞭解此函式在幕後的作用,您會在DeviceResources.cpp中找到它。
  • DeviceResources::InitializeUsingHolographicSpace 函式示範如何透過查閱 LUID 來取得配接器,以及如何在未指定慣用適配卡時選擇預設配接器。
  • 應用程式的主要類別會使用AppView::SetWindow或App::CreateWindowAndHolographicSpace中的全像攝影空間進行更新和轉譯。

注意

雖然下列各節提及來自 AppView::SetWindow 等 範本的函式名稱,假設 您從全像攝影 UWP 應用程式範本開始,但您所看到的代碼段會同樣套用到 UWP 和 Win32 應用程式。

接下來,我們將深入探討 SetHolographicSpace 在 AppMain 類別中負責的設定程式

訂閱相機事件、建立和移除相機資源

您應用程式的全像攝影內容會存在於全像攝影空間中,並透過一或多個全像攝影相機來檢視,其代表場景中的不同視角。 現在您已擁有全像攝影空間,您可以接收全像攝影相機的數據。

您的應用程式必須藉由建立該相機特有的任何資源來回應 CameraAdded 事件。 這類資源的範例是後端緩衝區轉譯目標檢視。 您可以在 AppView::SetWindow 呼叫的 DeviceResources::SetHolographicSpace 函式中看到此程式代碼,然後應用程式建立任何全像攝影畫面:

m_cameraAddedToken = m_holographicSpace.CameraAdded(
    std::bind(&AppMain::OnCameraAdded, this, _1, _2));

您的應用程式也需要藉由釋放為該相機建立的資源來回應 CameraRemoved 事件。

DeviceResources::SetHolographicSpace

m_cameraRemovedToken = m_holographicSpace.CameraRemoved(
    std::bind(&AppMain::OnCameraRemoved, this, _1, _2));

事件處理程式必須完成一些工作,才能讓全像攝影轉譯順暢地流動,以及您的應用程式完全轉譯。 閱讀詳細數據的程式代碼和批註:您可以在主要類別中尋找 OnCameraAdded 和 OnCameraRemoved,以瞭解 DeviceResources 如何處理m_cameraResources地圖。

現在,我們專注於AppMain及其設定,讓您的App能夠知道全像攝影相機。 考慮到這一點,請務必注意下列兩個需求:

  1. 針對 CameraAdded 事件處理程式,應用程式可以異步運作,以完成為新的全像攝影機建立資源和載入資產。 需要一個以上的畫面來完成這項工作的應用程式應該要求延遲,並在異步載入之後完成延遲。 PPL 工作可用來執行異步工作。 您的應用程式必須確保它已準備好在結束事件處理程式或完成延遲時立即轉譯至該相機。 結束事件處理程式或完成延遲會告訴系統,您的應用程式現在已準備好接收包含該相機的全像攝影畫面。

  2. 當應用程式收到 CameraRemoved 事件時,它必須釋放返回緩衝區的所有參考,並立即結束函式。 這包括轉譯目標檢視,以及可能保存IDXGIResource參考的任何其他資源。 應用程式也必須確保背景緩衝區未附加為轉譯目標,如 CameraResources::ReleaseResourcesForBackBuffer 所示。 為了協助加快速度,您的應用程式可以釋放後台緩衝區,然後啟動工作,以異步方式完成相機的任何其他卸載工作。 全像攝影應用程式範本包含可用於此用途的PPL工作。

注意

如果您想要判斷新增或移除的相機何時顯示在畫面上,請使用 HolographicFrame AddedCamerasRemovedCameras 屬性。

為您的全像攝影內容建立參考框架

您的應用程式內容必須放置在 空間座標系統中 ,才能在 HolographicSpace 中轉譯。 系統提供兩個主要參考框架,您可以用來建立全像投影的座標系統。

Windows 全像攝影版中有兩種參考框架:附加至裝置的參考框架,以及當裝置在用戶環境中移動時,仍保持靜止的參考畫面。 全像攝影應用程式範本預設會使用固定參考框架;這是轉譯世界鎖定全像投影的最簡單方式之一。

固定參考框架的設計目的是穩定裝置目前位置附近的位置。 這表示裝置的座標會稍微相對於用戶環境漂移,因為裝置會進一步瞭解其周圍的空間。 有兩種方式可以建立固定的參考框架:從 空間階段取得座標系統,或使用預設 的 SpatialLocator。 如果您要為沉浸式頭戴裝置建立 Windows Mixed Reality 應用程式,建議的起點是 空間階段。 空間階段也提供玩家所穿沉浸式頭戴裝置功能的相關信息。 在這裡,我們將示範如何使用預設 SpatialLocator

空間定位器代表 Windows Mixed Reality 裝置,並追蹤裝置的動作,並提供可與其位置相對瞭解的座標系統。

AppMain::OnHolographicDisplayIsAvailableChanged

spatialLocator = SpatialLocator::GetDefault();

啟動應用程式時,建立固定參考框架一次。 這類似於定義世界座標系統,其原點位於應用程式啟動時裝置的位置。 此參考框架不會隨裝置移動。

AppMain::SetHolographicSpace

m_stationaryReferenceFrame =
    m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();

所有參考框架都會對齊重力,這表示 y 軸會指向與用戶環境相關的「向上」。 由於 Windows 使用「右手」座標系統,因此 –z 軸的方向與建立參照框架時裝置所面對的「向前」方向重合。

注意

當您的應用程式需要精確放置個別全像投影時,請使用 SpatialAnchor 將個別全像投影錨定到真實世界中的位置。 例如,當使用者指出某個點具有特殊興趣時,請使用空間錨點。 錨點位置不會漂移,但可以調整。 根據預設,調整錨點時,它會在更正發生之後,將其位置放寬到接下來的數個畫面格。 視您的應用程式而定,當發生這種情況時,您可能會想要以不同的方式處理調整(例如,延遲調整,直到全像投影失檢為止)。 RawCoordinateSystem 屬性和 RawCoordinateSystemAdjusted 事件會啟用這些自定義。

回應可擷取性變更事件

轉譯世界鎖定的全像投影需要裝置在世界上找出自己。 由於環境狀況,這不一定是可能的,若是如此,使用者可能會預期有追蹤中斷的視覺指示。 此視覺指示必須使用附加至裝置的參考畫面格來轉譯,而不是靜止到世界。

您的應用程式可以要求在追蹤因任何原因而中斷時收到通知。 註冊 LocatabilityChanged 事件,以偵測裝置在世界上找出自己的能力何時變更。 從 AppMain::SetHolographicSpace:

m_locatabilityChangedToken = m_spatialLocator.LocatabilityChanged(
    std::bind(&HolographicApp6Main::OnLocatabilityChanged, this, _1, _2));

然後使用這個事件來判斷何時無法將全像投影轉譯成靜止到世界。

另請參閱