Dodawanie komunikacji wirtualnej holograficznej (HoloLens 1. generacji)

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

Ważne

W tym dokumencie opisano tworzenie aplikacji hosta dla urządzenia HoloLens 1. Aplikacja hosta dla urządzenia HoloLens (1. generacji) musi używać pakietu NuGet w wersji 1.x.x. Oznacza to, że aplikacje hosta napisane dla urządzenia HoloLens 1 nie są zgodne z HoloLens 2 i odwrotnie.

HoloLens 2

Deweloperzy holoLens korzystający z usługi Holographic Remoting będą musieli zaktualizować swoje aplikacje, aby były zgodne z HoloLens 2. Wymaga to nowej wersji pakietu NuGet Holographic Remoting. Pamiętaj, aby używać wersji 2.0.0.0 lub nowszej pakietu NuGet Holographic Remoting podczas nawiązywania połączenia z odtwarzaczem Holographic Remoting Player na HoloLens 2. W przeciwnym razie połączenie zakończy się niepowodzeniem.

Uwaga

Wskazówki dotyczące HoloLens 2 można znaleźć tutaj.

Dodawanie komunikacji zdalnie holograficznej do aplikacji klasycznej lub uniwersalnej systemu Windows

Na tej stronie opisano sposób dodawania komunikacji mobilnej holographic do aplikacji klasycznej lub uniwersalnej systemu Windows.

Komunikacja zdalna holograficzna umożliwia aplikacji kierowanie urządzenia HoloLens z zawartością holograficzną hostowaną na komputerze stacjonarnym lub na urządzeniu platformy UWP, takim jak Xbox One. Masz również dostęp do większej liczby zasobów systemowych, co umożliwia integrację zdalnych widoków immersyjnych z istniejącym oprogramowaniem komputerowym. Aplikacja hosta komunikacji wirtualnej odbiera strumień danych wejściowych z urządzenia HoloLens, renderuje zawartość w wirtualnym widoku immersywnym i przesyła strumieniowo ramki zawartości z powrotem do urządzenia HoloLens. Połączenie jest wykonywane przy użyciu standardowej sieci Wi-Fi. Aby użyć komunikacji zdalnie, użyj pakietu NuGet, aby dodać połączenie holograficzne do aplikacji klasycznej lub uniwersalnej systemu Windows, a następnie napisz kod do obsługi połączenia i renderowania widoku immersyjnego. Biblioteki pomocnika są uwzględnione w przykładzie kodu, który upraszcza zadanie obsługi połączenia urządzenia.

Typowe połączenie zdalnie będzie miało opóźnienie nawet 50 ms. Aplikacja odtwarzacza może zgłaszać opóźnienie w czasie rzeczywistym.

Uwaga

Fragmenty kodu w tym artykule przedstawiają obecnie użycie języka C++/CX zamiast C++17 zgodnego z językiem C++/WinRT jako używanego w szablonie projektu holograficznego języka C++. Koncepcje są równoważne projektowi C++/WinRT, choć należy przetłumaczyć kod.

Pobieranie pakietów NuGet z komunikacji zdalną

Wykonaj następujące kroki, aby pobrać pakiet NuGet na potrzeby komunikacji zdalnie holograficznej i dodać odwołanie z projektu:

  1. Przejdź do projektu 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 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.

Tworzenie elementu HolographicStreamerHelpers

Najpierw musimy dodać wystąpienie holographicStreamerHelpers do klasy, która będzie obsługiwać komunikacja zdalna.

#include <HolographicStreamerHelpers.h>

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

Należy również śledzić stan połączenia. Jeśli chcesz renderować podgląd, musisz mieć teksturę, aby ją skopiować. Potrzebujesz również kilku rzeczy, takich jak blokada stanu połączenia, jakiś sposób przechowywania adresu IP urządzenia HoloLens itd.

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;

Inicjowanie holographicStreamerHelpers i nawiązywanie połączenia z urządzeniem HoloLens

Aby nawiązać połączenie z urządzeniem HoloLens, utwórz wystąpienie usługi HolographicStreamerHelpers i połącz się z docelowym adresem IP. Należy ustawić rozmiar ramki wideo, aby był zgodny z szerokością i wysokością wyświetlacza HoloLens, ponieważ biblioteka Holographic Remoting oczekuje, że koder i rozdzielczość dekodera będą dokładnie zgodne.

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);
       }

Połączenie urządzenia jest asynchroniczne. Aplikacja musi zapewnić procedury obsługi zdarzeń na potrzeby nawiązywania połączeń, rozłączania i wysyłania zdarzeń ramek.

Zdarzenie OnConnected może zaktualizować interfejs użytkownika, rozpocząć renderowanie itd. W naszym przykładzie kodu klasycznego zaktualizujemy tytuł okna z komunikatem "połączony".

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

Zdarzenie OnDisconnected może obsługiwać ponowne nawiązywanie połączenia, aktualizacje interfejsu użytkownika itd. W tym przykładzie połączymy się ponownie, jeśli wystąpi błąd przejściowy.

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.");
               }
           });

Gdy składnik komunikacji zapasowej jest gotowy do wysłania ramki, aplikacja ma możliwość utworzenia kopii w elemencie SendFrameEvent. W tym miejscu skopiujemy ramkę do łańcucha wymiany, abyśmy mogli wyświetlić ją w oknie podglądu.

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));
               }
           });

Renderowanie zawartości holograficznej

Aby renderować zawartość przy użyciu komunikacji wirtualnej, należy skonfigurować wirtualny element IFrameworkView w aplikacji klasycznej lub aplikacji platformy UWP i przetwarzać ramki holograficzne z komunikacji wirtualnej. Wszystkie interfejsy API systemu Windows Holographic są używane w ten sam sposób w tym widoku, ale są one skonfigurowane nieco inaczej.

Zamiast tworzyć je samodzielnie, przestrzeń holograficzne i składniki mowy pochodzą z klasy HolographicRemotingHelpers:

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

Zamiast używać pętli aktualizacji w metodzie Run, należy podać aktualizacje znaczników z pętli głównej aplikacji klasycznej lub aplikacji platformy UNIWERSALNEJ systemu Windows. Dzięki temu aplikacja klasyczna lub uwP może pozostać w kontroli nad przetwarzaniem komunikatów.

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

       // display preview, etc.
   }

Metoda Tick() widoku aplikacji holograficznej kończy jedną iterację aktualizacji, rysowanie, pętlę obecną.

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);
           }
       }
   }

Aktualizacja, renderowanie i bieżąca pętla widoku aplikacji holograficznej są dokładnie takie same jak w przypadku uruchamiania na urządzeniu HoloLens — z wyjątkiem tego, że masz dostęp do znacznie większej ilości zasobów systemowych na komputerze stacjonarnym. Możesz renderować wiele więcej trójkątów, mieć więcej przebiegów rysunku, wykonywać więcej fizyki i używać procesów x64 do ładowania zawartości, która wymaga więcej niż 2 GB pamięci RAM.

Rozłączanie i kończ sesję zdalną

Aby rozłączyć — na przykład gdy użytkownik kliknie przycisk interfejsu użytkownika w celu rozłączenia — wywołaj polecenie Disconnect() w holographicStreamerHelpers, a następnie zwolnij obiekt.

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;
       }
   }

Pobieranie odtwarzacza komunikacji zdalnie

Odtwarzacz remotingu systemu Windows Holographic jest oferowany w sklepie z aplikacjami systemu Windows jako punkt końcowy do nawiązywania połączenia z aplikacjami hosta do komunikacji wirtualnej. Aby uzyskać odtwarzacz remoting systemu Windows Holographic, odwiedź sklep z aplikacjami systemu Windows z urządzenia HoloLens, wyszukaj aplikację Remoting i pobierz aplikację. Odtwarzacz komunikacji mobilnej zawiera funkcję do wyświetlania statystyk na ekranie, co może być przydatne podczas debugowania aplikacji hosta komunikacji zdalnie.

Uwagi i zasoby

Widok aplikacji holograficznej będzie wymagał sposobu udostępnienia aplikacji urządzeniu Direct3D, którego należy użyć do zainicjowania przestrzeni holograficznej. Aplikacja powinna używać tego urządzenia Direct3D do kopiowania i wyświetlania ramki podglądu.

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

Przykładowy kod: Dostępny jest kompletny przykład kodu komunikacji wirtualnej Holographic Remoting , który zawiera widok aplikacji holograficznej, który jest zgodny z projektami hosta komunikacji wirtualnej i komunikacji wirtualnej dla komputerów Win32, UWP DirectX i UWP z XAML.

Uwaga dotycząca debugowania: Biblioteka Holographic Remoting może zgłaszać wyjątki pierwszej szansy. Te wyjątki mogą być widoczne w sesjach debugowania, w zależności od ustawień wyjątków programu Visual Studio, które są aktywne w tym czasie. Te wyjątki są przechwytywane wewnętrznie przez bibliotekę Holographic Remoting i można je zignorować.

Zobacz też