Adicionar Comunicação Remota Holográfica (HoloLens 1.ª geração)

Se não estiver familiarizado com a Comunicação Remota Holográfica, poderá querer ler a nossa descrição geral.

Importante

Este documento descreve a criação de uma aplicação anfitriã para o HoloLens 1. A aplicação anfitriã do HoloLens (1.ª geração) tem de utilizar a versão do pacote NuGet 1.x.x. Isto implica que as aplicações anfitriãs escritas para o HoloLens 1 não são compatíveis com HoloLens 2 e vice-versa.

HoloLens 2

Os programadores do HoloLens que utilizam a Comunicação Remota Holográfica terão de atualizar as suas aplicações para torná-las compatíveis com HoloLens 2. Isto requer uma nova versão do pacote Holographic Remoting NuGet. Certifique-se de que utiliza a versão 2.0.0.0 ou superior do pacote Holographic Remoting NuGet ao ligar ao Holographic Remoting Player no HoloLens 2. Caso contrário, a ligação falhará.

Nota

Pode encontrar orientações específicas para HoloLens 2 aqui.

Adicionar comunicação remota holográfica ao seu ambiente de trabalho ou aplicação UWP

Esta página descreve como adicionar a Comunicação Remota Holográfica a uma aplicação de ambiente de trabalho ou UWP.

A comunicação remota holográfica permite que a sua aplicação direcione um HoloLens com conteúdo holográfico alojado num PC de ambiente de trabalho ou num dispositivo UWP, como a Xbox One. Também tem acesso a mais recursos do sistema, tornando possível integrar vistas envolventes remotas em software de PC de secretária existente. Uma aplicação anfitriã remota recebe um fluxo de dados de entrada de um HoloLens, compõe conteúdos numa vista envolvente virtual e transmite os pacotes de conteúdo para o HoloLens. A ligação é efetuada com Wi-Fi padrão. Para utilizar a comunicação remota, utilize um pacote NuGet para adicionar comunicação remota holográfica ao seu ambiente de trabalho ou aplicação UWP e, em seguida, escreva código para processar a ligação e compor uma vista envolvente. As bibliotecas auxiliares estão incluídas no exemplo de código que simplifica a tarefa de processar a ligação do dispositivo.

Uma ligação remota típica terá até 50 ms de latência. A aplicação player pode comunicar a latência em tempo real.

Nota

Os fragmentos de código neste artigo demonstram atualmente a utilização de C++/CX em vez de C++17 compatíveis com C++/WinRT, conforme utilizado no modelo de projeto holográfico C++. Os conceitos são equivalentes para um projeto C++/WinRT, embora tenha de traduzir o código.

Obter os pacotes NuGet remoting

Siga estes passos para obter o pacote NuGet para comunicação remota holográfica e adicione uma referência do seu projeto:

  1. Aceda ao seu projeto no Visual Studio.
  2. Clique com o botão direito do rato no nó do projeto e selecione Gerir Pacotes NuGet...
  3. No painel apresentado, selecione Procurar e, em seguida, procure "Comunicação Remota Holográfica".
  4. Selecione Microsoft.Holographic.Remoting e selecione Instalar.
  5. Se a caixa de diálogo Pré-visualizar for apresentada, selecione OK.
  6. Selecione Aceito quando for apresentada a caixa de diálogo do contrato de licença.

Criar o HolographicStreamerHelpers

Em primeiro lugar, temos de adicionar uma instância de HolographicStreamerHelpers à classe que irá processar a comunicação remota.

#include <HolographicStreamerHelpers.h>

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

Também terá de controlar o estado da ligação. Se quiser compor a pré-visualização, tem de ter uma textura para a copiar. Também precisa de algumas coisas, como um bloqueio de estado de ligação, alguma forma de armazenar o endereço IP do HoloLens, etc.

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 HolographicStreamerHelpers e ligar ao HoloLens

Para ligar a um dispositivo HoloLens, crie uma instância do HolographicStreamerHelpers e ligue-se ao endereço IP de destino. Terá de definir o tamanho da moldura de vídeo para corresponder à largura e altura do ecrã do HoloLens, uma vez que a biblioteca Holographic Remoting espera que as resoluções do codificador e do descodificador correspondam exatamente.

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 ligação do dispositivo é assíncrona. A sua aplicação tem de fornecer processadores de eventos para eventos de ligação, desconexão e envio de fotogramas.

O evento OnConnected pode atualizar a IU, iniciar a composição, etc. No nosso exemplo de código de ambiente de trabalho, atualizamos o título da janela com uma mensagem "ligada".

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

O evento OnDisconnected pode processar a restabelecimento de ligação, as atualizações da IU, etc. Neste exemplo, voltaremos a ligar se ocorrer uma falha transitória.

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 estiver pronto para enviar uma moldura, é dada à sua aplicação a oportunidade de fazer uma cópia do mesmo no SendFrameEvent. Aqui, copiamos a moldura para uma cadeia de troca para que possamos apresentá-la numa janela de pré-visualização.

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

Compor conteúdo holográfico

Para compor conteúdo através da comunicação remota, configure um IFrameworkView virtual no seu ambiente de trabalho ou aplicação UWP e processe frames holográficos da comunicação remota. Todas as APIs do Windows Holographic são utilizadas da mesma forma por esta vista, mas estão configuradas de forma ligeiramente diferente.

Em vez de os criar, o espaço holográfico e os componentes de voz são provenientes da sua classe HolographicRemotingHelpers:

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

Em vez de utilizar um ciclo de atualização num método Run, fornece atualizações de tique a partir do ciclo principal do ambiente de trabalho ou da aplicação UWP. Isto permite que o seu ambiente de trabalho ou aplicação UWP se mantenham no controlo do processamento de mensagens.

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

       // display preview, etc.
   }

O método Tick() da vista de aplicação holográfica conclui uma iteração da atualização, desenho e ciclo presente.

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

A atualização, a composição e o ciclo presente da vista de aplicações holográficas são exatamente os mesmos que são quando são executados no HoloLens, exceto que tem acesso a uma quantidade muito maior de recursos do sistema no pc de secretária. Pode compor muitos mais triângulos, ter mais passes de desenho, fazer mais física e utilizar processos x64 para carregar conteúdo que requer mais de 2 GB de RAM.

Desligar e terminar a sessão remota

Para desligar - por exemplo, quando o utilizador clica num botão de IU para desligar - chame Disconnect() no HolographicStreamerHelpers e, em seguida, solte o objeto.

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 jogador de comunicação remota

O leitor de comunicação remota do Windows Holographic é oferecido na loja de aplicações do Windows como um ponto final para comunicação remota de aplicações anfitriãs às quais ligar. Para obter o leitor de comunicação remota do Windows Holographic, visite a loja de aplicações do Windows a partir do HoloLens, procure Remoting e transfira a aplicação. O leitor de comunicação remota inclui uma funcionalidade para apresentar estatísticas no ecrã, o que pode ser útil ao depurar aplicações anfitriãs remotas.

Notas e recursos

A vista de aplicação holográfica precisará de uma forma de fornecer a sua aplicação com o dispositivo Direct3D, que tem de ser utilizado para inicializar o espaço holográfico. A sua aplicação deve utilizar este dispositivo Direct3D para copiar e apresentar a moldura de pré-visualização.

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

Exemplo de código: Está disponível um exemplo de código Holographic Remoting completo, que inclui uma vista de aplicação holográfica compatível com projetos anfitriões remoting e remoting para o ambiente de trabalho Win32, UWP DirectX e UWP com XAML.

Nota de depuração: A biblioteca Holographic Remoting pode gerar exceções de primeira oportunidade. Estas exceções podem estar visíveis em sessões de depuração, consoante as definições de exceção do Visual Studio que estão ativas no momento. Estas exceções são detetados internamente pela biblioteca Holographic Remoting e podem ser ignoradas.

Consulte também