Escrevendo um aplicativo Holográfico Remoting Player personalizado
Se você é novo no Holographic Remoting, você pode querer ler nossa visão geral.
Importante
Este documento descreve a criação de um aplicativo de player personalizado para HoloLens 2. Os leitores personalizados escritos para HoloLens 2 não são compatíveis com aplicações remotas escritas para HoloLens 1. Isso implica que ambos os aplicativos devem usar o pacote NuGet versão 2.x.x.
Ao criar um aplicativo de player holográfico personalizado, você pode criar um aplicativo personalizado capaz de exibir vistas imersivas de uma máquina remota no seu HoloLens 2. Todo o código nesta página e projetos de trabalho podem ser encontrados no repositório github de amostras Holográficas Remotas.
Um player de comunicação remota holográfica permite que seu aplicativo exiba conteúdo holográfico renderizado em um computador desktop ou dispositivo UWP, como o Xbox One, com acesso a mais recursos do sistema. Um aplicativo Holographic Remoting player transmite dados de entrada para um aplicativo remoto Holographic Remoting e recebe de volta uma visão imersiva como fluxo de vídeo e áudio. A conexão é feita usando Wi-Fi padrão. Para criar um aplicativo de jogador, use um pacote NuGet para adicionar a comunicação remota holográfica ao seu aplicativo UWP. Em seguida, escreva o código para lidar com a conexão e exibir uma visão imersiva.
Pré-requisitos
Um bom ponto de partida é um aplicativo UWP baseado em DirectX que já tem como alvo a API do Windows Mixed Reality. Para obter detalhes, consulte Visão geral do desenvolvimento do DirectX. Se você não tem um aplicativo existente e quer começar do zero, o modelo de projeto holográfico C++ é um bom ponto de partida.
Importante
Qualquer aplicativo que use comunicação remota holográfica deve ser criado para usar um apartamento multi-threaded. O uso de um apartamento de thread único é suportado, mas levará a um desempenho abaixo do ideal e, possivelmente, gagueira durante a reprodução. Ao usar C++/WinRT winrt::init_apartment um apartamento multi-threaded é o padrão.
Obtenha o pacote NuGet de comunicação remota holográfica
As etapas a seguir são necessárias para adicionar o pacote NuGet a um projeto no Visual Studio.
- Abra o projeto no Visual Studio.
- Clique com o botão direito do mouse no nó do projeto e selecione Gerenciar pacotes NuGet...
- No painel que aparece, selecione Procurar e, em seguida, procure por "Comunicação Remota Holográfica".
- Selecione Microsoft.Holographic.Remoting, certifique-se de escolher a versão 2.x.x mais recente e selecione Instalar.
- Se a caixa de diálogo Visualizar for exibida, selecione OK.
- Selecione Aceito quando a caixa de diálogo do contrato de licença for exibida.
Importante
O build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl
pacote interno do NuGet contém documentação detalhada para a API exposta pela comunicação remota holográfica.
Modificar o Package.appxmanifest do aplicativo
Para tornar o aplicativo ciente dos Microsoft.Holographic.AppRemoting.dll adicionados pelo pacote NuGet, as seguintes etapas precisam ser executadas no projeto:
- No Gerenciador de Soluções, clique com o botão direito do mouse no arquivo Package.appxmanifest e selecione Abrir com...
- Selecione XML (Texto) Editor e selecione OK
- Adicione as seguintes linhas ao ficheiro e guarde
</Capabilities>
<!--Add lines below -->
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>Microsoft.Holographic.AppRemoting.dll</Path>
<ActivatableClass ActivatableClassId="Microsoft.Holographic.AppRemoting.PlayerContext" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
<!--Add lines above -->
</Package>
Criar o contexto do jogador
Como primeiro passo, a aplicação deve criar um contexto de jogador.
// class declaration:
#include <winrt/Microsoft.Holographic.AppRemoting.h>
...
private:
// PlayerContext used to connect with a Holographic Remoting remote app and display remotely rendered frames
winrt::Microsoft::Holographic::AppRemoting::PlayerContext m_playerContext = nullptr;
// class implementation:
// Create the player context
// IMPORTANT: This must be done before creating the HolographicSpace (or any other call to the Holographic API).
m_playerContext = winrt::Microsoft::Holographic::AppRemoting::PlayerContext::Create();
Aviso
Um player personalizado injeta uma camada intermediária entre o aplicativo player e o tempo de execução do Windows Mixed Reality fornecido com o Windows. Isto é feito durante a criação do contexto do jogador. Por esse motivo, qualquer chamada em qualquer API do Windows Mixed Reality antes de criar o contexto do player pode resultar em um comportamento inesperado. A abordagem recomendada é criar o contexto do jogador o mais cedo possível antes da interação com qualquer API de Realidade Mista. Nunca misture objetos criados ou recuperados por meio de qualquer API do Windows Mixed Reality antes da chamada com PlayerContext::Create
objetos criados ou recuperados posteriormente.
Em seguida, o HolographicSpace pode ser criado, chamando HolographicSpace.CreateForCoreWindow.
m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(window);
Conectar-se ao aplicativo remoto
Quando o aplicativo player estiver pronto para renderizar conteúdo, uma conexão com o aplicativo remoto poderá ser estabelecida.
A conexão pode ser estabelecida de uma das seguintes maneiras:
- O aplicativo player executado no HoloLens 2 se conecta ao aplicativo remoto.
- O aplicativo remoto se conecta ao aplicativo player em execução no HoloLens 2.
Para se conectar do aplicativo player ao aplicativo remoto, chame o Connect
método no contexto do player especificando o nome do host e a porta. A porta padrão é 8265.
try
{
m_playerContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
// Failed to connect. Get an error details via e.code() and e.message()
}
Importante
Como com qualquer API Connect
C++/WinRT pode lançar um winrt::hresult_error que precisa ser manipulado.
A escuta de conexões de entrada no aplicativo player pode ser feita chamando o Listen
método. Tanto a porta de handshake quanto a porta de transporte podem ser especificadas durante esta chamada. A porta de handshake é usada para o handshake inicial. Os dados são então enviados pela porta de transporte. Por padrão, são usados os números de porta 8265 e 8266 .
try
{
m_playerContext.Listen(L"0.0.0.0", m_port, m_port + 1);
}
catch(winrt::hresult_error& e)
{
// Failed to listen. Get an error details via e.code() and e.message()
}
Manipulando eventos relacionados à conexão
O PlayerContext
expõe três eventos para monitorar o estado da conexão
- OnConnected: acionado quando uma conexão com o aplicativo remoto foi estabelecida com êxito.
m_onConnectedEventToken = m_playerContext.OnConnected([]()
{
// Handle connection successfully established
});
- OnDisconnected: acionado se uma conexão estabelecida for encerrada ou uma conexão não puder ser estabelecida.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
switch (failureReason)
{
// Handle connection failed or terminated.
// See ConnectionFailureReason for possible reasons.
}
}
Nota
Os valores possíveis ConnectionFailureReason
estão documentados no Microsoft.Holographic.AppRemoting.idl
arquivo.
- OnListening: Quando a escuta de conexões de entrada é iniciada.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
// Handle start listening for incoming connections
});
Além disso, o estado da conexão pode ser consultado usando a ConnectionState
propriedade no contexto do player.
winrt::Microsoft::Holographic::AppRemoting::ConnectionState state = m_playerContext.ConnectionState();
Exibir o quadro renderizado remotamente
Para exibir o conteúdo renderizado remotamente, chame PlayerContext::BlitRemoteFrame
enquanto renderiza um HolographicFrame.
BlitRemoteFrame
requer que o buffer traseiro para o HolographicFrame atual esteja vinculado como destino de renderização. O buffer traseiro pode ser recebido do HolographicCameraRenderingParameters por meio da propriedade Direct3D11BackBuffer .
Quando chamado, BlitRemoteFrame
copia o último quadro recebido do aplicativo remoto para o BackBuffer do HolographicFrame. Além disso, o conjunto de pontos de foco é definido se o aplicativo remoto tiver especificado um ponto de foco durante a renderização do quadro remoto.
// Blit the remote frame into the backbuffer for the HolographicFrame.
winrt::Microsoft::Holographic::AppRemoting::BlitResult result = m_playerContext.BlitRemoteFrame();
Nota
PlayerContext::BlitRemoteFrame
potencialmente substitui o ponto de foco para o quadro atual.
- Para especificar um ponto de foco de fallback, chame HolographicCameraRenderingParameters::SetFocusPoint antes de
PlayerContext::BlitRemoteFrame
. - Para substituir o ponto de foco remoto, chame HolographicCameraRenderingParameters::SetFocusPoint após
PlayerContext::BlitRemoteFrame
.
Sobre o sucesso, BlitRemoteFrame
retorna BlitResult::Success_Color
. Caso contrário, ele retorna o motivo da falha:
BlitResult::Failed_NoRemoteFrameAvailable
: Falha porque nenhum quadro remoto está disponível.BlitResult::Failed_NoCamera
: Falhou porque nenhuma câmera está presente.BlitResult::Failed_RemoteFrameTooOld
: Falhou porque o quadro remoto é muito antigo (consulte a propriedade PlayerContext::BlitRemoteFrameTimeout).
Importante
A partir da versão 2.1.0 é possível com um leitor personalizado utilizar a reprojeção de profundidade através da comunicação remota holográfica.
BlitResult
pode também devolver BlitResult::Success_Color_Depth
nas seguintes condições:
- O aplicativo remoto confirmou um buffer de profundidade via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer.
- O aplicativo player personalizado vinculou um buffer de profundidade válido antes de chamar
BlitRemoteFrame
o .
Se essas condições forem atendidas, BlitRemoteFrame
a profundidade remota será transferida para o buffer de profundidade local atualmente vinculado. Em seguida, você pode renderizar conteúdo local adicional, que terá interseção de profundidade com o conteúdo renderizado remoto. Além disso, você pode confirmar o buffer de profundidade local via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer em seu player personalizado para ter reprojeção de profundidade para conteúdo renderizado remoto e local.
Modo de Transformação de Projeção
Um problema, que aparece ao usar a reprojeção de profundidade via comunicação remota holográfica, é que o conteúdo remoto pode ser renderizado com uma transformação de projeção diferente do conteúdo local renderizado diretamente pelo seu aplicativo player personalizado. Um caso de uso comum é especificar valores diferentes para o plano próximo e distante (via HolographicCamera::SetNearPlaneDistance e HolographicCamera::SetFarPlaneDistance) no lado do jogador e no lado remoto. Neste caso, não está claro se a transformação de projeção no lado do jogador deve refletir as distâncias planas remotas próximas/distantes ou as distâncias locais.
A partir da versão 2.1.0 , você pode controlar o modo de transformação de projeção via PlayerContext::ProjectionTransformConfig
. Os valores suportados são:
Local
- HolographicCameraPose::P rojectionTransform retorna uma transformação de projeção, que reflete as distâncias de plano próximas/distantes definidas pelo seu aplicativo player personalizado na HolographicCamera.Remote
- A transformação de projeção reflete as distâncias do plano próximo/distante especificadas pelo aplicativo remoto.Merged
- As distâncias de avião próximas/distantes do seu aplicativo remoto e do seu aplicativo de jogador personalizado são mescladas. Por padrão, isso é feito tomando o mínimo das distâncias de plano próximo e o máximo das distâncias de plano distante. No caso de o lado remoto ou local estar invertido, digamos muito < perto, as distâncias do plano remoto perto/longe são invertidas.
Opcional: Definir BlitRemoteFrameTimeout
Importante
PlayerContext::BlitRemoteFrameTimeout
é suportado a partir da versão 2.0.9.
A PlayerContext::BlitRemoteFrameTimeout
propriedade especifica a quantidade de tempo que um quadro remoto é reutilizado se nenhum novo quadro remoto for recebido.
Um caso de uso comum é habilitar o tempo limite de BlitRemoteFrame para exibir uma tela em branco se nenhum novo quadro for recebido por um determinado período de tempo. Quando habilitado, o tipo de retorno do BlitRemoteFrame
método também pode ser usado para alternar para um conteúdo de fallback renderizado localmente.
Para habilitar o tempo limite, defina o valor da propriedade para uma duração igual ou maior que 100 ms. Para desativar o tempo limite, defina a propriedade como duração zero. Se o tempo limite estiver ativado e nenhum quadro remoto for recebido para a duração definida, o BlitRemoteFrame falhará e retornará Failed_RemoteFrameTooOld
até que um novo quadro remoto seja recebido.
using namespace std::chrono_literals;
// Set the BlitRemoteFrame timeout to 0.5s
m_playerContext.BlitRemoteFrameTimeout(500ms);
Opcional: Obter estatísticas sobre o último quadro remoto
Para diagnosticar problemas de desempenho ou de rede, as estatísticas sobre o último quadro remoto podem ser recuperadas através da PlayerContext::LastFrameStatistics
propriedade. As estatísticas são atualizadas durante a chamada para HolographicFrame::P resentUsingCurrentPrediction.
// Get statistics for the last presented frame.
winrt::Microsoft::Holographic::AppRemoting::PlayerFrameStatistics statistics = m_playerContext.LastFrameStatistics();
Para obter mais informações, consulte a PlayerFrameStatistics
documentação no Microsoft.Holographic.AppRemoting.idl
arquivo.
Opcional: canais de dados personalizados
Canais de dados personalizados podem ser usados para enviar dados do usuário através da conexão remota já estabelecida. Para obter mais informações, consulte Canais de dados personalizados.
Opcional: Renderização excessiva
A comunicação remota holográfica prevê onde estará a cabeça do utilizador no momento em que as imagens renderizadas aparecerem nos ecrãs. No entanto, esta previsão é uma aproximação. Portanto, a janela de visualização prevista no aplicativo remoto e a janela de visualização real posterior no aplicativo player podem ser diferentes. Desvios mais fortes (por exemplo, devido a um movimento imprevisível) podem causar regiões negras nas bordas do frustum de visualização. A partir da versão 2.6.0 , você pode usar a renderização excessiva para reduzir as regiões pretas e melhorar a qualidade visual, aumentando artificialmente a janela de visualização além do frustum de visualização.
A renderização excessiva pode ser ativada via PlayerContext::ConfigureOverRendering
.
O OverRenderingConfig
especifica um aumento de tamanho fracionado para o visor real, para que o visor previsto se torne maior e ocorra menos corte.
Com um tamanho de visor aumentado, a densidade de pixels diminui, portanto, o OverRenderingConfig permite que você aumente a resolução também.
Se o aumento da janela de visualização for igual ao aumento da resolução, a densidade de pixels permanecerá a mesma.
OverRenderingConfig
define-se como:
struct OverRenderingConfig
{
float HorizontalViewportIncrease; // The fractional horizontal viewport increase. (e.g. 10% -> 0.1).
float VerticalViewportIncrease; // The fractional vertical viewport increase. (e.g. 10% -> 0.1).
float HorizontalResolutionIncrease; // The fractional horizontal resolution increase. (e.g. 10% -> 0.1).
float VerticalResolutionIncrease; // The fractional vertical resolution increase. (e.g. 10% -> 0.1).
};
Opcional: Coordenar a sincronização do sistema
A partir da versão 2.7.0 , a sincronização do sistema de coordenadas pode ser usada para alinhar dados espaciais entre o player e o aplicativo remoto. Para obter mais informações, consulte Visão geral da sincronização do sistema de coordenadas com comunicação remota holográfica.
Consulte Também
- Visão geral da comunicação remota holográfica
- Escrevendo um aplicativo remoto de comunicação remota holográfica usando APIs do Windows Mixed Reality
- Escrevendo um aplicativo remoto Holographic Remoting usando APIs OpenXR
- Canais de dados holográficos personalizados
- Estabelecendo uma conexão segura com a comunicação remota holográfica
- Solução de problemas e limitações da comunicação remota holográfica
- Termos de licença do software Holographic Remoting
- Declaração de Privacidade da Microsoft