Udostępnij za pośrednictwem


Pisanie niestandardowej aplikacji Holographic Remoting Player

Jeśli dopiero zaczynasz pracować z usługą Holographic Remoting, możesz przeczytać nasze omówienie.

Ważne

W tym dokumencie opisano tworzenie niestandardowej aplikacji odtwarzacza dla urządzenia HoloLens 2. Niestandardowe odtwarzacze napisane dla urządzenia HoloLens 2 nie są zgodne z aplikacjami zdalnymi napisanymi dla urządzenia HoloLens 1. Oznacza to, że obie aplikacje muszą używać pakietu NuGet w wersji 2.x.x.

Tworząc niestandardową aplikację odtwarzacza Holographic Remoting, można utworzyć niestandardową aplikację, która umożliwia wyświetlanie immersyjnych widoków z komputera zdalnego na urządzeniu HoloLens 2. Cały kod na tej stronie i roboczych projektów można znaleźć w repozytorium github przykładów Holographic Remoting.

Odtwarzacz Holographic Remoting umożliwia aplikacji wyświetlanie zawartości holograficznej renderowanej na komputerze stacjonarnym lub urządzeniu platformy UWP, takiej jak Xbox One z dostępem do większej liczby zasobów systemowych. Aplikacja odtwarzacza Holographic Remoting przesyła strumieniowo dane wejściowe do aplikacji zdalnej Holographic Remoting i odbiera z powrotem immersywny widok jako strumień wideo i audio. Połączenie jest wykonywane przy użyciu standardowej sieci Wi-Fi. Aby utworzyć aplikację odtwarzacza, użyj pakietu NuGet, aby dodać holographic Remoting do aplikacji platformy UWP. Następnie napisz kod do obsługi połączenia i wyświetlenia widoku immersyjnego.

Wymagania wstępne

Dobrym punktem wyjścia jest działająca aplikacja platformy UWP oparta na protokole DirectX, która jest już przeznaczona dla interfejsu API windows Mixed Reality. Aby uzyskać szczegółowe informacje, zobacz Omówienie programowania DirectX. Jeśli nie masz istniejącej aplikacji i chcesz zacząć od podstaw, szablon projektu holograficznego języka C++ jest dobrym punktem wyjścia.

Ważne

Każda aplikacja korzystająca z komunikacji zdalnie holograficznej powinna być autorem do korzystania z wielowątkowego mieszkania. Korzystanie z mieszkania jednowątkowego jest obsługiwane, ale doprowadzi do nie optymalnej wydajności i ewentualnie zacinania podczas odtwarzania. W przypadku korzystania z C++/WinRT winrt::init_apartment apartament wielowątkowy jest domyślny.

Pobieranie pakietu NuGet Holographic Remoting

Poniższe kroki są wymagane do dodania pakietu NuGet do projektu w programie Visual Studio.

  1. Otwórz projekt w programie Visual Studio.
  2. Kliknij prawym przyciskiem myszy węzeł projektu i wybierz polecenie Zarządzaj pakietami NuGet...
  3. W wyświetlonym panelu wybierz pozycję Przeglądaj , a następnie wyszukaj ciąg "Holographic Remoting".
  4. Wybierz pozycję Microsoft.Holographic.Remoting, upewnij się, że wybrano najnowszą wersję 2.x.x i wybierz pozycję Zainstaluj.
  5. Jeśli zostanie wyświetlone okno dialogowe Podgląd, wybierz przycisk OK.
  6. Wybierz pozycję Akceptuję po wyświetleniu okna dialogowego umowy licencyjnej.

Ważne

Wewnątrz build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl pakietu NuGet znajduje się szczegółowa dokumentacja interfejsu API uwidoczniona przez usługę Holographic Remoting.

Modyfikowanie pliku Package.appxmanifest aplikacji

Aby aplikacja wiedziała o Microsoft.Holographic.AppRemoting.dll dodanym przez pakiet NuGet, należy wykonać następujące czynności w projekcie:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy plik Package.appxmanifest i wybierz polecenie Otwórz za pomocą...
  2. Wybierz pozycję Edytor XML (tekst) i wybierz przycisk OK
  3. Dodaj następujące wiersze do pliku i zapisz
  </Capabilities>

  <!--Add lines below -->
  <Extensions>
    <Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>Microsoft.Holographic.AppRemoting.dll</Path>
        <ActivatableClass ActivatableClassId="Microsoft.Holographic.AppRemoting.PlayerContext" ThreadingModel="both" />
      </InProcessServer>
    </Extension>
  </Extensions>
  <!--Add lines above -->

</Package>

Tworzenie kontekstu odtwarzacza

W pierwszym kroku aplikacja powinna utworzyć kontekst odtwarzacza.

// class declaration:

#include <winrt/Microsoft.Holographic.AppRemoting.h>

...

private:
// PlayerContext used to connect with a Holographic Remoting remote app and display remotely rendered frames
winrt::Microsoft::Holographic::AppRemoting::PlayerContext m_playerContext = nullptr;
// class implementation:

// Create the player context
// IMPORTANT: This must be done before creating the HolographicSpace (or any other call to the Holographic API).
m_playerContext = winrt::Microsoft::Holographic::AppRemoting::PlayerContext::Create();

Ostrzeżenie

Niestandardowy odtwarzacz wprowadza warstwę pośrednią między aplikacją odtwarzacza a środowiskiem uruchomieniowym Windows Mixed Reality dostarczanym z systemem Windows. Odbywa się to podczas tworzenia kontekstu odtwarzacza. Z tego powodu każde wywołanie dowolnego interfejsu API usługi Windows Mixed Reality przed utworzeniem kontekstu odtwarzacza może spowodować nieoczekiwane zachowanie. Zalecanym podejściem jest utworzenie kontekstu odtwarzacza tak szybko, jak to możliwe przed rozpoczęciem interakcji z dowolnym interfejsem API rzeczywistości mieszanej. Nigdy nie mieszaj obiektów utworzonych ani pobieranych za pośrednictwem dowolnego interfejsu API rzeczywistości mieszanej systemu Windows przed wywołaniem metody PlayerContext::Create z obiektami utworzonymi lub pobranymi później.

Następnie można utworzyć holographicSpace, wywołując element HolographicSpace.CreateForCoreWindow.

m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(window);

Nawiązywanie połączenia z aplikacją zdalną

Gdy aplikacja odtwarzacza będzie gotowa do renderowania zawartości, można ustanowić połączenie z aplikacją zdalną.

Połączenie można ustanowić na jeden z następujących sposobów:

  1. Aplikacja odtwarzacza uruchomiona na urządzeniu HoloLens 2 łączy się z aplikacją zdalną.
  2. Aplikacja zdalna łączy się z aplikacją odtwarzacza uruchomioną na urządzeniu HoloLens 2.

Aby nawiązać połączenie z aplikacji odtwarzacza z aplikacją zdalną, wywołaj Connect metodę w kontekście odtwarzacza, określając nazwę hosta i port. Domyślny port to 8265.

try
{
    m_playerContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
    // Failed to connect. Get an error details via e.code() and e.message()
}

Ważne

Podobnie jak w przypadku dowolnego interfejsu API Connect języka C++/WinRT może zgłosić winrt::hresult_error, które należy obsłużyć.

Nasłuchiwanie połączeń przychodzących w aplikacji odtwarzacza można wykonać przez wywołanie Listen metody . Podczas tego wywołania można określić zarówno port uzgadniania, jak i port transportu. Port uzgadniania jest używany do początkowego uzgadniania. Dane są następnie wysyłane za pośrednictwem portu transportu. Domyślnie używany jest numer portu 8265 i 8266 .

try
{
    m_playerContext.Listen(L"0.0.0.0", m_port, m_port + 1);
}
catch(winrt::hresult_error& e)
{
    // Failed to listen. Get an error details via e.code() and e.message()
}

Funkcja PlayerContext uwidacznia trzy zdarzenia w celu monitorowania stanu połączenia

  1. OnConnected: wyzwalany po pomyślnym nawiązaniu połączenia z aplikacją zdalną.
m_onConnectedEventToken = m_playerContext.OnConnected([]() 
{
    // Handle connection successfully established
});
  1. OnDisconnected: wyzwolony, jeśli nawiązane połączenie zostało przerwane lub nie można ustanowić połączenia.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
    switch (failureReason)
    {
        // Handle connection failed or terminated.
        // See ConnectionFailureReason for possible reasons.
    }
}

Uwaga

Możliwe ConnectionFailureReason wartości są udokumentowane w Microsoft.Holographic.AppRemoting.idl pliku.

  1. OnListening: Podczas nasłuchiwania połączeń przychodzących rozpoczyna się.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
    // Handle start listening for incoming connections
});

Ponadto można wykonywać zapytania dotyczące stanu połączenia przy użyciu ConnectionState właściwości w kontekście odtwarzacza.

winrt::Microsoft::Holographic::AppRemoting::ConnectionState state = m_playerContext.ConnectionState();

Wyświetlanie zdalnie renderowanej ramki

Aby wyświetlić zdalnie renderowaną zawartość, wywołaj PlayerContext::BlitRemoteFrame metodę podczas renderowania elementu HolographicFrame.

BlitRemoteFrame wymaga, aby bufor wsteczny dla bieżącego elementu HolographicFrame był powiązany jako element docelowy renderowania. Bufor wsteczny można odebrać z właściwości HolographicCameraRenderingParameters za pośrednictwem właściwości Direct3D11BackBuffer .

Po wywołaniu BlitRemoteFrame program kopiuje najnowszą odebraną ramkę z aplikacji zdalnej do elementu BackBuffer elementu HolographicFrame. Ponadto zestaw punktów koncentracji uwagi jest ustawiony, jeśli aplikacja zdalna określiła punkt koncentracji uwagi podczas renderowania ramki zdalnej.

// Blit the remote frame into the backbuffer for the HolographicFrame.
winrt::Microsoft::Holographic::AppRemoting::BlitResult result = m_playerContext.BlitRemoteFrame();

Uwaga

PlayerContext::BlitRemoteFrame potencjalnie zastępuje punkt koncentracji uwagi dla bieżącej ramki.

Po powodzeniu BlitRemoteFrame zwraca wartość BlitResult::Success_Color. W przeciwnym razie zwraca przyczynę błędu:

  • BlitResult::Failed_NoRemoteFrameAvailable: Niepowodzenie, ponieważ żadna ramka zdalna nie jest dostępna.
  • BlitResult::Failed_NoCamera: Nie powiodło się, ponieważ aparat nie istnieje.
  • BlitResult::Failed_RemoteFrameTooOld: Niepowodzenie, ponieważ zdalna ramka jest zbyt stara (zobacz właściwość PlayerContext::BlitRemoteFrameTimeout).

Ważne

Począwszy od wersji 2.1.0 , można użyć niestandardowego odtwarzacza do ponownego tworzenia głębokości za pośrednictwem komunikacji zdalnie holograficznej.

BlitResult można również zwrócić BlitResult::Success_Color_Depth w następujących warunkach:

  • Aplikacja zdalna zadeklarowała bufor głębokości za pośrednictwem holographicCameraRenderingParameters.CommitDirect3D11DepthBuffer.
  • Aplikacja niestandardowego odtwarzacza ma powiązany prawidłowy bufor głębokości przed wywołaniem metody BlitRemoteFrame.

Jeśli te warunki zostaną spełnione, BlitRemoteFrame spowoduje rozbicie głębokości zdalnej do obecnie powiązanego lokalnego buforu głębokości. Następnie możesz renderować dodatkową zawartość lokalną, która będzie miała część części głębokości ze zdalną renderowaną zawartością. Ponadto możesz zatwierdzić lokalny bufor głębokości za pośrednictwem holographicCameraRenderingParameters.CommitDirect3D11DepthBuffer w niestandardowym odtwarzaczu, aby mieć szczegółowe ponowne projekty dla zawartości zdalnej i lokalnej renderowanej.

Tryb przekształcania projekcji

Jednym z problemów, które są powierzchnie podczas ponownego projekcji głębokości za pośrednictwem komunikacji zdalnej holograficznej, jest to, że zawartość zdalna może być renderowana z inną transformacją projekcji niż zawartość lokalna bezpośrednio renderowana przez niestandardową aplikację odtwarzacza. Typowym przypadkiem użycia jest określenie różnych wartości dla płaszczyzny bliskiej i dalekiej (za pośrednictwem HolographicCamera::SetNearPlaneDistance i HolographicCamera::SetFarPlaneDistance) po stronie gracza i po stronie zdalnej. W takim przypadku nie jest jasne, czy transformacja projekcji po stronie odtwarzacza powinna odzwierciedlać odległe odległości w pobliżu/na dalekiej płaszczyźnie lub na lokalnych.

Począwszy od wersji 2.1.0 , można kontrolować tryb przekształcania projekcji za pomocą polecenia PlayerContext::ProjectionTransformConfig. Obsługiwane wartości to:

  • Local - HolographicCameraPose::P rojectionTransform zwraca transformację projekcji, która odzwierciedla odległości płaszczyzny bliskiej/dalekiej ustawionej przez niestandardową aplikację odtwarzacza na HolographicCamera.
  • Remote - Transformacja projekcji odzwierciedla odległości płaszczyzny bliskiej/dalekiej określonej przez aplikację zdalną.
  • Merged - Odległość płaszczyzny bliskiej/dalekiej od aplikacji zdalnej i niestandardowej aplikacji odtwarzacza są scalane. Domyślnie odbywa się to przez podjęcie minimalnej odległości bliskiej płaszczyzny i maksymalnej odległości dalekiego płaszczyzny. W przypadku, gdy zdalna lub lokalna strona są odwrócone, powiedzmy daleko < w pobliżu, zdalne odległości w pobliżu/dalekiej płaszczyzny są odwrócone.

Opcjonalnie: ustaw wartość BlitRemoteFrameTimeout

Ważne

PlayerContext::BlitRemoteFrameTimeout Program jest obsługiwany od wersji 2.0.9.

Właściwość PlayerContext::BlitRemoteFrameTimeout określa czas ponownego użycia ramki zdalnej, jeśli nie zostanie odebrana nowa ramka zdalna.

Typowy przypadek użycia polega na włączeniu limitu czasu elementu BlitRemoteFrame w celu wyświetlenia pustego ekranu, jeśli nie odebrano żadnych nowych ramek przez określony czas. Po włączeniu zwracanego BlitRemoteFrame typu metody można również użyć do przełączenia na lokalnie renderowaną zawartość rezerwową.

Aby włączyć limit czasu, ustaw wartość właściwości na czas trwania równy lub większy niż 100 ms. Aby wyłączyć limit czasu, ustaw właściwość na zero czasu trwania. Jeśli limit czasu jest włączony i nie zostanie odebrana żadna ramka zdalna przez ustawiony czas trwania, element BlitRemoteFrame zakończy się niepowodzeniem i powróci Failed_RemoteFrameTooOld do momentu odebrania nowej ramki zdalnej.

using namespace std::chrono_literals;

// Set the BlitRemoteFrame timeout to 0.5s
m_playerContext.BlitRemoteFrameTimeout(500ms);

Opcjonalnie: Pobieranie statystyk dotyczących ostatniej ramki zdalnej

Aby zdiagnozować problemy z wydajnością lub siecią, statystyki dotyczące ostatniej ramki zdalnej można pobrać za pośrednictwem PlayerContext::LastFrameStatistics właściwości . Statystyki są aktualizowane podczas wywołania elementu HolographicFrame::P resentUsingCurrentPrediction.

// Get statistics for the last presented frame.
winrt::Microsoft::Holographic::AppRemoting::PlayerFrameStatistics statistics = m_playerContext.LastFrameStatistics();

Aby uzyskać więcej informacji, zobacz dokumentację PlayerFrameStatistics w Microsoft.Holographic.AppRemoting.idl pliku .

Opcjonalnie: Niestandardowe kanały danych

Niestandardowe kanały danych mogą służyć do wysyłania danych użytkownika za pośrednictwem już ustanowionego połączenia komunikacji wirtualnej. Aby uzyskać więcej informacji, zobacz niestandardowe kanały danych.

Opcjonalnie: nadmierne renderowanie

Holographic Remoting przewiduje, gdzie głowa użytkownika będzie w momencie wyświetlania renderowanych obrazów na ekranach. Jednak to przewidywanie jest przybliżeniem. W związku z tym przewidywane okienko wyświetlania w aplikacji zdalnej i późniejsze rzeczywistego widoku w aplikacji odtwarzacza mogą się różnić. Silniejsze odchylenia (na przykład ze względu na nieprzewidywalny ruch) mogą powodować czarne regiony na granicach frustum oglądania. Począwszy od wersji 2.6.0 , możesz użyć funkcji Over-Rendering, aby zmniejszyć liczbę czarnych regionów i zwiększyć jakość wizualizacji, sztucznie zwiększając widok poza frustum wyświetlania.

Funkcję over-rendering można włączyć za pomocą polecenia PlayerContext::ConfigureOverRendering.

Parametr OverRenderingConfig określa ułamkowe zwiększenie rozmiaru do rzeczywistego widoku, dzięki czemu przewidywane przycinanie widoku staje się większe i mniejsze. Dzięki zwiększonemu rozmiarowi wyświetlania gęstość pikseli się zmniejsza, więc funkcja OverRenderingConfig umożliwia zwiększenie rozdzielczości. Jeśli wzrost widoku jest równy rozdzielczości, zwiększ gęstość pikseli pozostaje taka sama. OverRenderingConfig parametr jest zdefiniowany jako:

struct OverRenderingConfig
{
    float HorizontalViewportIncrease; // The fractional horizontal viewport increase. (e.g. 10% -> 0.1).
    float VerticalViewportIncrease; // The fractional vertical viewport increase. (e.g. 10% -> 0.1).
                
    float HorizontalResolutionIncrease; // The fractional horizontal resolution increase. (e.g. 10% -> 0.1).
    float VerticalResolutionIncrease; // The fractional vertical resolution increase. (e.g. 10% -> 0.1).
};

Opcjonalnie: Synchronizacja systemu współrzędnych

Począwszy od wersji 2.7.0 synchronizacji systemu współrzędnych, można użyć do wyrównania danych przestrzennych między odtwarzaczem a aplikacją zdalną. Aby uzyskać więcej informacji, zobacz Koordynowanie synchronizacji systemu z holograficzne remoting — omówienie.

Zobacz też