Escritura de una aplicación personalizada del Reproductor de comunicación remota holográfica
Si no está familiarizado con la comunicación remota holográfica, es posible que desee leer nuestra información general.
Importante
En este documento se describe la creación de una aplicación de reproductor personalizada para HoloLens 2. Los reproductores personalizados escritos para HoloLens 2 no son compatibles con aplicaciones remotas escritas para HoloLens 1. Esto implica que ambas aplicaciones deben usar el paquete NuGet versión 2.x.x.
Al crear una aplicación de reproductor de comunicación remota holográfica personalizada, puede crear una aplicación personalizada capaz de mostrar vistas inmersivas desde un equipo remoto en el HoloLens 2. Todo el código de esta página y los proyectos de trabajo se pueden encontrar en el repositorio de github de ejemplos de comunicación remota holográfica.
Un reproductor de comunicación remota holográfica permite que la aplicación muestre contenido holográfico representado en un equipo de escritorio o dispositivo UWP como Xbox One con acceso a más recursos del sistema. Una aplicación de reproductor de comunicación remota holográfica transmite datos de entrada a una aplicación remota de comunicación remota holográfica y recibe una vista inmersiva como secuencia de vídeo y audio. La conexión se realiza mediante Wi-Fi estándar. Para crear una aplicación de reproductor, usa un paquete NuGet para agregar comunicación remota holográfica a tu aplicación para UWP. A continuación, escriba código para controlar la conexión y mostrar una vista inmersiva.
Requisitos previos
Un buen punto de partida es una aplicación para UWP basada en DirectX que ya está destinada a la API de Windows Mixed Reality. Para obtener más información, consulte Introducción al desarrollo de DirectX. Si no tiene una aplicación existente y quiere empezar desde cero, la plantilla de proyecto holográfico de C++ es un buen punto de partida.
Importante
Cualquier aplicación que use la comunicación remota holográfica debe crearse para usar un apartamento multiproceso. El uso de un apartamento de un solo subproceso es compatible, pero dará lugar a un rendimiento sub-óptimo y posiblemente tartamudez durante la reproducción. Cuando se usa C++/WinRT winrt::init_apartment un apartamento multiproceso es el valor predeterminado.
Obtención del paquete NuGet de comunicación remota holográfica
Los pasos siguientes son necesarios para agregar el paquete NuGet a un proyecto de Visual Studio.
- Abra el proyecto en Visual Studio.
- Haga clic con el botón derecho en el nodo del proyecto y seleccione Administrar paquetes NuGet...
- En el panel que aparece, seleccione Examinar y busque "Comunicación remota holográfica".
- Seleccione Microsoft.Holographic.Remoting, asegúrese de elegir la versión 2.x.x más reciente y seleccione Instalar.
- Si aparece el cuadro de diálogo Vista previa , seleccione Aceptar.
- Seleccione Acepto cuando aparezca el cuadro de diálogo del contrato de licencia.
Importante
Dentro build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl
del paquete NuGet contiene documentación detallada para la API expuesta por Holographic Remoting.
Modificación del archivo Package.appxmanifest de la aplicación
Para que la aplicación tenga en cuenta los Microsoft.Holographic.AppRemoting.dll agregados por el paquete NuGet, es preciso realizar los pasos siguientes en el proyecto:
- En el Explorador de soluciones, haga clic con el botón derecho en el archivo Package.appxmanifest y seleccione Abrir con...
- Seleccione XML (texto) Editor y seleccione Aceptar.
- Agregue las líneas siguientes al archivo y 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>
Creación del contexto del reproductor
Como primer paso, la aplicación debe crear un contexto de reproductor.
// 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();
Advertencia
Un reproductor personalizado inserta una capa intermedia entre la aplicación del reproductor y el entorno de ejecución de Windows Mixed Reality que se incluye con Windows. Esto se hace durante la creación del contexto del jugador. Por ese motivo, cualquier llamada a cualquier API de Windows Mixed Reality antes de crear el contexto del reproductor puede dar lugar a un comportamiento inesperado. El enfoque recomendado es crear el contexto del reproductor lo antes posible antes de interactuar con cualquier API de Mixed Reality. Nunca mezcle objetos creados o recuperados a través de ninguna API de Windows Mixed Reality antes de la llamada a PlayerContext::Create
con objetos creados o recuperados posteriormente.
A continuación, se puede crear HolographicSpace llamando a HolographicSpace.CreateForCoreWindow.
m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(window);
Conexión a la aplicación remota
Una vez que la aplicación del reproductor está lista para representar contenido, se puede establecer una conexión a la aplicación remota.
La conexión se puede establecer de una de las siguientes maneras:
- La aplicación del reproductor que se ejecuta en HoloLens 2 se conecta a la aplicación remota.
- La aplicación remota se conecta a la aplicación del reproductor que se ejecuta en HoloLens 2.
Para conectarse desde la aplicación del reproductor a la aplicación remota, llame al Connect
método en el contexto del reproductor especificando el nombre de host y el puerto. El puerto predeterminado es 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
Al igual que con cualquier API Connect
de C++/WinRT, podría producir un winrt::hresult_error que se debe controlar.
La escucha de conexiones entrantes en la aplicación del reproductor se puede realizar llamando al Listen
método . Tanto el puerto de protocolo de enlace como el puerto de transporte se pueden especificar durante esta llamada. El puerto de protocolo de enlace se usa para el protocolo de enlace inicial. A continuación, los datos se envían a través del puerto de transporte. De forma predeterminada, se usan los números de puerto 8265 y 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()
}
Control de eventos relacionados con la conexión
PlayerContext
expone tres eventos para supervisar el estado de la conexión.
- OnConnected: se desencadena cuando se ha establecido correctamente una conexión a la aplicación remota.
m_onConnectedEventToken = m_playerContext.OnConnected([]()
{
// Handle connection successfully established
});
- OnDisconnected: se desencadena si se finaliza una conexión establecida o no se puede establecer una conexión.
m_onDisconnectedEventToken = m_playerContext.OnDisconnected([](ConnectionFailureReason failureReason)
{
switch (failureReason)
{
// Handle connection failed or terminated.
// See ConnectionFailureReason for possible reasons.
}
}
Nota:
Los valores posibles ConnectionFailureReason
se documentan en el Microsoft.Holographic.AppRemoting.idl
archivo.
- OnListening: cuando se inicia la escucha de conexiones entrantes.
m_onListeningEventToken = m_playerContext.OnListening([]()
{
// Handle start listening for incoming connections
});
Además, el estado de conexión se puede consultar mediante la ConnectionState
propiedad en el contexto del reproductor.
winrt::Microsoft::Holographic::AppRemoting::ConnectionState state = m_playerContext.ConnectionState();
Mostrar el marco representado de forma remota
Para mostrar el contenido representado de forma remota, llame a PlayerContext::BlitRemoteFrame
al representar un HolographicFrame.
BlitRemoteFrame
requiere que el búfer de retroceso del holographicFrame actual esté enlazado como destino de representación. El búfer de reserva se puede recibir desde HolographicCameraRenderingParameters a través de la propiedad Direct3D11BackBuffer .
Cuando se le llama, BlitRemoteFrame
copia el fotograma recibido más reciente de la aplicación remota en el BackBuffer del HolographicFrame. Además, se establece el conjunto de puntos de enfoque, si la aplicación remota ha especificado un punto de enfoque durante la representación del marco remoto.
// Blit the remote frame into the backbuffer for the HolographicFrame.
winrt::Microsoft::Holographic::AppRemoting::BlitResult result = m_playerContext.BlitRemoteFrame();
Nota:
PlayerContext::BlitRemoteFrame
potencialmente sobrescribe el punto de enfoque para el marco actual.
- Para especificar un punto de enfoque de reserva, llame a HolographicCameraRenderingParameters::SetFocusPoint antes de
PlayerContext::BlitRemoteFrame
. - Para sobrescribir el punto de enfoque remoto, llame a HolographicCameraRenderingParameters::SetFocusPoint después de
PlayerContext::BlitRemoteFrame
.
Si se realiza correctamente, BlitRemoteFrame
devuelve BlitResult::Success_Color
. De lo contrario, devuelve el motivo del error:
-
BlitResult::Failed_NoRemoteFrameAvailable
: error porque no hay ningún marco remoto disponible. -
BlitResult::Failed_NoCamera
: se produjo un error porque no hay ninguna cámara presente. -
BlitResult::Failed_RemoteFrameTooOld
: error porque el marco remoto es demasiado antiguo (vea PlayerContext::BlitRemoteFrameTimeout propiedad).
Importante
A partir de la versión 2.1.0 , es posible con un reproductor personalizado usar la reproyecto de profundidad a través de la comunicación remota holográfica.
BlitResult
también puede devolver BlitResult::Success_Color_Depth
en las condiciones siguientes:
- La aplicación remota ha confirmado un búfer de profundidad a través de HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer.
- La aplicación de reproductor personalizada ha enlazado un búfer de profundidad válido antes de llamar a
BlitRemoteFrame
.
Si se cumplen estas condiciones, BlitRemoteFrame
cortará la profundidad remota en el búfer de profundidad local actualmente enlazado. A continuación, puede representar contenido local adicional, que tendrá una intersección de profundidad con el contenido representado remoto. Además, puede confirmar el búfer de profundidad local a través de HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer en el reproductor personalizado para tener una reproyecto de profundidad para el contenido representado local y remoto.
Modo de transformación de proyección
Un problema que aparece cuando se usa la reproyecto de profundidad a través de la comunicación remota holográfica es que el contenido remoto se puede representar con una transformación de proyección diferente a la del contenido local representado directamente por la aplicación de reproductor personalizada. Un caso de uso común es especificar valores diferentes para plano cercano y lejano (a través de HolographicCamera::SetNearPlaneDistance y HolographicCamera::SetFarPlaneDistance) en el lado del jugador y en el lado remoto. En este caso, no está claro si la transformación de proyección en el lado del jugador debe reflejar las distancias remotas del plano cercano o lejano o las locales.
A partir de la versión 2.1.0 , puede controlar el modo de transformación de proyección a través de PlayerContext::ProjectionTransformConfig
. Los valores admitidos son los siguientes:
-
Local
- HolographicCameraPose::P rojectionTransform devuelve una transformación de proyección, que refleja las distancias de plano cercanas o lejanas establecidas por la aplicación de reproductor personalizada en HolographicCamera. -
Remote
- La transformación de proyección refleja las distancias de plano cercanas o lejanas especificadas por la aplicación remota. -
Merged
- Se combinan distancias de plano cercanas o lejanas desde la aplicación remota y la aplicación de reproductor personalizada. De forma predeterminada, esto se hace tomando el mínimo de las distancias de plano cercano y el máximo de las distancias de plano lejano. En caso de que el lado remoto o local se invierta, digamos muy < cerca, las distancias remotas del plano cercano o lejano se voltea.
Opcional: Establecer BlitRemoteFrameTimeout
Importante
PlayerContext::BlitRemoteFrameTimeout
se admite a partir de la versión 2.0.9.
La PlayerContext::BlitRemoteFrameTimeout
propiedad especifica la cantidad de tiempo que se reutiliza un marco remoto si no se recibe ningún nuevo marco remoto.
Un caso de uso común es habilitar el tiempo de espera de BlitRemoteFrame para mostrar una pantalla en blanco si no se reciben fotogramas nuevos durante un período de tiempo determinado. Cuando está habilitado, el tipo de valor devuelto del BlitRemoteFrame
método también se puede usar para cambiar a un contenido de reserva representado localmente.
Para habilitar el tiempo de espera, establezca el valor de propiedad en una duración igual o mayor que 100 ms. Para deshabilitar el tiempo de espera, establezca la propiedad en duración cero. Si el tiempo de espera está habilitado y no se recibe ninguna trama remota durante la duración establecida, BlitRemoteFrame producirá un error y devolverá Failed_RemoteFrameTooOld
hasta que se reciba un nuevo fotograma remoto.
using namespace std::chrono_literals;
// Set the BlitRemoteFrame timeout to 0.5s
m_playerContext.BlitRemoteFrameTimeout(500ms);
Opcional: obtener estadísticas sobre el último fotograma remoto
Para diagnosticar problemas de rendimiento o de red, las estadísticas sobre la última trama remota se pueden recuperar a través de la PlayerContext::LastFrameStatistics
propiedad . Las estadísticas se actualizan durante la llamada a HolographicFrame::P resentUsingCurrentPrediction.
// Get statistics for the last presented frame.
winrt::Microsoft::Holographic::AppRemoting::PlayerFrameStatistics statistics = m_playerContext.LastFrameStatistics();
Para obtener más información, consulte la PlayerFrameStatistics
documentación del Microsoft.Holographic.AppRemoting.idl
archivo.
Opcional: Canales de datos personalizados
Los canales de datos personalizados se pueden usar para enviar datos de usuario a través de la conexión remota ya establecida. Para obtener más información, consulte canales de datos personalizados.
Opcional: Over-Rendering
La comunicación remota holográfica predice dónde estará la cabeza del usuario en el momento en que aparezcan las imágenes representadas en las pantallas. Sin embargo, esta predicción es una aproximación. Por lo tanto, la ventanilla prevista en la aplicación remota y la ventanilla real posterior de la aplicación del reproductor pueden diferir. Las desviaciones más fuertes (por ejemplo, debido al movimiento imprevisible) podrían provocar regiones negras en los bordes del frustum de visualización. A partir de la versión 2.6.0 , puede usar Over-Rendering para reducir las regiones negras y mejorar la calidad visual aumentando artificialmente la ventanilla más allá del frustum de visualización.
Over-Rendering se puede habilitar a través de PlayerContext::ConfigureOverRendering
.
OverRenderingConfig
especifica un aumento de tamaño fraccionario en la ventanilla real, de modo que la ventanilla prevista sea más grande y se produzca menos corte.
Con un mayor tamaño de ventanilla, la densidad de píxeles disminuye, por lo que OverRenderingConfig también permite aumentar la resolución.
Si el aumento de la ventanilla es igual al aumento de resolución, la densidad de píxeles sigue siendo la misma.
OverRenderingConfig
se define 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: Sincronización del sistema de coordenadas
A partir de la versión 2.7.0 , se puede usar la sincronización del sistema de coordenadas para alinear los datos espaciales entre el reproductor y la aplicación remota. Para obtener más información, vea Información general sobre la sincronización del sistema de coordenadas con comunicación remota holográfica.
Consulta también
- Introducción a la comunicación remota holográfica
- Escritura de una aplicación remota de comunicación remota holográfica mediante Windows Mixed Reality API
- Escritura de una aplicación remota de comunicación remota holográfica mediante las API de OpenXR
- Canales de datos de comunicación remota holográfica personalizada
- Establecer una conexión segura con la comunicación remota holográfica
- Solución de problemas y limitaciones de la comunicación remota holográfica
- Términos de licencia de software de comunicación remota holográfica
- Declaración de privacidad de Microsoft