Interoperatività di WPF e Direct3D9WPF and Direct3D9 Interoperation

È possibile includere contenuto Direct3D9 in un'applicazione Windows Presentation Foundation (WPF).You can include Direct3D9 content in a Windows Presentation Foundation (WPF) application. In questo argomento viene descritto come creare contenuto Direct3D9 in modo che in modo efficiente interagisce con WPF.This topic describes how to create Direct3D9 content so that it efficiently interoperates with WPF.

Nota

Quando si utilizza il contenuto Direct3D9 in WPF, è necessario anche valutare le prestazioni.When using Direct3D9 content in WPF, you also need to think about performance. Per ulteriori informazioni su come ottimizzare le prestazioni, vedere considerazioni sulle prestazioni per l'interoperabilità di WPF e Direct3D9.For more information about how to optimize for performance, see Performance Considerations for Direct3D9 and WPF Interoperability.

Buffer di visualizzazioneDisplay Buffers

Il D3DImage classe gestisce due buffer di visualizzazione, ovvero il buffer nascosto e buffer front-.The D3DImage class manages two display buffers, which are called the back buffer and the front buffer. Il buffer rappresenta la superficie Direct3D9.The back buffer is your Direct3D9 surface. Le modifiche apportate al buffer nascosto vengono copiate nel front buffer quando si chiama il Unlock metodo.Changes to the back buffer are copied forward to the front buffer when you call the Unlock method.

Nella figura seguente viene illustrata la relazione tra il buffer nascosto e il buffer anteriore.The following illustration shows the relationship between the back buffer and the front buffer.

Buffer di visualizzazione D3DImageD3DImage display buffers

Creazione di un dispositivo Direct3D9Direct3D9 Device Creation

Per eseguire il rendering Direct3D9 contenuto, è necessario creare un dispositivo Direct3D9.To render Direct3D9 content, you must create a Direct3D9 device. Esistono due oggetti Direct3D9 che è possibile utilizzare per creare un dispositivo, IDirect3D9 e IDirect3D9Ex.There are two Direct3D9 objects that you can use to create a device, IDirect3D9 and IDirect3D9Ex. Utilizzare questi oggetti per creare IDirect3DDevice9 e IDirect3DDevice9Ex dispositivi, rispettivamente.Use these objects to create IDirect3DDevice9 and IDirect3DDevice9Ex devices, respectively.

Creare un dispositivo chiamando uno dei metodi seguenti.Create a device by calling one of the following methods.

  • IDirect3D9 * Direct3DCreate9(UINT SDKVersion);

  • HRESULT Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex **ppD3D);

In Windows Vista o versioni successive del sistema operativo, utilizzare il Direct3DCreate9Ex metodo con una visualizzazione che è configurata per l'utilizzo di Windows Driver Model (WDDM Display).On Windows Vista or later operating system, use the Direct3DCreate9Ex method with a display that is configured to use the Windows Display Driver Model (WDDM). Utilizzare il Direct3DCreate9 metodo su qualsiasi altra piattaforma.Use the Direct3DCreate9 method on any other platform.

Disponibilità del metodo Direct3DCreate9ExAvailability of the Direct3DCreate9Ex method

È il d3d9.dll il Direct3DCreate9Ex metodo solo in Windows Vista o versioni successive del sistema operativo.The d3d9.dll has the Direct3DCreate9Ex method only on Windows Vista or later operating system. Se si collega direttamente la funzione in Windows XP, l'applicazione non riesce a caricare.If you directly link the function on Windows XP, your application fails to load. Per determinare se il Direct3DCreate9Ex metodo è supportato, caricare la DLL e cercare l'indirizzo di routine.To determine whether the Direct3DCreate9Ex method is supported, load the DLL and look for the proc address. Il codice seguente viene illustrato come verificare la presenza di Direct3DCreate9Ex metodo.The following code shows how to test for the Direct3DCreate9Ex method. Per un esempio di codice completo, vedere procedura dettagliata: creazione di contenuto Direct3D9 per l'Hosting in WPF.For a full code example, see Walkthrough: Creating Direct3D9 Content for Hosting in WPF.

HRESULT
CRendererManager::EnsureD3DObjects()
{
    HRESULT hr = S_OK;

    HMODULE hD3D = NULL;
    if (!m_pD3D)
    {
        hD3D = LoadLibrary(TEXT("d3d9.dll"));
        DIRECT3DCREATE9EXFUNCTION pfnCreate9Ex = (DIRECT3DCREATE9EXFUNCTION)GetProcAddress(hD3D, "Direct3DCreate9Ex");
        if (pfnCreate9Ex)
        {
            IFC((*pfnCreate9Ex)(D3D_SDK_VERSION, &m_pD3DEx));
            IFC(m_pD3DEx->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&m_pD3D)));
        }
        else
        {
            m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
            if (!m_pD3D) 
            {
                IFC(E_FAIL);
            }
        }

        m_cAdapters = m_pD3D->GetAdapterCount();
    }

Cleanup:
    if (hD3D)
    {
        FreeLibrary(hD3D);
    }

    return hr;
}

Creazione di un HWNDHWND Creation

Creazione di un dispositivo richiede un elemento HWND.Creating a device requires an HWND. In generale, si crea un HWND fittizio Direct3D9 da utilizzare.In general, you create a dummy HWND for Direct3D9 to use. Esempio di codice seguente viene illustrato come creare un HWND fittizio.The following code example shows how to create a dummy HWND.

HRESULT
CRendererManager::EnsureHWND()
{
    HRESULT hr = S_OK;

    if (!m_hwnd)
    {
        WNDCLASS wndclass;

        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = DefWindowProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = NULL;
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;

        if (!RegisterClass(&wndclass))
        {
            IFC(E_FAIL);
        }

        m_hwnd = CreateWindow(szAppName,
                            TEXT("D3DImageSample"),
                            WS_OVERLAPPEDWINDOW,
                            0,                   // Initial X
                            0,                   // Initial Y
                            0,                   // Width
                            0,                   // Height
                            NULL,
                            NULL,
                            NULL,
                            NULL);
    }

Cleanup:
    return hr;
}

Parametri presentiPresent Parameters

La creazione di un dispositivo richiede anche un D3DPRESENT_PARAMETERS struct, ma solo alcuni parametri sono importanti.Creating a device also requires a D3DPRESENT_PARAMETERS struct, but only a few parameters are important. Questi parametri vengono scelti per ridurre il footprint di memoria.These parameters are chosen to minimize the memory footprint.

Impostare il BackBufferHeight e BackBufferWidth campi su 1.Set the BackBufferHeight and BackBufferWidth fields to 1. Se li su 0, che è possibile impostare le dimensioni di HWND.Setting them to 0 causes them to be set to the dimensions of the HWND.

Impostare sempre la D3DCREATE_MULTITHREADED e D3DCREATE_FPU_PRESERVE flag per evitare il danneggiamento della memoria utilizzata da Direct3D9 e per impedire a Direct3D9 di modificare le impostazioni FPU.Always set the D3DCREATE_MULTITHREADED and D3DCREATE_FPU_PRESERVE flags to prevent corrupting memory used by Direct3D9 and to prevent Direct3D9 from changing FPU settings.

Il codice seguente viene illustrato come inizializzare il D3DPRESENT_PARAMETERS struct.The following code shows how to initialize the D3DPRESENT_PARAMETERS struct.

HRESULT 
CRenderer::Init(IDirect3D9 *pD3D, IDirect3D9Ex *pD3DEx, HWND hwnd, UINT uAdapter)
{
    HRESULT hr = S_OK;

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.BackBufferHeight = 1;
    d3dpp.BackBufferWidth = 1;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    D3DCAPS9 caps;
    DWORD dwVertexProcessing;
    IFC(pD3D->GetDeviceCaps(uAdapter, D3DDEVTYPE_HAL, &caps));
    if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == D3DDEVCAPS_HWTRANSFORMANDLIGHT)
    {
        dwVertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    }
    else
    {
        dwVertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    if (pD3DEx)
    {
        IDirect3DDevice9Ex *pd3dDevice = NULL;
        IFC(pD3DEx->CreateDeviceEx(
            uAdapter,
            D3DDEVTYPE_HAL,
            hwnd,
            dwVertexProcessing | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
            &d3dpp,
            NULL,
            &m_pd3dDeviceEx
            ));

        IFC(m_pd3dDeviceEx->QueryInterface(__uuidof(IDirect3DDevice9), reinterpret_cast<void**>(&m_pd3dDevice)));  
    }
    else 
    {
        assert(pD3D);

        IFC(pD3D->CreateDevice(
            uAdapter,
            D3DDEVTYPE_HAL,
            hwnd,
            dwVertexProcessing | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
            &d3dpp,
            &m_pd3dDevice
            ));
    }

Cleanup:
    return hr;
}

Creazione di destinazione di rendering del Buffer nascostoCreating the Back Buffer Render Target

Per visualizzare il contenuto Direct3D9 in un D3DImage, si crea una superficie di Direct3D9 e assegnarlo chiamando il SetBackBuffer metodo.To display Direct3D9 content in a D3DImage, you create a Direct3D9 surface and assign it by calling the SetBackBuffer method.

Supporto per gli Adapter di verificaVerifying Adapter Support

Prima di creare un'area, verificare che tutti gli adapter supportano la superficie di attacco proprietà che necessarie.Before creating a surface, verify that all adapters support the surface properties you require. Anche se si esegue il rendering di una sola scheda, la finestra WPF è visualizzata in qualsiasi scheda nel sistema.Even if you render to only one adapter, the WPF window may be displayed on any adapter in the system. È necessario scrivere sempre codice Direct3D9 che gestisce le configurazioni delle multi- schede e controllare tutte le schede per il supporto, poiché WPF è possibile spostare l'area tra le schede disponibili.You should always write Direct3D9 code that handles multi-adapter configurations, and you should check all adapters for support, because WPF might move the surface among the available adapters.

Esempio di codice seguente viene illustrato come controllare tutte le schede sul sistema per Direct3D9 supportano.The following code example shows how to check all adapters on the system for Direct3D9 support.

HRESULT
CRendererManager::TestSurfaceSettings()
{
    HRESULT hr = S_OK;

    D3DFORMAT fmt = m_fUseAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8;

    // 
    // We test all adapters because because we potentially use all adapters.
    // But even if this sample only rendered to the default adapter, you
    // should check all adapters because WPF may move your surface to
    // another adapter for you!
    //

    for (UINT i = 0; i < m_cAdapters; ++i)
    {
        // Can we get HW rendering?
        IFC(m_pD3D->CheckDeviceType(
            i,
            D3DDEVTYPE_HAL,
            D3DFMT_X8R8G8B8,
            fmt,
            TRUE
            )); 

        // Is the format okay?
        IFC(m_pD3D->CheckDeviceFormat(
            i,
            D3DDEVTYPE_HAL,
            D3DFMT_X8R8G8B8,
            D3DUSAGE_RENDERTARGET | D3DUSAGE_DYNAMIC, // We'll use dynamic when on XP
            D3DRTYPE_SURFACE,
            fmt
            ));

        // D3DImage only allows multisampling on 9Ex devices. If we can't 
        // multisample, overwrite the desired number of samples with 0.
        if (m_pD3DEx && m_uNumSamples > 1)
        {   
            assert(m_uNumSamples <= 16);

            if (FAILED(m_pD3D->CheckDeviceMultiSampleType(
                i,
                D3DDEVTYPE_HAL,
                fmt,
                TRUE,
                static_cast<D3DMULTISAMPLE_TYPE>(m_uNumSamples),
                NULL
                )))
            {
                m_uNumSamples = 0;
            }
        }
        else
        {
            m_uNumSamples = 0;
        }
    }

Cleanup:
    return hr;
}

La creazione della superficieCreating the Surface

Prima di creare un'area, verificare che le funzionalità dei dispositivi supportano buone prestazioni nel sistema operativo di destinazione.Before creating a surface, verify that the device capabilities support good performance on the target operating system. Per ulteriori informazioni, vedere considerazioni sulle prestazioni per l'interoperabilità di WPF e Direct3D9.For more information, see Performance Considerations for Direct3D9 and WPF Interoperability.

Dopo avere verificato le funzionalità di dispositivo, è possibile creare l'area.When you have verified device capabilities, you can create the surface. Esempio di codice seguente viene illustrato come creare la destinazione di rendering.The following code example shows how to create the render target.

HRESULT
CRenderer::CreateSurface(UINT uWidth, UINT uHeight, bool fUseAlpha, UINT m_uNumSamples)
{
    HRESULT hr = S_OK;

    SAFE_RELEASE(m_pd3dRTS);

    IFC(m_pd3dDevice->CreateRenderTarget(
        uWidth,
        uHeight,
        fUseAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8,
        static_cast<D3DMULTISAMPLE_TYPE>(m_uNumSamples),
        0,
        m_pd3dDeviceEx ? FALSE : TRUE,  // Lockable RT required for good XP perf
        &m_pd3dRTS,
        NULL
        ));

    IFC(m_pd3dDevice->SetRenderTarget(0, m_pd3dRTS));

Cleanup:
    return hr;
}

WDDMWDDM

In Windows Vista e versioni successive, che sono configurati per l'utilizzo di WDDM, è possibile creare una trama di destinazione di rendering e passare la superficie di livello 0 per il SetBackBuffer metodo.On Windows Vista and later operating systems, which are configured to use the WDDM, you can create a render target texture and pass the level 0 surface to the SetBackBuffer method. Questo approccio non è consigliato in Windows XP, perché non è possibile creare una trama di destinazione di rendering bloccabile e prestazioni risultano ridotte.This approach is not recommended on Windows XP, because you cannot create a lockable render target texture and performance will be reduced.

Gestione dello stato del dispositivoHandling Device State

Il D3DImage classe gestisce due buffer di visualizzazione, ovvero il buffer nascosto e buffer front-.The D3DImage class manages two display buffers, which are called the back buffer and the front buffer. Il buffer rappresenta la superficie di Direct3D.The back buffer is your Direct3D surface. Le modifiche apportate al buffer nascosto vengono copiate nel front buffer quando si chiama il Unlock (metodo), in cui vengono visualizzati nell'hardware.Changes to the back buffer are copied forward to the front buffer when you call the Unlock method, where it is displayed on the hardware. In alcuni casi, il front buffer non è più disponibile.Occasionally, the front buffer becomes unavailable. La mancanza di disponibilità può essere causata dal blocco dello schermo, applicazioni Direct3D esclusive a schermo intero, cambio utente o altre attività di sistema.This lack of availability can be caused by screen locking, full-screen exclusive Direct3D applications, user-switching, or other system activities. In questo caso, l'applicazione WPF notifica gestendo il IsFrontBufferAvailableChanged evento.When this occurs, your WPF application is notified by handling the IsFrontBufferAvailableChanged event. Modalità di risposta dell'applicazione nel front buffer non sono più disponibili dipende dal tipo di attivazione WPF per eseguire il fallback per il rendering software.How your application responds to the front buffer becoming unavailable depends on whether WPF is enabled to fall back to software rendering. Il SetBackBuffer metodo presenta un overload che accetta un parametro che specifica se il fallback WPF per il rendering software.The SetBackBuffer method has an overload that takes a parameter that specifies whether WPF falls back to software rendering.

Quando si chiama il SetBackBuffer(D3DResourceType, IntPtr) overload o chiamare il SetBackBuffer(D3DResourceType, IntPtr, Boolean) eseguire l'overload con il enableSoftwareFallback parametro impostato su false, il sistema di rendering rilascia il riferimento al buffer nascosto quando il front buffer non è più disponibile e non è visualizzato.When you call the SetBackBuffer(D3DResourceType, IntPtr) overload or call the SetBackBuffer(D3DResourceType, IntPtr, Boolean) overload with the enableSoftwareFallback parameter set to false, the rendering system releases its reference to the back buffer when the front buffer becomes unavailable and nothing is displayed. Quando il buffer anteriore è nuovamente disponibile, il sistema di rendering genera il IsFrontBufferAvailableChanged evento per notificare all'applicazione WPF.When the front buffer is available again, the rendering system raises the IsFrontBufferAvailableChanged event to notify your WPF application. È possibile creare un gestore eventi per il IsFrontBufferAvailableChanged riavviare il rendering con una superficie Direct3D valida dell'evento.You can create an event handler for the IsFrontBufferAvailableChanged event to restart rendering again with a valid Direct3D surface. Per riavviare il rendering, è necessario chiamare SetBackBuffer.To restart rendering, you must call SetBackBuffer.

Quando si chiama il SetBackBuffer(D3DResourceType, IntPtr, Boolean) eseguire l'overload con il enableSoftwareFallback parametro impostato su true, il sistema di rendering mantiene il relativo riferimento al buffer nascosto quando il front buffer non è disponibile, in modo non è necessario chiamare SetBackBuffer quando all'inizio buffer sarà nuovamente disponibile.When you call the SetBackBuffer(D3DResourceType, IntPtr, Boolean) overload with the enableSoftwareFallback parameter set to true, the rendering system retains its reference to the back buffer when the front buffer becomes unavailable, so there is no need to call SetBackBuffer when the front buffer is available again.

Quando è abilitato per il rendering software, potrebbero verificarsi situazioni in cui il dispositivo dell'utente non è più disponibile, ma il sistema di rendering mantiene un riferimento all'area di Direct3D.When software rendering is enabled, there may be situations where the user’s device becomes unavailable, but the rendering system retains a reference to the Direct3D surface. Per verificare se un dispositivo Direct3D9 è disponibile, chiamare il TestCooperativeLevel metodo.To check whether a Direct3D9 device is unavailable, call the TestCooperativeLevel method. Per verificare una chiamata di dispositivi Direct3D9Ex il CheckDeviceState (metodo), in quanto il TestCooperativeLevel metodo è obsoleto e restituisce sempre esito positivo.To check a Direct3D9Ex devices call the CheckDeviceState method, because the TestCooperativeLevel method is deprecated and always returns success. Se il dispositivo dell'utente non è più disponibile, chiamare SetBackBuffer per rilasciare il riferimento di WPF al buffer nascosto.If the user device has become unavailable, call SetBackBuffer to release WPF’s reference to the back buffer. Per reimpostare il dispositivo, è necessario chiamare SetBackBuffer con il backBuffer parametro impostato su nulle quindi chiamare SetBackBuffer con backBuffer impostato su una superficie Direct3D valida.If you need to reset your device, call SetBackBuffer with the backBuffer parameter set to null, and then call SetBackBuffer again with backBuffer set to a valid Direct3D surface.

Chiamare il Reset metodo per recuperare da un dispositivo non valido solo se si implementa il supporto per più adattatori.Call the Reset method to recover from an invalid device only if you implement multi-adapter support. In caso contrario, rilascia tutte le interfacce Direct3D9 e ricrearle completamente.Otherwise, release all Direct3D9 interfaces and re-create them completely. Se è stato modificato il layout dell'adattatore, gli oggetti Direct3D9 creati prima della modifica non vengono aggiornati.If the adapter layout has changed, Direct3D9 objects created before the change are not updated.

Gestione del ridimensionamentoHandling Resizing

Se un D3DImage viene visualizzata una risoluzione diversa da quella nativa, viene ridimensionato in base alle corrente BitmapScalingMode, ad eccezione del fatto che Bilinear verrà sostituito con Fant.If a D3DImage is displayed at a resolution other than its native size, it is scaled according to the current BitmapScalingMode, except that Bilinear is substituted for Fant.

Se è necessaria fedeli, è necessario creare un nuovo superficie quando il contenitore di D3DImage Modifica dimensione.If you require higher fidelity, you must create a new surface when the container of the D3DImage changes size.

Esistono tre possibili approcci per gestire il ridimensionamento.There are three possible approaches to handle resizing.

  • Creare una nuova area quando cambiano le dimensioni fanno parte del sistema di layout.Participate in the layout system and create a new surface when the size changes. Non creare troppe superfici, perché non è possibile esaurire o frammentare la memoria video.Do not create too many surfaces, because you may exhaust or fragment video memory.

  • Attendere un evento di ridimensionamento non è stata eseguita per un determinato periodo di tempo per creare la nuova area.Wait until a resize event has not occurred for a fixed period of time to create the new surface.

  • Creare un DispatcherTimer che controlla le dimensioni del contenitore varie volte al secondo.Create a DispatcherTimer that checks the container dimensions several times per second.

Ottimizzazione di più monitorMulti-monitor Optimization

In modo significativo calo delle prestazioni può verificarsi quando il sistema di rendering sposta un D3DImage in un altro monitor.Significantly reduced performance can result when the rendering system moves a D3DImage to another monitor.

In WDDM, purché i monitoraggi si trovano nello stesso video card e si utilizza Direct3DCreate9Ex, non vi è alcuna riduzione delle prestazioni.On WDDM, as long as the monitors are on the same video card and you use Direct3DCreate9Ex, there is no reduction in performance. Se i monitoraggi sono sulle schede video separate, le prestazioni sono ridotte.If the monitors are on separate video cards, performance is reduced. In Windows XP, le prestazioni sono sempre ridotte.On Windows XP, performance is always reduced.

Quando il D3DImage viene spostato in un altro monitor, è possibile creare una nuova superficie nell'adattatore corrispondente per ripristinare le buone prestazioni.When the D3DImage moves to another monitor, you can create a new surface on the corresponding adapter to restore good performance.

Per evitare la riduzione delle prestazioni, è possibile scrivere codice in modo specifico per il caso di più monitor.To avoid the performance penalty, write code specifically for the multi-monitor case. Nell'elenco seguente viene illustrato un modo per scrivere codice più monitor.The following list shows one way to write multi-monitor code.

  1. Trovare un punto del D3DImage nello spazio dello schermo con il Visual.ProjectToScreen metodo.Find a point of the D3DImage in screen space with the Visual.ProjectToScreen method.

  2. Utilizzare il MonitorFromPoint metodo GDI per trovare il monitoraggio in cui viene visualizzato il punto.Use the MonitorFromPoint GDI method to find the monitor that is displaying the point.

  3. Utilizzare il IDirect3D9::GetAdapterMonitor metodo per trovare l'adattatore Direct3D9 il monitor si trova.Use the IDirect3D9::GetAdapterMonitor method to find which Direct3D9 adapter the monitor is on.

  4. Se l'adapter non corrisponde l'adapter per il buffer nascosto, creare un nuovo buffer nascosto nel nuovo monitor e assegnarlo al D3DImage buffer nascosto.If the adapter is not the same as the adapter with the back buffer, create a new back buffer on the new monitor and assign it to the D3DImage back buffer.

Nota

Se il D3DImage monitor gestisce, le prestazioni saranno lente, salvo nel caso WDDM e IDirect3D9Ex sulla stessa scheda.If the D3DImage straddles monitors, performance will be slow, except in the case of WDDM and IDirect3D9Ex on the same adapter. Non è possibile migliorare le prestazioni in questa situazione.There is no way to improve performance in this situation.

Esempio di codice seguente viene illustrato come trovare il monitoraggio corrente.The following code example shows how to find the current monitor.

void 
CRendererManager::SetAdapter(POINT screenSpacePoint)
{
    CleanupInvalidDevices();

    //
    // After CleanupInvalidDevices, we may not have any D3D objects. Rather than
    // recreate them here, ignore the adapter update and wait for render to recreate.
    //

    if (m_pD3D && m_rgRenderers)
    {
        HMONITOR hMon = MonitorFromPoint(screenSpacePoint, MONITOR_DEFAULTTONULL);

        for (UINT i = 0; i < m_cAdapters; ++i)
        {
            if (hMon == m_pD3D->GetAdapterMonitor(i))
            {
                m_pCurrentRenderer = m_rgRenderers[i];
                break;
            }
        }
    }
}

Aggiornare il monitoraggio quando il D3DImage le modifiche apportate a dimensioni o la posizione del contenitore o l'aggiornamento del monitoraggio utilizzando un DispatcherTimer che aggiorna più volte al secondo.Update the monitor when the D3DImage container's size or position changes, or update the monitor by using a DispatcherTimer that updates a few times per second.

Rendering Software WPFWPF Software Rendering

WPF esegue il rendering in modo sincrono sul thread dell'interfaccia utente in software nelle situazioni seguenti.WPF renders synchronously on the UI thread in software in the following situations.

Quando si verifica una di queste situazioni, il rendering viene chiamato il CopyBackBuffer metodo per copiare il buffer hardware nel software.When one of these situations occurs, the rendering system calls the CopyBackBuffer method to copy the hardware buffer to software. L'implementazione predefinita chiama il GetRenderTargetData metodo con la superficie.The default implementation calls the GetRenderTargetData method with your surface. Poiché questa chiamata si trova di fuori il criterio di blocco/sblocco, potrebbe non riuscire.Because this call occurs outside of the Lock/Unlock pattern, it may fail. In questo caso, il CopyBackBuffer restituisce null e viene visualizzata alcuna immagine.In this case, the CopyBackBuffer method returns null and no image is displayed.

È possibile eseguire l'override di CopyBackBuffer metodo, chiamare l'implementazione di base, e se viene restituito null, è possibile restituire un segnaposto BitmapSource.You can override the CopyBackBuffer method, call the base implementation, and if it returns null, you can return a placeholder BitmapSource.

È anche possibile implementare direttamente il rendering software anziché chiamare l'implementazione di base.You can also implement your own software rendering instead of calling the base implementation.

Nota

Se viene eseguito il rendering completamente il software, WPF D3DImage non viene visualizzato perché WPF non dispone di un front buffer.If WPF is rendering completely in software, D3DImage is not shown because WPF does not have a front buffer.

Vedere ancheSee Also

D3DImage
Considerazioni sulle prestazioni per l'interoperabilità fra Direct3D9 e WPFPerformance Considerations for Direct3D9 and WPF Interoperability
Procedura dettagliata: Creazione di contenuto Direct3D9 per l'hosting in WPFWalkthrough: Creating Direct3D9 Content for Hosting in WPF
Procedura dettagliata: Hosting di contenuto Direct3D9 in WPFWalkthrough: Hosting Direct3D9 Content in WPF