Adicionar comunicação remota Holographic (HoloLens (1ª gen))Add Holographic Remoting (HoloLens (1st gen))

Importante

Este documento descreve a criação de um aplicativo host para o HoloLens 1.This document describes the creation of a host application for HoloLens 1. O aplicativo de host para o HoloLens (1º gen) deve usar o pacote NuGet versão 1. x. x.Host application for HoloLens (1st gen) must use NuGet package version 1.x.x. Isso implica que os aplicativos host escritos para o HoloLens 1 não são compatíveis com o HoloLens 2 e vice-versa.This implies that host applications written for HoloLens 1 are not compatible with HoloLens 2 and vice versa.

HoloLens 2HoloLens 2

Os desenvolvedores de HoloLens que usam a comunicação remota do Holographic precisarão atualizar seus aplicativos para torná-los compatíveis com o HoloLens 2.HoloLens developers using Holographic Remoting will need to update their apps to make them compatible with HoloLens 2. Isso requer uma nova versão do pacote NuGet de comunicação remota do Holographic.This requires a new version of the Holographic Remoting NuGet package. Se um aplicativo que usa o pacote NuGet de comunicação remota do Holographic com um número de versão menor do que o 2.0.0.0 tentar se conectar ao Player de comunicação remota do Holographic no HoloLens 2, a conexão falhará.If an application using the Holographic Remoting NuGet package with a version number smaller than 2.0.0.0 attempts to connect to the Holographic Remoting Player on HoloLens 2, the connection will fail.

Observação

As diretrizes específicas para o HoloLens 2 podem ser encontradas aqui.Guidance specific to HoloLens 2 can be found here.

Adicionar a comunicação remota do Holographic ao seu aplicativo da área de trabalho ou UWPAdd holographic remoting to your desktop or UWP app

Esta página descreve como adicionar o Holographic Remoting a um aplicativo desktop ou UWP.This page describes how to add Holographic Remoting to a desktop or UWP app.

A comunicação remota do Holographic permite que seu aplicativo direcione um HoloLens com conteúdo Holographic hospedado em um PC desktop ou em um dispositivo UWP, como o Xbox One, permitindo o acesso a mais recursos do sistema e possibilitando a integração de exibições de imersão remotas ao software de PC desktop existente.Holographic remoting allows your app to target a HoloLens with holographic content hosted on a desktop PC or on a UWP device such as the Xbox One, allowing access to more system resources and making it possible to integrate remote immersive views into existing desktop PC software. Um aplicativo host de comunicação remota recebe um fluxo de dados de entrada de um HoloLens, renderiza o conteúdo em uma exibição de imersão virtual e transmite quadros de conteúdo de volta para o HoloLens.A remoting host app receives an input data stream from a HoloLens, renders content in a virtual immersive view, and streams content frames back to HoloLens. A conexão é feita usando Wi-Fi padrão.The connection is made using standard Wi-Fi. Para usar a comunicação remota, você usará um pacote NuGet para adicionar o Holographic Remoting ao seu aplicativo de área de trabalho ou UWP e escreverá código para lidar com a conexão e para renderizar em uma exibição de imersão.To use remoting, you will use a NuGet package to add holographic remoting to your desktop or UWP app, and write code to handle the connection and to render in an immersive view. As bibliotecas auxiliares são incluídas no exemplo de código que simplificam a tarefa de lidar com a conexão do dispositivo.Helper libraries are included in the code sample that simplify the task of handling the device connection.

Uma conexão de comunicação remota típica terá um mínimo de 50 ms de latência.A typical remoting connection will have as low as 50 ms of latency. O aplicativo de player pode relatar a latência em tempo real.The player app can report the latency in real-time.

Observação

Os trechos de código neste artigo demonstram atualmente o C++uso de/CX em vez de/WinRT em C++conformidade com C + +17, conforme usado no C++ modelo de projeto Holographic.The code snippets in this article currently demonstrate use of C++/CX rather than C++17-compliant C++/WinRT as used in the C++ holographic project template. Os conceitos são equivalentes a C++um projeto/WinRT, embora você precise converter o código.The concepts are equivalent for a C++/WinRT project, though you will need to translate the code.

Obter os pacotes de NuGet de comunicação remotaGet the remoting NuGet packages

Siga estas etapas para obter o pacote NuGet para a comunicação remota do Holographic e adicione uma referência do seu projeto:Follow these steps to get the NuGet package for holographic remoting, and add a reference from your project:

  1. Vá para seu projeto no Visual Studio.Go to your project in Visual Studio.
  2. Clique com o botão direito do mouse no nó do projeto e selecione gerenciar pacotes NuGet...Right-click on the project node and select Manage NuGet Packages...
  3. No painel que aparece, clique em procurar e procure "comunicação remota do Holographic".In the panel that appears, click Browse and then search for "Holographic Remoting".
  4. Selecione Microsoft. Holographic. Remoting e clique em instalar.Select Microsoft.Holographic.Remoting and click Install.
  5. Se a caixa de diálogo Visualizar for exibida, clique em OK.If the Preview dialog appears, click OK.
  6. A próxima caixa de diálogo exibida é o contrato de licença.The next dialog that appears is the license agreement. Clique em aceito para aceitar o contrato de licença.Click on I Accept to accept the license agreement.

Criar o HolographicStreamerHelpersCreate the HolographicStreamerHelpers

Primeiro, precisamos de uma instância de HolographicStreamerHelpers.First, we need an instance of HolographicStreamerHelpers. Adicione isso à classe que tratará de comunicação remota.Add this to the class that will be handling remoting.

#include <HolographicStreamerHelpers.h>

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

Você também precisará acompanhar o estado da conexão.You'll also need to track connection state. Se você quiser renderizar a visualização, precisará ter uma textura para copiá-la para.If you want to render the preview, you need to have a texture to copy it to. Você também precisa de algumas coisas como um bloqueio de estado de conexão, alguma maneira de armazenar o endereço IP do HoloLens e assim por diante.You also need a few things like a connection state lock, some way of storing the IP address of HoloLens, and so on.

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;

Inicializar o HolographicStreamerHelpers e conectar-se ao HoloLensInitialize HolographicStreamerHelpers and connect to HoloLens

Para se conectar a um dispositivo HoloLens, crie uma instância do HolographicStreamerHelpers e conecte-se ao endereço IP de destino.To connect to a HoloLens device, create an instance of HolographicStreamerHelpers and connect to the target IP address. Você precisará definir o tamanho do quadro de vídeo para corresponder à largura e altura de exibição do HoloLens, pois a biblioteca de comunicação remota Holographic espera que as resoluções do codificador e do decodificador correspondam exatamente.You will need to set the video frame size to match the HoloLens display width and height, because the Holographic Remoting library expects the encoder and decoder resolutions to match exactly.

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

A conexão do dispositivo é assíncrona.The device connection is asynchronous. Seu aplicativo precisa fornecer manipuladores de eventos para eventos de conexão, desconexão e quadros de envio.Your app needs to provide event handlers for connect, disconnect, and frame send events.

O evento onconnected pode atualizar a interface do usuário, iniciar a renderização e assim por diante.The OnConnected event can update the UI, start rendering, and so on. Em nosso exemplo de código de área de trabalho, atualizamos o título da janela com uma mensagem "conectada".In our desktop code sample, we update the window title with a "connected" message.

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

O evento ondisconnectd pode lidar com a reconexão, as atualizações da interface do usuário e assim por diante.The OnDisconnected event can handle reconnection, UI updates, and so on. Neste exemplo, reconectamos se houver uma falha transitória.In this example, we reconnect if there is a transient failure.

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

Quando o componente de comunicação remota está pronto para enviar um quadro, seu aplicativo recebe uma oportunidade de fazer uma cópia dele no SendFrameEvent.When the remoting component is ready to send a frame, your app is provided an opportunity to make a copy of it in the SendFrameEvent. Aqui, copiamos o quadro em uma cadeia de permuta para que possamos exibi-lo em uma janela de visualização.Here, we copy the frame to a swap chain so that we can display it in a preview window.

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

Renderizar conteúdo HolographicRender holographic content

Para renderizar o conteúdo usando comunicação remota, você configura um IFrameworkView virtual em seu aplicativo de área de trabalho ou UWP e processa os quadros Holographic da comunicação remota.To render content using remoting, you set up a virtual IFrameworkView within your desktop or UWP app and process holographic frames from remoting. Todas as APIs Holographic do Windows são usadas da mesma forma por essa exibição, mas elas são configuradas de forma ligeiramente diferente.All of the Windows Holographic APIs are uses the same way by this view, but it is set up slightly differently.

Em vez de criá-los por conta própria, os componentes de espaço e fala do Holographic vêm de sua classe HolographicRemotingHelpers:Instead of creating them yourself, the holographic space and speech components come from your HolographicRemotingHelpers class:

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

Em vez de usar um loop de atualização dentro de um método Run, você fornece atualizações em escala do loop principal de seu aplicativo de desktop ou UWP.Instead of using an update loop inside of a Run method, you provide tick updates from the main loop of your desktop or UWP app. Isso permite que seu aplicativo da área de trabalho ou UWP permaneça no controle do processamento de mensagens.This allows your desktop or UWP app to remain in control of message processing.

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

       // display preview, etc.
   }

O método Tick () da exibição do aplicativo Holographic conclui uma iteração do loop Update, Draw e Present.The holographic app view's Tick() method completes one iteration of the update, draw, present loop.

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

O loop de atualização de exibição do aplicativo Holographic, render e Present é exatamente o mesmo que é quando executado no HoloLens, exceto pelo fato de que você tem acesso a uma quantidade muito maior de recursos do sistema no seu PC desktop.The holographic app view update, render, and present loop is exactly the same as it is when running on HoloLens - except that you have access to a much greater amount of system resources on your desktop PC. Você pode renderizar muitos triângulos, ter mais passagens de desenho, realizar mais física e usar processos x64 para carregar o conteúdo que exige mais de 2 GB de RAM.You can render many more triangles, have more drawing passes, do more physics, and use x64 processes to load content that requires more than 2 GB of RAM.

Desconectar e encerrar a sessão remotaDisconnect and end the remote session

Para desconectar-por exemplo, quando o usuário clica em um botão da interface do usuário para desconectar-chamada Disconnect () no HolographicStreamerHelpers e, em seguida, libera o objeto.To disconnect - for example, when the user clicks a UI button to disconnect - call Disconnect() on the HolographicStreamerHelpers, and then release the object.

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

Obter o reprodutor de comunicação remotaGet the remoting player

O player de comunicação remota do Windows Holographic é oferecido na loja de aplicativos do Windows como um ponto de extremidade para aplicativos de host remotos se conectarem ao.The Windows Holographic remoting player is offered in the Windows app store as an endpoint for remoting host apps to connect to. Para obter o Windows Holographic Remoting Player, visite a Windows App Store do seu HoloLens, pesquise por comunicação remota e baixe o aplicativo.To get the Windows Holographic remoting player, visit the Windows app store from your HoloLens, search for Remoting, and download the app. O player de comunicação remota inclui um recurso para exibir estatísticas na tela, o que pode ser útil ao depurar aplicativos de host de comunicação remota.The remoting player includes a feature to display statistics on-screen, which can be useful when debugging remoting host apps.

Notas e recursosNotes and resources

A exibição do aplicativo Holographic precisará de uma maneira de fornecer seu aplicativo com o dispositivo Direct3D, que deve ser usado para inicializar o espaço do Holographic.The holographic app view will need a way to provide your app with the Direct3D device, which must be used to initialize the holographic space. Seu aplicativo deve usar este dispositivo Direct3D para copiar e exibir o quadro de visualização.Your app should use this Direct3D device to copy and display the preview frame.

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

Exemplo de código: Um exemplo de código remoto Holographic completo está disponível, que inclui uma exibição de aplicativo Holographic compatível com projetos de host remoto e de comunicação remota para desktop Win32, UWP DirectX e UWP com XAML.Code sample: A complete Holographic Remoting code sample is available, which includes a holographic application view that is compatible with remoting and remoting host projects for desktop Win32, UWP DirectX, and UWP with XAML. Para obtê-lo, acesse:To get it, go here:

Observação de depuração: A biblioteca de comunicação remota do Holographic pode gerar exceções de primeira chance.Debugging note: The Holographic Remoting library can throw first-chance exceptions. Essas exceções podem ser visíveis em sessões de depuração, dependendo das configurações de exceção do Visual Studio que estão ativas no momento.These exceptions may be visible in debugging sessions, depending on the Visual Studio exception settings that are active at the time. Essas exceções são detectadas internamente pela biblioteca de comunicação remota do Holographic e podem ser ignoradas.These exceptions are caught internally by the Holographic Remoting library and can be ignored.