Rendering in DirectXRendering in DirectX

Nota

Questo articolo si riferisce alle API native di WinRT legacy.This article relates to the legacy WinRT native APIs. Per i nuovi progetti di app native, è consigliabile usare l' API OpenXR.For new native app projects, we recommend using the OpenXR API.

La realtà mista di Windows si basa su DirectX per produrre un'esperienza grafica 3D avanzata per gli utenti.Windows Mixed Reality is built on DirectX to produce rich, 3D graphical experiences for users. L'astrazione del rendering si trova appena sopra DirectX, che consente alle app di ragionare sulla posizione e sull'orientamento degli osservatori di scena olografici previsti dal sistema.The rendering abstraction sits just above DirectX, which lets apps reason about the position and orientation of holographic scene observers predicted by the system. Lo sviluppatore può quindi trovare i propri ologrammi in base a ogni fotocamera, consentendo all'app di eseguire il rendering di questi ologrammi in vari sistemi di coordinate spaziali quando l'utente si sposta.The developer can then locate their holograms based on each camera, letting the app render these holograms in various spatial coordinate systems as the user moves around.

Nota: in questa procedura dettagliata viene descritto il rendering olografico in Direct3D 11.Note: This walkthrough describes holographic rendering in Direct3D 11. Un modello di app per la realtà mista Direct3D 12 Windows viene fornito anche con l'estensione dei modelli di app per realtà mista.A Direct3D 12 Windows Mixed Reality app template is also supplied with the Mixed Reality app templates extension.

Aggiornamento per il frame correnteUpdate for the current frame

Per aggiornare lo stato dell'applicazione per gli ologrammi, una volta per ogni fotogramma l'app:To update the application state for holograms, once per frame the app will:

  • Ottenere un HolographicFrame dal sistema di gestione dello schermo.Get a HolographicFrame from the display management system.
  • Aggiornare la scena con la stima corrente del punto in cui la visualizzazione della fotocamera sarà quando il rendering viene completato.Update the scene with the current prediction of where the camera view will be when render is completed. Si noti che la scena olografica può contenere più di una fotocamera.Note, there can be more than one camera for the holographic scene.

Per eseguire il rendering delle visualizzazioni della fotocamera olografica, una volta per ogni fotogramma l'app:To render to holographic camera views, once per frame the app will:

  • Per ogni fotocamera, eseguire il rendering della scena per il frame corrente, usando la visualizzazione della fotocamera e le matrici di proiezione dal sistema.For each camera, render the scene for the current frame, using the camera view and projection matrices from the system.

Creare un nuovo frame olografico e ottenere la relativa stimaCreate a new holographic frame and get its prediction

Il HolographicFrame contiene informazioni necessarie all'app per aggiornare ed eseguire il rendering del frame corrente.The HolographicFrame has information that the app needs to update and render the current frame. L'app avvia ogni nuovo frame chiamando il metodo CreateNextFrame .The app begins each new frame by calling the CreateNextFrame method. Quando viene chiamato questo metodo, le stime vengono effettuate usando i dati dei sensori più recenti disponibili e incapsulati nell'oggetto CurrentPrediction .When this method is called, predictions are made using the latest sensor data available, and encapsulated in CurrentPrediction object.

Per ogni frame sottoposto a rendering è necessario usare un nuovo oggetto frame perché è valido solo per un istante di tempo.A new frame object must be used for each rendered frame as it is only valid for an instant in time. La proprietà CurrentPrediction contiene informazioni come la posizione della fotocamera.The CurrentPrediction property contains information such as the camera position. Le informazioni vengono estrapolate nel momento esatto in cui il frame dovrebbe essere visibile all'utente.The information is extrapolated to the exact moment in time when the frame is expected to be visible to the user.

Il codice seguente è tratto da AppMain:: Update:The following code is excerpted from AppMain::Update:

// The HolographicFrame has information that the app needs in order
// to update and render the current frame. The app begins each new
// frame by calling CreateNextFrame.
HolographicFrame holographicFrame = m_holographicSpace.CreateNextFrame();

// Get a prediction of where holographic cameras will be when this frame
// is presented.
HolographicFramePrediction prediction = holographicFrame.CurrentPrediction();

Elaborare gli aggiornamenti della fotocameraProcess camera updates

I buffer indietro possono variare da frame a frame.Back buffers can change from frame to frame. L'app deve convalidare il buffer nascosto per ogni fotocamera e rilasciare e ricreare le visualizzazioni delle risorse e i buffer di profondità in base alle esigenze.Your app needs to validate the back buffer for each camera, and release and recreate resource views and depth buffers as needed. Si noti che il set di pose nella stima è l'elenco autorevole di fotocamere utilizzate nel frame corrente.Notice that the set of poses in the prediction is the authoritative list of cameras being used in the current frame. In genere, questo elenco viene usato per eseguire l'iterazione sul set di fotocamere.Usually, you use this list to iterate on the set of cameras.

Da AppMain:: Update:From AppMain::Update:

m_deviceResources->EnsureCameraResources(holographicFrame, prediction);

Da DeviceResources:: EnsureCameraResources:From DeviceResources::EnsureCameraResources:

for (HolographicCameraPose const& cameraPose : prediction.CameraPoses())
{
    HolographicCameraRenderingParameters renderingParameters = frame.GetRenderingParameters(cameraPose);
    CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
    pCameraResources->CreateResourcesForBackBuffer(this, renderingParameters);
}

Ottenere il sistema di coordinate da utilizzare come base per il renderingGet the coordinate system to use as a basis for rendering

La realtà mista di Windows consente all'app di creare vari sistemi di coordinate, ad esempio frame di riferimento allegati e stazionari per i percorsi di rilevamento nel mondo fisico.Windows Mixed Reality lets your app create various coordinate systems, like attached and stationary reference frames for tracking locations in the physical world. L'app può quindi usare questi sistemi di coordinate per motivare la posizione in cui eseguire il rendering degli ologrammi per ogni fotogramma.Your app can then use these coordinate systems to reason about where to render holograms each frame. Quando si richiedono le coordinate da un'API, si passerà sempre il SpatialCoordinateSystem all'interno del quale si desidera esprimere le coordinate.When requesting coordinates from an API, you'll always pass in the SpatialCoordinateSystem within which you want those coordinates to be expressed.

Da AppMain:: Update:From AppMain::Update:

pose = SpatialPointerPose::TryGetAtTimestamp(
    m_stationaryReferenceFrame.CoordinateSystem(), prediction.Timestamp());

Questi sistemi di coordinate possono quindi essere utilizzati per generare matrici di visualizzazione stereo durante il rendering del contenuto nella scena.These coordinate systems can then be used to generate stereo view matrices when rendering the content in your scene.

Da CameraResources:: UpdateViewProjectionBuffer:From CameraResources::UpdateViewProjectionBuffer:

// Get a container object with the view and projection matrices for the given
// pose in the given coordinate system.
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);

Input di sguardi e movimenti del processoProcess gaze and gesture input

Gli input sguardo e mano non sono basati sul tempo e non è necessario aggiornarli nella funzione StepTimer .Gaze and hand input aren't time-based and don't have to update in the StepTimer function. Tuttavia, questo input è un elemento che l'app deve esaminare per ogni fotogramma.However this input is something that the app needs to look at each frame.

Elaborare gli aggiornamenti basati sul tempoProcess time-based updates

Qualsiasi app per il rendering in tempo reale richiede un modo per elaborare gli aggiornamenti basati sul tempo. il modello di app olografico di Windows usa un'implementazione di StepTimer , simile a StepTimer fornito nel modello di app DirectX 11 UWP.Any real-time rendering app will need some way to process time-based updates - the Windows Holographic app template uses a StepTimer implementation, similar to the StepTimer provided in the DirectX 11 UWP app template. Questa classe helper di esempio StepTimer può fornire aggiornamenti fissi in fase di esecuzione, aggiornamenti variabili del tempo e la modalità predefinita prevede intervalli temporali variabili.This StepTimer sample helper class can provide fixed time-step updates, variable time-step updates, and the default mode is variable time steps.

Per il rendering olografico, è stato scelto di non inserire troppo nella funzione timer perché è possibile configurarla in modo che sia un passaggio di tempo fisso.For holographic rendering, we've chosen not to put too much into the timer function because you can configure it to be a fixed time step. Potrebbe essere chiamato più di una volta per frame, o non per alcuni frame, e gli aggiornamenti dei dati olografici dovrebbero essere eseguiti una sola volta per ogni fotogramma.It might get called more than once per frame – or not at all, for some frames – and our holographic data updates should happen once per frame.

Da AppMain:: Update:From AppMain::Update:

m_timer.Tick([this]()
{
    m_spinningCubeRenderer->Update(m_timer);
});

Posizionare e ruotare gli ologrammi nel sistema di coordinatePosition and rotate holograms in your coordinate system

Se si opera in un sistema di coordinate singolo, come nel caso del modello con il SpatialStationaryReferenceFrame, questo processo non è diverso da quello che viene usato altrimenti in grafica 3D.If you're operating in a single coordinate system, as the template does with the SpatialStationaryReferenceFrame, this process isn't different from what you're otherwise used to in 3D graphics. Qui viene ruotato il cubo e la matrice del modello viene impostata in base alla posizione nel sistema di coordinate fisse.Here, we rotate the cube and set the model matrix based on the position in the stationary coordinate system.

Da SpinningCubeRenderer:: Update:From SpinningCubeRenderer::Update:

// Rotate the cube.
// Convert degrees to radians, then convert seconds to rotation angle.
const float    radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
const double   totalRotation = timer.GetTotalSeconds() * radiansPerSecond;
const float    radians = static_cast<float>(fmod(totalRotation, XM_2PI));
const XMMATRIX modelRotation = XMMatrixRotationY(-radians);

// Position the cube.
const XMMATRIX modelTranslation = XMMatrixTranslationFromVector(XMLoadFloat3(&m_position));

// Multiply to get the transform matrix.
// Note that this transform does not enforce a particular coordinate system. The calling
// class is responsible for rendering this content in a consistent manner.
const XMMATRIX modelTransform = XMMatrixMultiply(modelRotation, modelTranslation);

// The view and projection matrices are provided by the system; they are associated
// with holographic cameras, and updated on a per-camera basis.
// Here, we provide the model transform for the sample hologram. The model transform
// matrix is transposed to prepare it for the shader.
XMStoreFloat4x4(&m_modelConstantBufferData.model, XMMatrixTranspose(modelTransform));

Nota sugli scenari avanzati: Il cubo rotante è un semplice esempio di come posizionare un ologramma all'interno di un singolo frame di riferimento.Note about advanced scenarios: The spinning cube is a simple example of how to position a hologram within a single reference frame. È anche possibile usare più SpatialCoordinateSystems nello stesso frame sottoposto a rendering, allo stesso tempo.It's also possible to use multiple SpatialCoordinateSystems in the same rendered frame, at the same time.

Aggiornare i dati del buffer costanteUpdate constant buffer data

Le trasformazioni del modello per il contenuto vengono aggiornate come di consueto.Model transforms for content are updated as usual. A questo punto sono state calcolate le trasformazioni valide per il sistema di coordinate in cui verrà eseguito il rendering.By now, you'll have computed valid transforms for the coordinate system you'll be rendering in.

Da SpinningCubeRenderer:: Update:From SpinningCubeRenderer::Update:

// Update the model transform buffer for the hologram.
context->UpdateSubresource(
    m_modelConstantBuffer.Get(),
    0,
    nullptr,
    &m_modelConstantBufferData,
    0,
    0
);

Informazioni sulle trasformazioni di visualizzazione e proiezioneWhat about view and projection transforms? Per ottenere risultati ottimali, è necessario attendere fino a quando non si è pronti per le chiamate di estrazione.For best results, we want to wait until we're almost ready for our draw calls before we get these.

Esegue il rendering del frame correnteRender the current frame

Il rendering in realtà mista di Windows non è molto diverso dal rendering in una visualizzazione mono 2D, ma vi sono alcune differenze:Rendering on Windows Mixed Reality isn't much different from rendering on a 2D mono display, but there are a few differences:

  • Le stime del frame olografico sono importanti.Holographic frame predictions are important. Più si avvicina la stima a quando viene presentato il frame, migliore sarà l'aspetto degli ologrammi.The closer the prediction is to when your frame is presented, the better your holograms will look.
  • La realtà mista di Windows controlla le visualizzazioni della fotocamera.Windows Mixed Reality controls the camera views. Eseguirne il rendering in ognuno di essi poiché il frame olografico li mostrerà in un secondo momento.Render to each one because the holographic frame will be presenting them for you later.
  • Si consiglia di eseguire il rendering stereo utilizzando il disegno istanza in una matrice di destinazione di rendering.We recommend doing stereo rendering using instanced drawing to a render target array. Il modello di app olografico usa l'approccio consigliato del disegno di istanza in una matrice di destinazione di rendering, che usa una visualizzazione della destinazione di rendering in un Texture2DArray.The holographic app template uses the recommended approach of instanced drawing to a render target array, which uses a render target view onto a Texture2DArray.
  • Se si vuole eseguire il rendering senza usare le istanze stereo, è necessario creare due RenderTargetViews non di matrice, uno per ogni occhio.If you want to render without using stereo instancing, you'll need to create two non-array RenderTargetViews, one for each eye. Ogni RenderTargetViews fa riferimento a una delle due sezioni in Texture2DArray fornite all'app dal sistema.Each RenderTargetViews references one of the two slices in the Texture2DArray provided to the app from the system. Questa operazione non è consigliata, in quanto è in genere più lenta rispetto all'uso della creazione di istanze.This isn't recommended, as it's typically slower than using instancing.

Ottenere una stima HolographicFrame aggiornataGet an updated HolographicFrame prediction

L'aggiornamento della stima del frame migliora l'efficacia della stabilizzazione dell'immagine.Updating the frame prediction enhances the effectiveness of image stabilization. Si ottiene un posizionamento più accurato degli ologrammi a causa del tempo più breve tra la stima e quando il frame è visibile all'utente.You get more accurate positioning of holograms because of the shorter time between the prediction and when the frame is visible to the user. Aggiornare idealmente la stima dei frame immediatamente prima del rendering.Ideally update your frame prediction just before rendering.

holographicFrame.UpdateCurrentPrediction();
HolographicFramePrediction prediction = holographicFrame.CurrentPrediction();

Rendering in ogni fotocameraRender to each camera

Il ciclo del set di fotocamere si pone nella stima e viene eseguito il rendering in ogni fotocamera in questo set.Loop on the set of camera poses in the prediction, and render to each camera in this set.

Configurare la sessione di renderingSet up your rendering pass

La realtà mista di Windows usa il rendering stereoscopico per migliorare l'illusione della profondità e per eseguire il rendering in modo stereoscopico, in modo che sia la visualizzazione a sinistra che quella destra siano attiveWindows Mixed Reality uses stereoscopic rendering to enhance the illusion of depth and to render stereoscopically, so both the left and the right display are active. Con il rendering stereoscopico, esiste un offset tra le due visualizzazioni, che il cervello può riconciliare come profondità effettiva.With stereoscopic rendering, there's an offset between the two displays, which the brain can reconcile as actual depth. Questa sezione illustra il rendering stereoscopico usando le istanze, usando il codice del modello di app olografico di Windows.This section covers stereoscopic rendering using instancing, using code from the Windows Holographic app template.

Ogni fotocamera ha una propria destinazione di rendering (buffer nascosto) e matrici di visualizzazione e proiezione nello spazio olografico.Each camera has its own render target (back buffer), and view and projection matrices, into the holographic space. L'app dovrà creare altre risorse basate su fotocamera, ad esempio il buffer di profondità, per ogni singola fotocamera.Your app will need to create any other camera-based resources - such as the depth buffer - on a per-camera basis. Nel modello di app olografico di Windows, viene fornita una classe helper per raggruppare queste risorse in DX:: CameraResources.In the Windows Holographic app template, we provide a helper class to bundle these resources together in DX::CameraResources. Per iniziare, configurare le visualizzazioni della destinazione di rendering:Start by setting up the render target views:

Da AppMain:: Render:From AppMain::Render:

// This represents the device-based resources for a HolographicCamera.
DX::CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();

// Get the device context.
const auto context = m_deviceResources->GetD3DDeviceContext();
const auto depthStencilView = pCameraResources->GetDepthStencilView();

// Set render targets to the current holographic camera.
ID3D11RenderTargetView *const targets[1] =
    { pCameraResources->GetBackBufferRenderTargetView() };
context->OMSetRenderTargets(1, targets, depthStencilView);

// Clear the back buffer and depth stencil view.
if (m_canGetHolographicDisplayForCamera &&
    cameraPose.HolographicCamera().Display().IsOpaque())
{
    context->ClearRenderTargetView(targets[0], DirectX::Colors::CornflowerBlue);
}
else
{
    context->ClearRenderTargetView(targets[0], DirectX::Colors::Transparent);
}
context->ClearDepthStencilView(
    depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

Utilizzare la stima per ottenere le matrici di visualizzazione e proiezione per la fotocameraUse the prediction to get the view and projection matrices for the camera

Le matrici di visualizzazione e proiezione per ogni fotocamera olografica cambieranno con ogni frame.The view and projection matrices for each holographic camera will change with every frame. Aggiornare i dati nel buffer costante per ogni fotocamera olografica.Refresh the data in the constant buffer for each holographic camera. Eseguire questa operazione dopo aver aggiornato la stima e prima di effettuare qualsiasi chiamata di richiamo per la fotocamera.Do this after you updated the prediction, and before you make any draw calls for that camera.

Da AppMain:: Render:From AppMain::Render:

// The view and projection matrices for each holographic camera will change
// every frame. This function refreshes the data in the constant buffer for
// the holographic camera indicated by cameraPose.
if (m_stationaryReferenceFrame)
{
    pCameraResources->UpdateViewProjectionBuffer(
        m_deviceResources, cameraPose, m_stationaryReferenceFrame.CoordinateSystem());
}

// Attach the view/projection constant buffer for this camera to the graphics pipeline.
bool cameraActive = pCameraResources->AttachViewProjectionBuffer(m_deviceResources);

Qui viene illustrato come vengono acquisite le matrici dalla fotocamera.Here, we show how the matrices are acquired from the camera pose. Durante questo processo, viene anche ottenuto il viewport corrente per la fotocamera.During this process, we also obtain the current viewport for the camera. Si noti il modo in cui viene fornito un sistema di Coordinate: si tratta dello stesso sistema di coordinate usato per comprendere lo sguardo ed è uguale a quello usato per posizionare il cubo rotante.Note how we provide a coordinate system: this is the same coordinate system we used to understand gaze, and it's the same one we used to position the spinning cube.

Da CameraResources:: UpdateViewProjectionBuffer:From CameraResources::UpdateViewProjectionBuffer:

// The system changes the viewport on a per-frame basis for system optimizations.
auto viewport = cameraPose.Viewport();
m_d3dViewport = CD3D11_VIEWPORT(
    viewport.X,
    viewport.Y,
    viewport.Width,
    viewport.Height
);

// The projection transform for each frame is provided by the HolographicCameraPose.
HolographicStereoTransform cameraProjectionTransform = cameraPose.ProjectionTransform();

// Get a container object with the view and projection matrices for the given
// pose in the given coordinate system.
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);

// If TryGetViewTransform returns a null pointer, that means the pose and coordinate
// system cannot be understood relative to one another; content cannot be rendered
// in this coordinate system for the duration of the current frame.
// This usually means that positional tracking is not active for the current frame, in
// which case it is possible to use a SpatialLocatorAttachedFrameOfReference to render
// content that is not world-locked instead.
DX::ViewProjectionConstantBuffer viewProjectionConstantBufferData;
bool viewTransformAcquired = viewTransformContainer != nullptr;
if (viewTransformAcquired)
{
    // Otherwise, the set of view transforms can be retrieved.
    HolographicStereoTransform viewCoordinateSystemTransform = viewTransformContainer.Value();

    // Update the view matrices. Holographic cameras (such as Microsoft HoloLens) are
    // constantly moving relative to the world. The view matrices need to be updated
    // every frame.
    XMStoreFloat4x4(
        &viewProjectionConstantBufferData.viewProjection[0],
        XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) *
            XMLoadFloat4x4(&cameraProjectionTransform.Left))
    );
    XMStoreFloat4x4(
        &viewProjectionConstantBufferData.viewProjection[1],
        XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) *
            XMLoadFloat4x4(&cameraProjectionTransform.Right))
    );
}

Il viewport deve essere impostato su ogni frame.The viewport should be set each frame. Il vertex shader (almeno) deve in genere accedere ai dati di visualizzazione/proiezione.Your vertex shader (at least) will generally need access to the view/projection data.

Da CameraResources:: AttachViewProjectionBuffer:From CameraResources::AttachViewProjectionBuffer:

// Set the viewport for this camera.
context->RSSetViewports(1, &m_d3dViewport);

// Send the constant buffer to the vertex shader.
context->VSSetConstantBuffers(
    1,
    1,
    m_viewProjectionConstantBuffer.GetAddressOf()
);

Eseguire il rendering sul buffer nascosto della fotocamera ed eseguire il commit del buffer di profondità:Render to the camera back buffer and commit the depth buffer:

È consigliabile verificare che TryGetViewTransform abbia avuto esito positivo prima di provare a usare i dati di visualizzazione/proiezione, perché se il sistema di coordinate non è locatable (ad esempio, il rilevamento è stato interrotto) non è possibile eseguire il rendering dell'app per quel frame.It's a good idea to check that TryGetViewTransform succeeded before trying to use the view/projection data, because if the coordinate system isn't locatable (for example, tracking was interrupted) your app can't render with it for that frame. Il modello chiama solo il rendering sul cubo rotante se la classe CameraResources indica un aggiornamento riuscito.The template only calls Render on the spinning cube if the CameraResources class indicates a successful update.

La realtà mista di Windows include funzionalità per la stabilizzazione delle immagini che consentono di posizionare gli ologrammi in cui uno sviluppatore o un utente li inserisce nel mondo.Windows Mixed Reality includes features for image stabilization to keep holograms positioned where a developer or user puts them in the world. La stabilizzazione delle immagini consente di nascondere la latenza intrinseca in una pipeline di rendering per garantire la migliore esperienza olografica per gli utenti.Image stabilization helps hide the latency inherent in a rendering pipeline to ensure the best holographic experiences for users. È possibile specificare un punto di interesse per migliorare ulteriormente la stabilizzazione dell'immagine oppure è possibile fornire un buffer di profondità per calcolare la stabilizzazione delle immagini ottimizzata in tempo reale.A focus point may be specified to enhance image stabilization even further, or a depth buffer may be provided to compute optimized image stabilization in real time.

Per ottenere risultati ottimali, l'app deve fornire un buffer di profondità usando l'API CommitDirect3D11DepthBuffer .For best results, your app should provide a depth buffer using the CommitDirect3D11DepthBuffer API. La realtà mista di Windows può quindi usare le informazioni di geometria dal buffer di profondità per ottimizzare la stabilizzazione delle immagini in tempo reale.Windows Mixed Reality can then use geometry information from the depth buffer to optimize image stabilization in real time. Per impostazione predefinita, il modello di app Windows olografico consente di eseguire il commit del buffer di profondità dell'app per ottimizzare la stabilità degli ologrammi.The Windows Holographic app template commits the app's depth buffer by default, helping optimize hologram stability.

Da AppMain:: Render:From AppMain::Render:

// Only render world-locked content when positional tracking is active.
if (cameraActive)
{
    // Draw the sample hologram.
    m_spinningCubeRenderer->Render();
    if (m_canCommitDirect3D11DepthBuffer)
    {
        // On versions of the platform that support the CommitDirect3D11DepthBuffer API, we can 
        // provide the depth buffer to the system, and it will use depth information to stabilize 
        // the image at a per-pixel level.
        HolographicCameraRenderingParameters renderingParameters =
            holographicFrame.GetRenderingParameters(cameraPose);
        
        IDirect3DSurface interopSurface =
            DX::CreateDepthTextureInteropObject(pCameraResources->GetDepthStencilTexture2D());

        // Calling CommitDirect3D11DepthBuffer causes the system to queue Direct3D commands to 
        // read the depth buffer. It will then use that information to stabilize the image as
        // the HolographicFrame is presented.
        renderingParameters.CommitDirect3D11DepthBuffer(interopSurface);
    }
}

Nota

Windows elaborerà la trama di profondità sulla GPU, quindi è necessario usare il buffer di profondità come risorsa dello shader.Windows will process your depth texture on the GPU, so it must be possible to use your depth buffer as a shader resource. Il ID3D11Texture2D creato deve avere un formato senza tipo e deve essere associato come visualizzazione delle risorse dello shader.The ID3D11Texture2D that you create should be in a typeless format and it should be bound as a shader resource view. Di seguito è riportato un esempio di come creare una trama di profondità di cui è possibile eseguire il commit per la stabilizzazione delle immagini.Here is an example of how to create a depth texture that can be committed for image stabilization.

Codice per la creazione di risorse del buffer di profondità per CommitDirect3D11DepthBuffer:Code for Depth buffer resource creation for CommitDirect3D11DepthBuffer:

// Create a depth stencil view for use with 3D rendering if needed.
CD3D11_TEXTURE2D_DESC depthStencilDesc(
    DXGI_FORMAT_R16_TYPELESS,
    static_cast<UINT>(m_d3dRenderTargetSize.Width),
    static_cast<UINT>(m_d3dRenderTargetSize.Height),
    m_isStereo ? 2 : 1, // Create two textures when rendering in stereo.
    1, // Use a single mipmap level.
    D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE
);

winrt::check_hresult(
    device->CreateTexture2D(
        &depthStencilDesc,
        nullptr,
        &m_d3dDepthStencil
    ));

CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(
    m_isStereo ? D3D11_DSV_DIMENSION_TEXTURE2DARRAY : D3D11_DSV_DIMENSION_TEXTURE2D,
    DXGI_FORMAT_D16_UNORM
);
winrt::check_hresult(
    device->CreateDepthStencilView(
        m_d3dDepthStencil.Get(),
        &depthStencilViewDesc,
        &m_d3dDepthStencilView
    ));

Creare contenuto olograficoDraw holographic content

Il modello di app olografico di Windows esegue il rendering del contenuto in stereo usando la tecnica consigliata per il disegno di una geometria di istanza in un Texture2DArray di dimensioni 2.The Windows Holographic app template renders content in stereo by using the recommended technique of drawing instanced geometry to a Texture2DArray of size 2. Esaminiamo la parte relativa alle istanze e il funzionamento della realtà mista di Windows.Let's look at the instancing part of this, and how it works on Windows Mixed Reality.

Da SpinningCubeRenderer:: Render:From SpinningCubeRenderer::Render:

// Draw the objects.
context->DrawIndexedInstanced(
    m_indexCount,   // Index count per instance.
    2,              // Instance count.
    0,              // Start index location.
    0,              // Base vertex location.
    0               // Start instance location.
);

Ogni istanza accede a una matrice di visualizzazione/proiezione diversa dal buffer costante.Each instance accesses a different view/projection matrix from the constant buffer. Di seguito è illustrata la struttura del buffer costante, che è solo una matrice di due matrici.Here's the constant buffer structure, which is just an array of two matrices.

Da VertexShaderShared. HLSL, incluso in VPRTVertexShader. HLSL:From VertexShaderShared.hlsl, included by VPRTVertexShader.hlsl:

// A constant buffer that stores each set of view and projection matrices in column-major format.
cbuffer ViewProjectionConstantBuffer : register(b1)
{
    float4x4 viewProjection[2];
};

Per ogni pixel è necessario impostare l'indice della matrice di destinazione di rendering.The render target array index must be set for each pixel. Nel frammento di codice seguente viene eseguito il mapping di output. viewId alla semantica SV_RenderTargetArrayIndex .In the following snippet, output.viewId is mapped to the SV_RenderTargetArrayIndex semantic. È necessario il supporto per una funzionalità facoltativa Direct3D 11,3, che consente di impostare la semantica dell'indice della matrice di destinazione di rendering da qualsiasi fase dello shader.This requires support for an optional Direct3D 11.3 feature, which allows the render target array index semantic to be set from any shader stage.

Da VPRTVertexShader. HLSL:From VPRTVertexShader.hlsl:

// Per-vertex data passed to the geometry shader.
struct VertexShaderOutput
{
    min16float4 pos     : SV_POSITION;
    min16float3 color   : COLOR0;

    // The render target array index is set here in the vertex shader.
    uint        viewId  : SV_RenderTargetArrayIndex;
};

Da VertexShaderShared. HLSL, incluso in VPRTVertexShader. HLSL:From VertexShaderShared.hlsl, included by VPRTVertexShader.hlsl:

// Per-vertex data used as input to the vertex shader.
struct VertexShaderInput
{
    min16float3 pos     : POSITION;
    min16float3 color   : COLOR0;
    uint        instId  : SV_InstanceID;
};

// Simple shader to do vertex processing on the GPU.
VertexShaderOutput main(VertexShaderInput input)
{
    VertexShaderOutput output;
    float4 pos = float4(input.pos, 1.0f);

    // Note which view this vertex has been sent to. Used for matrix lookup.
    // Taking the modulo of the instance ID allows geometry instancing to be used
    // along with stereo instanced drawing; in that case, two copies of each 
    // instance would be drawn, one for left and one for right.
    int idx = input.instId % 2;

    // Transform the vertex position into world space.
    pos = mul(pos, model);

    // Correct for perspective and project the vertex position onto the screen.
    pos = mul(pos, viewProjection[idx]);
    output.pos = (min16float4)pos;

    // Pass the color through without modification.
    output.color = input.color;

    // Set the render target array index.
    output.viewId = idx;

    return output;
}

Se si desidera utilizzare le tecniche di disegno con istanze esistenti con questo metodo di disegno in una matrice di destinazione di rendering stereo, disegnare due volte il numero di istanze di cui si dispone normalmente.If you want to use your existing instanced drawing techniques with this method of drawing to a stereo render target array, draw twice the number of instances you normally have. Nello shader dividere input. IDIstanza per 2 per ottenere l'ID istanza originale, che può essere indicizzato in (ad esempio) un buffer di dati per oggetto: int actualIdx = input.instId / 2;In the shader, divide input.instId by 2 to get the original instance ID, which can be indexed into (for example) a buffer of per-object data: int actualIdx = input.instId / 2;

Nota importante sul rendering del contenuto stereo in HoloLensImportant note about rendering stereo content on HoloLens

La realtà mista di Windows supporta la possibilità di impostare l'indice della matrice di destinazione di rendering da qualsiasi fase dello shader.Windows Mixed Reality supports the ability to set the render target array index from any shader stage. In genere, si tratta di un'attività che può essere eseguita solo nella fase geometry shader a causa del modo in cui la semantica è definita per Direct3D 11.Normally, this is a task that could only be done in the geometry shader stage because of the way the semantic is defined for Direct3D 11. Qui viene illustrato un esempio completo di come configurare una pipeline di rendering solo con le fasi Vertex e pixel shader impostate.Here, we show a complete example of how to set up a rendering pipeline with just the vertex and pixel shader stages set. Il codice dello shader è come descritto in precedenza.The shader code is as described above.

Da SpinningCubeRenderer:: Render:From SpinningCubeRenderer::Render:

const auto context = m_deviceResources->GetD3DDeviceContext();

// Each vertex is one instance of the VertexPositionColor struct.
const UINT stride = sizeof(VertexPositionColor);
const UINT offset = 0;
context->IASetVertexBuffers(
    0,
    1,
    m_vertexBuffer.GetAddressOf(),
    &stride,
    &offset
);
context->IASetIndexBuffer(
    m_indexBuffer.Get(),
    DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
    0
);
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
context->IASetInputLayout(m_inputLayout.Get());

// Attach the vertex shader.
context->VSSetShader(
    m_vertexShader.Get(),
    nullptr,
    0
);
// Apply the model constant buffer to the vertex shader.
context->VSSetConstantBuffers(
    0,
    1,
    m_modelConstantBuffer.GetAddressOf()
);

// Attach the pixel shader.
context->PSSetShader(
    m_pixelShader.Get(),
    nullptr,
    0
);

// Draw the objects.
context->DrawIndexedInstanced(
    m_indexCount,   // Index count per instance.
    2,              // Instance count.
    0,              // Start index location.
    0,              // Base vertex location.
    0               // Start instance location.
);

Nota importante sul rendering nei dispositivi non HoloLensImportant note about rendering on non-HoloLens devices

Per impostare l'indice della matrice di destinazione di rendering nel vertex shader, è necessario che il driver di grafica supporti una funzionalità facoltativa Direct3D 11,3, supportata da HoloLens.Setting the render target array index in the vertex shader requires that the graphics driver supports an optional Direct3D 11.3 feature, which HoloLens does support. L'app può implementare in modo sicuro solo questa tecnica per il rendering e tutti i requisiti verranno soddisfatti per l'esecuzione in Microsoft HoloLens.Your app may can safely implement just that technique for rendering, and all requirements will be met for running on the Microsoft HoloLens.

È possibile che si voglia usare anche l'emulatore di HoloLens, che può essere uno strumento di sviluppo potente per l'app olografica e per supportare i dispositivi con auricolari a realtà mista di Windows, collegati a PC Windows 10.It may be the case that you want to use the HoloLens emulator as well, which can be a powerful development tool for your holographic app - and support Windows Mixed Reality immersive headset devices that are attached to Windows 10 PCs. Il supporto per il percorso di rendering non HoloLens, per tutte le realtà miste di Windows, è anche incorporato nel modello di app olografico di Windows.Support for the non-HoloLens rendering path - for all of Windows Mixed Reality - is also built into the Windows Holographic app template. Nel codice del modello è presente codice per abilitare l'esecuzione dell'app olografica sulla GPU nel PC di sviluppo.In the template code, you'll find code to enable your holographic app to run on the GPU in your development PC. Ecco il modo in cui la classe DeviceResources verifica la presenza di questo supporto della funzionalità facoltativa.Here's how the DeviceResources class checks for this optional feature support.

Da DeviceResources:: CreateDeviceResources:From DeviceResources::CreateDeviceResources:

// Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options, sizeof(options));
if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
{
    m_supportsVprt = true;
}

Per supportare il rendering senza questa funzionalità facoltativa, l'app deve usare un geometry shader per impostare l'indice della matrice di destinazione di rendering.To support rendering without this optional feature, your app must use a geometry shader to set the render target array index. Questo frammento di codice verrà aggiunto dopo VSSetConstantBuffers e prima di PSSetShader nell'esempio di codice illustrato nella sezione precedente, in cui viene illustrato come eseguire il rendering dello stereo su HoloLens.This snippet would be added after VSSetConstantBuffers, and before PSSetShader in the code example shown in the previous section that explains how to render stereo on HoloLens.

Da SpinningCubeRenderer:: Render:From SpinningCubeRenderer::Render:

if (!m_usingVprtShaders)
{
    // On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
    // VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
    // a pass-through geometry shader is used to set the render target 
    // array index.
    context->GSSetShader(
        m_geometryShader.Get(),
        nullptr,
        0
    );
}

HLSL nota: in questo caso, è necessario caricare anche un vertex shader leggermente modificato che passa l'indice della matrice di destinazione di rendering a geometry shader usando una semantica shader sempre consentita, ad esempio TEXCOORD0.HLSL NOTE: In this case, you must also load a slightly modified vertex shader that passes the render target array index to the geometry shader using an always-allowed shader semantic, such as TEXCOORD0. Il geometry shader non deve eseguire alcuna operazione; il modello geometry shader passa attraverso tutti i dati, fatta eccezione per l'indice della matrice di destinazione di rendering, che viene usato per impostare la semantica del SV_RenderTargetArrayIndex.The geometry shader doesn't have to do any work; the template geometry shader passes through all data, with the exception of the render target array index, which is used to set the SV_RenderTargetArrayIndex semantic.

Codice modello app per GeometryShader. HLSL:App template code for GeometryShader.hlsl:

// Per-vertex data from the vertex shader.
struct GeometryShaderInput
{
    min16float4 pos     : SV_POSITION;
    min16float3 color   : COLOR0;
    uint instId         : TEXCOORD0;
};

// Per-vertex data passed to the rasterizer.
struct GeometryShaderOutput
{
    min16float4 pos     : SV_POSITION;
    min16float3 color   : COLOR0;
    uint rtvId          : SV_RenderTargetArrayIndex;
};

// This geometry shader is a pass-through that leaves the geometry unmodified 
// and sets the render target array index.
[maxvertexcount(3)]
void main(triangle GeometryShaderInput input[3], inout TriangleStream<GeometryShaderOutput> outStream)
{
    GeometryShaderOutput output;
    [unroll(3)]
    for (int i = 0; i < 3; ++i)
    {
        output.pos   = input[i].pos;
        output.color = input[i].color;
        output.rtvId = input[i].instId;
        outStream.Append(output);
    }
}

PresentePresent

Abilitare il frame olografico per presentare la catena di scambioEnable the holographic frame to present the swap chain

Con la realtà mista di Windows, il sistema controlla la catena di scambio.With Windows Mixed Reality, the system controls the swap chain. Il sistema gestisce quindi la presentazione dei frame a ogni fotocamera olografica per garantire un'esperienza utente di alta qualità.The system then manages presenting frames to each holographic camera to ensure a high-quality user experience. Fornisce anche un viewport per aggiornare ogni frame, per ogni fotocamera, per ottimizzare gli aspetti del sistema, ad esempio la stabilizzazione dell'immagine o l'acquisizione di realtà mista.It also provides a viewport update each frame, for each camera, to optimize aspects of the system such as image stabilization or Mixed Reality Capture. Quindi, un'app olografica che usa DirectX non chiama presente in una catena di scambio dxgi.So, a holographic app using DirectX doesn't call Present on a DXGI swap chain. Al contrario, si usa la classe HolographicFrame per presentare tutti i le catene per un frame al termine del disegno.Instead, you use the HolographicFrame class to present all swapchains for a frame once you're done drawing it.

Da DeviceResources::P inviato nuovamente:From DeviceResources::Present:

HolographicFramePresentResult presentResult = frame.PresentUsingCurrentPrediction();

Per impostazione predefinita, questa API attende il completamento del frame prima della restituzione.By default, this API waits for the frame to finish before it returns. Le app olografiche devono attendere il completamento del frame precedente prima di iniziare a lavorare su un nuovo frame, perché questo riduce la latenza e consente di ottenere risultati migliori dalle stime dei frame olografici.Holographic apps should wait for the previous frame to finish before starting work on a new frame, because this reduces latency and allows for better results from holographic frame predictions. Questa regola non è rigida e se sono presenti frame che impostano più di un aggiornamento dello schermo per il rendering, è possibile disabilitare questa attesa passando il parametro HolographicFramePresentWaitBehavior a PresentUsingCurrentPrediction.This isn't a hard rule, and if you have frames that take longer than one screen refresh to render you can disable this wait by passing the HolographicFramePresentWaitBehavior parameter to PresentUsingCurrentPrediction. In questo caso, è probabile che si usi un thread di rendering asincrono per mantenere un carico continuo sulla GPU.In this case, you would likely use an asynchronous rendering thread to maintain a continuous load on the GPU. La frequenza di aggiornamento del dispositivo HoloLens è 60 Hz, dove un frame ha una durata di circa 16 ms.The refresh rate of the HoloLens device is 60 hz, where one frame has a duration of approximately 16 ms. I dispositivi per auricolari immersivi possono variare da 60 Hz a 90 Hz; Quando si aggiorna la visualizzazione a 90 Hz, ogni frame avrà una durata pari a circa 11 ms.Immersive headset devices can range from 60 hz to 90 hz; when refreshing the display at 90 hz, each frame will have a duration of approximately 11 ms.

Gestire scenari DeviceLost in collaborazione con HolographicFrameHandle DeviceLost scenarios in cooperation with the HolographicFrame

Le app DirectX 11 in genere vogliono controllare il valore HRESULT restituito dalla funzione presente della catena di scambio DXGI per determinare se si è verificato un errore DeviceLost .DirectX 11 apps would typically want to check the HRESULT returned by the DXGI swap chain's Present function to find out if there was a DeviceLost error. La classe HolographicFrame gestisce questa operazione automaticamente.The HolographicFrame class handles this for you. Esaminare i HolographicFramePresentResult restituiti per verificare se è necessario rilasciare e ricreare il dispositivo Direct3D e le risorse basate su dispositivo.Inspect the returned HolographicFramePresentResult to find out if you need to release and recreate the Direct3D device and device-based resources.

// The PresentUsingCurrentPrediction API will detect when the graphics device
// changes or becomes invalid. When this happens, it is considered a Direct3D
// device lost scenario.
if (presentResult == HolographicFramePresentResult::DeviceRemoved)
{
    // The Direct3D device, context, and resources should be recreated.
    HandleDeviceLost();
}

Se il dispositivo Direct3D è stato perso ed è stato ricreato, è necessario indicare all' HolographicSpace di iniziare a usare il nuovo dispositivo.If the Direct3D device was lost, and you did recreate it, you have to tell the HolographicSpace to start using the new device. La catena di scambio verrà ricreata per questo dispositivo.The swap chain will be recreated for this device.

Da DeviceResources:: InitializeUsingHolographicSpace:From DeviceResources::InitializeUsingHolographicSpace:

m_holographicSpace.SetDirect3D11Device(m_d3dInteropDevice);

Una volta visualizzato il frame, è possibile tornare al ciclo principale del programma e consentirne la continuazione al frame successivo.Once your frame is presented, you can return back to the main program loop and allow it to continue to the next frame.

Computer grafici ibridi e applicazioni di realtà mistaHybrid graphics PCs and mixed reality applications

I PC Windows 10 Creators Update possono essere configurati con GPU sia discrete che integrate.Windows 10 Creators Update PCs may be configured with both discrete and integrated GPUs. Con questi tipi di computer, Windows sceglierà la scheda a cui è connessa l'auricolare.With these types of computers, Windows will choose the adapter the headset is connected to. Le applicazioni devono garantire che il dispositivo DirectX creato usi la stessa scheda.Applications must ensure the DirectX device it creates uses the same adapter.

La maggior parte del codice di esempio Direct3D generale illustra la creazione di un dispositivo DirectX usando la scheda hardware predefinita, che in un sistema ibrido potrebbe non essere uguale a quella usata per l'auricolare.Most general Direct3D sample code demonstrates creating a DirectX device using the default hardware adapter, which on a hybrid system may not be the same as the one used for the headset.

Per risolvere i problemi, usare HolographicAdapterID da HolographicSpace. PrimaryAdapterId () o HolographicDisplay. AdapterId ().To work around any issues, use the HolographicAdapterID from either HolographicSpace.PrimaryAdapterId() or HolographicDisplay.AdapterId(). Questo adapterId può quindi essere usato per selezionare il DXGIAdapter corretto usando IDXGIFactory4. EnumAdapterByLuid.This adapterId can then be used to select the right DXGIAdapter using IDXGIFactory4.EnumAdapterByLuid.

Da DeviceResources:: InitializeUsingHolographicSpace:From DeviceResources::InitializeUsingHolographicSpace:

// The holographic space might need to determine which adapter supports
// holograms, in which case it will specify a non-zero PrimaryAdapterId.
LUID id =
{
    m_holographicSpace.PrimaryAdapterId().LowPart,
    m_holographicSpace.PrimaryAdapterId().HighPart
};

// When a primary adapter ID is given to the app, the app should find
// the corresponding DXGI adapter and use it to create Direct3D devices
// and device contexts. Otherwise, there is no restriction on the DXGI
// adapter the app can use.
if ((id.HighPart != 0) || (id.LowPart != 0))
{
    UINT createFlags = 0;

    // Create the DXGI factory.
    ComPtr<IDXGIFactory1> dxgiFactory;
    winrt::check_hresult(
        CreateDXGIFactory2(
            createFlags,
            IID_PPV_ARGS(&dxgiFactory)
        ));
    ComPtr<IDXGIFactory4> dxgiFactory4;
    winrt::check_hresult(dxgiFactory.As(&dxgiFactory4));

    // Retrieve the adapter specified by the holographic space.
    winrt::check_hresult(
        dxgiFactory4->EnumAdapterByLuid(
            id,
            IID_PPV_ARGS(&m_dxgiAdapter)
        ));
}
else
{
    m_dxgiAdapter.Reset();
}

Codice per l' aggiornamento di DeviceResources:: CreateDeviceResources per l'uso di IDXGIAdapterCode to update DeviceResources::CreateDeviceResources to use IDXGIAdapter

// Create the Direct3D 11 API device object and a corresponding context.
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;

const D3D_DRIVER_TYPE driverType = m_dxgiAdapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
const HRESULT hr = D3D11CreateDevice(
    m_dxgiAdapter.Get(),        // Either nullptr, or the primary adapter determined by Windows Holographic.
    driverType,                 // Create a device using the hardware graphics driver.
    0,                          // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
    creationFlags,              // Set debug and Direct2D compatibility flags.
    featureLevels,              // List of feature levels this app can support.
    ARRAYSIZE(featureLevels),   // Size of the list above.
    D3D11_SDK_VERSION,          // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
    &device,                    // Returns the Direct3D device created.
    &m_d3dFeatureLevel,         // Returns feature level of device created.
    &context                    // Returns the device immediate context.
);

Grafica ibrida e Media FoundationHybrid graphics and Media Foundation

L'uso di Media Foundation nei sistemi ibridi può causare problemi in caso di danneggiamento del video o della trama video, in quanto Media Foundation viene utilizzato per impostazione predefinita un comportamento del sistema.Using Media Foundation on hybrid systems may cause issues where video won't render or video texture are corrupt because Media Foundation is defaulting to a system behavior. In alcuni scenari, la creazione di un ID3D11Device separato è necessaria per supportare il multithreading e vengono impostati i flag di creazione corretti.In some scenarios, creating a separate ID3D11Device is required to support multi-threading and the correct creation flags are set.

Durante l'inizializzazione di ID3D11Device, D3D11_CREATE_DEVICE_VIDEO_SUPPORT flag deve essere definito come parte del D3D11_CREATE_DEVICE_FLAG.When initializing the ID3D11Device, D3D11_CREATE_DEVICE_VIDEO_SUPPORT flag must be defined as part of the D3D11_CREATE_DEVICE_FLAG. Una volta creato il dispositivo e il contesto, chiamare SetMultithreadProtected per abilitare il multithreading.Once the device and context is created, call SetMultithreadProtected to enable multithreading. Per associare il dispositivo a IMFDXGIDeviceManager, usare la funzione IMFDXGIDeviceManager:: ResetDevice .To associate the device with the IMFDXGIDeviceManager, use the IMFDXGIDeviceManager::ResetDevice function.

Codice per associare un ID3D11Device a IMFDXGIDeviceManager:Code to associate a ID3D11Device with IMFDXGIDeviceManager:

// create dx device for media pipeline
winrt::com_ptr<ID3D11Device> spMediaDevice;

// See above. Also make sure to enable the following flags on the D3D11 device:
//   * D3D11_CREATE_DEVICE_VIDEO_SUPPORT
//   * D3D11_CREATE_DEVICE_BGRA_SUPPORT
if (FAILED(CreateMediaDevice(spAdapter.get(), &spMediaDevice)))
    return;                                                     

// Turn multithreading on 
winrt::com_ptr<ID3D10Multithread> spMultithread;
if (spContext.try_as(spMultithread))
{
    spMultithread->SetMultithreadProtected(TRUE);
}

// lock the shared dxgi device manager
// call MFUnlockDXGIDeviceManager when no longer needed
UINT uiResetToken;
winrt::com_ptr<IMFDXGIDeviceManager> spDeviceManager;
hr = MFLockDXGIDeviceManager(&uiResetToken, spDeviceManager.put());
if (FAILED(hr))
    return hr;
    
// associate the device with the manager
hr = spDeviceManager->ResetDevice(spMediaDevice.get(), uiResetToken);
if (FAILED(hr))
    return hr;

Vedere ancheSee also