Hinzufügen von Holographic Remoting (HoloLens 1. Generation)

Wenn Sie noch nicht mit Holographic Remoting sind, sollten Sie unsere Übersicht lesen.

Wichtig

In diesem Dokument wird die Erstellung einer Hostanwendung für HoloLens 1 beschrieben. Hostanwendung für HoloLens (1. Generation) muss NuGet Paketversion 1.x.x verwenden. Dies bedeutet, dass Hostanwendungen, die für HoloLens 1 geschrieben wurden, nicht mit HoloLens 2 und umgekehrt kompatibel sind.

HoloLens 2

HoloLens, die Holographic Remoting verwenden, müssen ihre Apps aktualisieren, damit sie mit den HoloLens 2. Dies erfordert eine neue Version des Holographic Remoting NuGet Pakets. Achten Sie darauf, version 2.0.0.0 oder höher des Holographic Remoting NuGet-Pakets zu verwenden, wenn Sie eine Verbindung mit dem Holographic Remoting Player auf dem HoloLens 2. Andernfalls wird die Verbindung nicht hergestellt.

Hinweis

Spezifische Anleitungen HoloLens 2 finden Sie hier.

Hinzufügen von holografischem Remoting zu Ihrem Desktop oder Ihrer UWP-App

Auf dieser Seite wird beschrieben, wie Holographic Remoting einer Desktop- oder UWP-App hinzugefügt wird.

Mit Holographic Remoting kann Ihre App auf eine HoloLens mit holografischen Inhalten ausgerichtet werden, die auf einem Desktop-PC oder auf einem UWP-Gerät wie dem Xbox One. Sie haben auch Zugriff auf weitere Systemressourcen, was die Integration von immersiven Remoteansichten in vorhandene Desktop-PC-Software ermöglicht. Eine Remotinghost-App empfängt einen Eingabedatenstrom von einem HoloLens, rendert Inhalte in einer virtuellen immersiven Ansicht und streamt Inhaltsframes zurück an HoloLens. Die Verbindung wird über wlan-standard hergestellt. Um Remoting zu verwenden, verwenden Sie ein NuGet-Paket, um Ihrem Desktop oder Ihrer UWP-App holografisches Remoting hinzuzufügen. Schreiben Sie dann Code, um die Verbindung zu verarbeiten und eine immersive Ansicht zu rendern. Hilfsbibliotheken sind im Codebeispiel enthalten, die die Verarbeitung der Geräteverbindung vereinfachen.

Eine typische Remotingverbindung hat eine Latenz von bis zu 50 ms. Die Player-App kann die Latenzzeit in Echtzeit melden.

Hinweis

Die Codeausschnitte in diesem Artikel veranschaulichen derzeit die Verwendung von C++/CX anstelle von C++17-kompatiblem C++/WinRT, wie in der holografischen C++-Projektvorlage verwendet. Die Konzepte sind für ein C++/WinRT-Projekt gleichwertig, obwohl Sie den Code übersetzen müssen.

Get the remoting NuGet packages

Führen Sie die folgenden Schritte aus, um NuGet Paket für holografisches Remoting zu erhalten, und fügen Sie einen Verweis aus Ihrem Projekt hinzu:

  1. Wechseln Sie zu Ihrem Projekt in Visual Studio.
  2. Klicken Sie mit der rechten Maustaste auf den Projektknoten, und wählen Sie manage NuGet Packages... (Pakete verwalten) aus.
  3. Wählen Sie im angezeigten Bereich Durchsuchen aus , und suchen Sie dann nach "Holographic Remoting".
  4. Wählen Sie Microsoft.Holographic.Remoting und dann Installieren aus.
  5. Wenn das Dialogfeld Vorschau angezeigt wird, wählen Sie OK aus.
  6. Wählen Sie Ich stimme zu aus, wenn das Dialogfeld lizenzvertrag angezeigt wird.

Erstellen der HolographicStreamerHelpers

Zunächst müssen wir der Klasse eine Instanz von HolographicStreamerHelpers hinzufügen, die Remoting behandelt.

#include <HolographicStreamerHelpers.h>

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

Außerdem müssen Sie den Verbindungsstatus nachverfolgen. Wenn Sie die Vorschau rendern möchten, benötigen Sie eine Textur, in die sie kopiert werden kann. Außerdem benötigen Sie einige Dinge wie eine Verbindungsstatussperre, eine Möglichkeit zum Speichern der IP-Adresse HoloLens und so weiter.

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;

Initialisieren von HolographicStreamerHelpers und Herstellen einer Verbindung mit HoloLens

Um eine Verbindung mit einem HoloLens herzustellen, erstellen Sie eine Instanz von HolographicStreamerHelpers, und stellen Sie eine Verbindung mit der ZIEL-IP-Adresse herstellen. Sie müssen die Größe des Videoframes so festlegen, dass sie mit der HoloLens-Anzeigebreite und -höhe übereinstimmen, da die Holographic Remoting-Bibliothek erwartet, dass die Encoder- und Decoderauflösungen genau übereinstimmen.

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

Die Geräteverbindung ist asynchron. Ihre App muss Ereignishandler für Verbindungs-, Trennungs- und Frame-Sendeereignisse bereitstellen.

Das OnConnected-Ereignis kann die Benutzeroberfläche aktualisieren, das Rendering starten und so weiter. In unserem Desktopcodebeispiel aktualisieren wir den Fenstertitel mit einer "verbundenen" Meldung.

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

Das OnDisconnected-Ereignis kann die wiederhergestellte Verbindung, Aktualisierungen der Benutzeroberfläche und so weiter verarbeiten. In diesem Beispiel stellen wir die Verbindung wieder her, wenn ein vorübergehender Fehler vor liegt.

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

Wenn die Remotingkomponente bereit ist, einen Frame zu senden, wird Ihrer App die Möglichkeit gegeben, eine Kopie davon im SendFrameEvent zu erstellen. Hier kopieren wir den Frame in eine Austauschkette, damit wir ihn in einem Vorschaufenster anzeigen können.

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

Rendern von holografischem Inhalt

Um Inhalte mithilfe von Remoting zu rendern, richten Sie eine virtuelle IFrameworkView in Ihrem Desktop oder ihrer UWP-App ein und verarbeiten holografische Frames aus Remoting. Alle Windows Holographic-APIs werden in dieser Ansicht auf die gleiche Weise verwendet, aber sie sind etwas anders eingerichtet.

Anstatt sie selbst zu erstellen, stammen der holografische Raum und die Sprachkomponenten aus Ihrer HolographicRemotingHelpers-Klasse:

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

Anstatt eine Updateschleife in einer Run-Methode zu verwenden, stellen Sie Tickupdates aus der Hauptschleife Ihres Desktops oder Ihrer UWP-App bereit. Dadurch kann Ihr Desktop oder Ihre UWP-App die Kontrolle über die Nachrichtenverarbeitung erhalten.

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

       // display preview, etc.
   }

Die Tick()-Methode der holografischen App-Ansicht schließt eine Iteration der Update-, Draw- und Present-Schleife ab.

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

Die Update-, Render- und Present-Schleife der holografischen App-Ansicht ist identisch mit der Ausführung auf HoloLens– mit der Ausnahme, dass Sie zugriff auf eine viel größere Anzahl von Systemressourcen auf Ihrem Desktop-PC haben. Sie können viele weitere Dreiecke rendern, mehr Zeichenläufe haben, mehr Physikalisches tun und x64-Prozesse verwenden, um Inhalte zu laden, die mehr als 2 GB RAM erfordern.

Trennen und Beenden der Remotesitzung

Um die Verbindung zu trennen, z. B. wenn der Benutzer auf eine Benutzeroberflächenschaltfläche klickt, um die Verbindung zu trennen, rufen Sie Disconnect() für HolographicStreamerHelpers auf, und geben Sie dann das Objekt frei.

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

Get the remoting player (Remotingplayer erhalten)

Der Windows Holographic-Remotingplayer wird im Windows App Store als Endpunkt für Remotinghost-Apps angeboten, mit dem eine Verbindung hergestellt werden kann. Um den Windows Holographic-Remoting-Player zu erhalten, besuchen Sie den Windows App Store aus Ihrem HoloLens, suchen Sie nach Remoting, und laden Sie die App herunter. Der Remotingplayer enthält ein Feature zum Anzeigen von Statistiken auf dem Bildschirm, was beim Debuggen von Remotinghost-Apps nützlich sein kann.

Hinweise und Ressourcen

Die holografische App-Ansicht benötigt eine Möglichkeit, um Ihrer App das Direct3D-Gerät zur Verfügung zu stellen, das zum Initialisieren des holografischen Raums verwendet werden muss. Ihre App sollte dieses Direct3D-Gerät verwenden, um den Vorschauframe zu kopieren und anzuzeigen.

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

Codebeispiel: Ein vollständiges Holographic Remoting-Codebeispiel ist verfügbar, das eine holografische Anwendungsansicht enthält, die mit Remoting- und Remotinghostprojekten für Desktop-Win32, UWP DirectX und UWP mit XAML kompatibel ist.

Debughinweis: Die Holographic Remoting-Bibliothek kann Ausnahmen der ersten Chance auslösen. Diese Ausnahmen können in Debugsitzungen sichtbar sein, je Visual Studio Ausnahmeeinstellungen, die zu diesem Zeitpunkt aktiv sind. Diese Ausnahmen werden intern von der Holographic Remoting-Bibliothek erfasst und können ignoriert werden.

Weitere Informationen