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

Se você não estiver familiarizado com a Comunicação Remota Holográfica, talvez queira ler nossa visão geral.

Importante

Este documento descreve a criação de um aplicativo host para o HoloLens 1. O aplicativo host para HoloLens (1ª geração) deve usar o pacote NuGet versão 1.x.x. Isso implica que os aplicativos host gravados para o HoloLens 1 não são compatíveis com HoloLens 2 e vice-versa.

HoloLens 2

Os desenvolvedores do HoloLens que usam a Comunicação Remota Holográfica precisarão atualizar seus aplicativos para torná-los compatíveis com HoloLens 2. Isso requer uma nova versão do pacote NuGet de Comunicação Remota Holográfica. Use a versão 2.0.0.0 ou superior do pacote NuGet de Comunicação Remota Holográfica ao se conectar ao Holographic Remoting Player no HoloLens 2. Caso contrário, a conexão falhará.

Observação

Diretrizes específicas para HoloLens 2 podem ser encontradas aqui.

Adicionar comunicação remota holográfica à sua área de trabalho ou aplicativo UWP

Esta página descreve como adicionar a Comunicação Remota Holográfica a um aplicativo da área de trabalho ou UWP.

A comunicação remota holográfica permite que seu aplicativo direcione um HoloLens com conteúdo holográfico hospedado em um computador desktop ou em um dispositivo UWP, como o Xbox One. Você também tem acesso a mais recursos do sistema, possibilitando a integração de exibições imersivas remotas ao software de computador da área de trabalho existente. 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 imersiva virtual e transmite quadros de conteúdo de volta para o HoloLens. A conexão é feita usando Wi-Fi padrão. Para usar a comunicação remota, use um pacote NuGet para adicionar comunicação remota holográfica à sua área de trabalho ou aplicativo UWP e escreva código para lidar com a conexão e renderizar uma exibição imersiva. As bibliotecas auxiliares são incluídas no exemplo de código que simplifica a tarefa de lidar com a conexão do dispositivo.

Uma conexão remota típica terá até 50 ms de latência. O aplicativo player pode relatar a latência em tempo real.

Observação

Os snippets de código neste artigo demonstram atualmente o uso do C++/CX em vez do C++17 compatível com C++/WinRT, conforme usado no modelo de projeto holográfico do C++. Os conceitos são equivalentes a um projeto C++/WinRT, embora você precise traduzir o código.

Obter os pacotes NuGet de comunicação remota

Siga estas etapas para obter o pacote NuGet para comunicação remota holográfica e adicionar uma referência do seu projeto:

  1. Acesse seu projeto no Visual Studio.
  2. Clique com o botão direito do mouse no nó do projeto e selecione Gerenciar Pacotes NuGet...
  3. No painel exibido, selecione Procurar e, em seguida, pesquise "Comunicação Remota Holográfica".
  4. Selecione Microsoft.Holographic.Remoting e selecione Instalar.
  5. Se a caixa de diálogo Visualizar for exibida, selecione OK.
  6. Selecione Aceito quando a caixa de diálogo do contrato de licença for exibida.

Criar o HolographicStreamerHelpers

Primeiro, precisamos adicionar uma instância do HolographicStreamerHelpers à classe que manipulará a comunicação remota.

#include <HolographicStreamerHelpers.h>

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

Você também precisará acompanhar o estado da conexão. Se você quiser renderizar a visualização, precisará ter uma textura para a qual copiá-la. 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.

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 HoloLens

Para se conectar a um dispositivo HoloLens, crie uma instância do HolographicStreamerHelpers e conecte-se ao endereço IP de destino. 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 Holográfica espera que as resoluções de codificador e decodificador 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 conexão do dispositivo é assíncrona. Seu aplicativo precisa fornecer manipuladores de eventos para conectar, desconectar e enviar quadros de eventos.

O evento OnConnected pode atualizar a interface do usuário, iniciar a renderização e assim por diante. Em nosso exemplo de código da área de trabalho, atualizamos o título da janela com uma mensagem "conectada".

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

O evento OnDisconnected pode lidar com reconexão, atualizações de interface do usuário e assim por diante. Neste exemplo, nos reconectamos se houver 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 um quadro, seu aplicativo terá a oportunidade de fazer uma cópia dele no SendFrameEvent. Aqui, copiamos o quadro para uma cadeia de troca para que possamos exibi-lo em uma janela de 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));
               }
           });

Renderizar conteúdo holográfico

Para renderizar conteúdo usando comunicação remota, configure um IFrameworkView virtual em seu aplicativo da área de trabalho ou UWP e processe quadros holográficos da comunicação remota. Todas as APIs Holográficas do Windows são usadas da mesma maneira por essa exibição, mas elas são configuradas de maneira ligeiramente diferente.

Em vez de criá-los por conta própria, os componentes de espaço holográfico e de fala vêm da classe HolographicRemotingHelpers:

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

Em vez de usar um loop de atualização em um método Run, você fornece atualizações de escala do loop main da área de trabalho ou do aplicativo UWP. Isso permite que seu aplicativo da área de trabalho ou UWP permaneça no controle do processamento de mensagens.

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

       // display preview, etc.
   }

O método Tick() do modo de exibição de aplicativo holográfico conclui uma iteração do loop de atualização, desenho e 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);
           }
       }
   }

O loop de atualização, renderização e presente do modo de exibição de aplicativo holográfico é exatamente o mesmo que é quando executado no HoloLens , exceto que você tem acesso a uma quantidade muito maior de recursos do sistema em seu computador desktop. Você pode renderizar muito mais triângulos, ter mais passagens de desenho, fazer mais física e usar processos x64 para carregar conteúdo que requer mais de 2 GB de RAM.

Desconectar e encerrar a sessão remota

Para desconectar - por exemplo, quando o usuário clica em um botão de interface do usuário para desconectar - chame Disconnect() no HolographicStreamerHelpers e 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 player de comunicação remota do Windows Holographic é oferecido na loja de aplicativos do Windows como um ponto de extremidade para aplicativos host de comunicação remota se conectarem. Para obter o player de comunicação remota do Windows Holographic, visite a loja de aplicativos do Windows em seu HoloLens, pesquise Comunicação Remota e baixe o aplicativo. O player de comunicação remota inclui um recurso para exibir estatísticas na tela, o que pode ser útil ao depurar aplicativos host de comunicação remota.

Anotações e recursos

A exibição do aplicativo holográfico precisará de uma maneira de fornecer ao seu aplicativo o dispositivo Direct3D, que deve ser usado para inicializar o espaço holográfico. Seu aplicativo deve usar esse dispositivo Direct3D para copiar e exibir o quadro de visualização.

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

Exemplo de código: Um exemplo completo de código de Comunicação Remota Holográfica está disponível, que inclui uma exibição de aplicativo holográfico compatível com projetos de host de comunicação remota e comunicação remota para área de trabalho Win32, UWP DirectX e UWP com XAML.

Observação de depuração: A biblioteca de Comunicação Remota Holográfica pode gerar exceções de primeira chance. Essas exceções podem estar visíveis em sessões de depuração, dependendo das configurações de exceção do Visual Studio que estão ativas no momento. Essas exceções são capturadas internamente pela biblioteca de Comunicação Remota Holográfica e podem ser ignoradas.

Consulte Também