首页 > 解决方案 > Direct2D 在“硬件模式”渲染目标上不绘制任何内容

问题描述

我正在尝试根据MSDN 文档在 Direct3D 创建的渲染目标上使用 Direct2D。不使用 HWND 渲染缓冲区的想法是让应用程序能够轻松切换目标,因此我可以例如将静态绘画渲染到位图并使用直接命令进行任何依赖于运行时的绘画。创建接口的代码如下:

bool CreateD2DC(HWND hh)
{
    D2D& d = *this;
    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_1
    };
    auto de = D3D_DRIVER_TYPE_HARDWARE;
    if (IsCurrentSessionRemoteable())
        de = D3D_DRIVER_TYPE_SOFTWARE;
    D3D_FEATURE_LEVEL m_featureLevel;
    D3D11CreateDevice(
        nullptr,                    // specify null to use the default adapter
        de,
        0,
        D3D11_CREATE_DEVICE_BGRA_SUPPORT,              // optionally set debug and Direct2D compatibility flags
        featureLevels,              // list of feature levels this app can support
        ARRAYSIZE(featureLevels),   // number of possible feature levels
        D3D11_SDK_VERSION,
        &d.device,                // returns the Direct3D device created
        &m_featureLevel,            // returns feature level of device created
        &d.context                    // returns the device immediate context
    );
    if (!d.device)
        return 0;

    d.dxgiDevice = d.device;
    if (!d.dxgiDevice)
        return 0;

    D2D1_CREATION_PROPERTIES dp;
    dp.threadingMode = D2D1_THREADING_MODE::D2D1_THREADING_MODE_SINGLE_THREADED;
    dp.debugLevel = D2D1_DEBUG_LEVEL::D2D1_DEBUG_LEVEL_NONE;
    dp.options = D2D1_DEVICE_CONTEXT_OPTIONS::D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
    D2D1CreateDevice(d.dxgiDevice, dp, &d.m_d2dDevice);
    if (!d.m_d2dDevice)
        return 0;

    d.m_d2dDevice->CreateDeviceContext(
        D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
        &d.m_d2dContext);
    if (!d.m_d2dContext)
        return 0;

    // Allocate a descriptor.
    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
    swapChainDesc.Width = 0;                           // use automatic sizing
    swapChainDesc.Height = 0;
    swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
    swapChainDesc.Stereo = false;
    swapChainDesc.SampleDesc.Count = 1;                // don't use multi-sampling
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.BufferCount = 2;                     // use double buffering to enable flip
    swapChainDesc.Scaling = DXGI_SCALING_NONE;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all apps must use this SwapEffect
    swapChainDesc.Flags = 0;

    d.dxgiDevice->GetAdapter(&d.dxgiAdapter);
    if (!d.dxgiAdapter)
        return 0;

    // Get the factory object that created the DXGI device.
    d.dxgiAdapter->GetParent(IID_PPV_ARGS(&d.dxgiFactory));
    if (!d.dxgiFactory)
        return 0;

    d.dxgiFactory->CreateSwapChainForHwnd(
        d.device,
        hh, &swapChainDesc,
        nullptr,    // allow on all displays
        nullptr,    // allow on all displays
        &d.m_swapChain);
    if (!d.m_swapChain)
        return 0;

    d.dxgiDevice->SetMaximumFrameLatency(1);

    d.m_swapChain->GetBuffer(0, IID_PPV_ARGS(&d.backBuffer));
    if (!d.backBuffer)
        return 0;

    // Now we set up the Direct2D render target bitmap linked to the swapchain. 
    D2D1_BITMAP_PROPERTIES1 bitmapProperties;
    bitmapProperties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
    bitmapProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
    bitmapProperties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
    bitmapProperties.dpiX = 96;
    bitmapProperties.dpiY = 96;
    bitmapProperties.colorContext = 0;


    // Direct2D needs the dxgi version of the backbuffer surface pointer.
    d.m_swapChain->GetBuffer(0, IID_PPV_ARGS(&d.dxgiBackBuffer));
    if (!d.dxgiBackBuffer)
        return 0;

    // Get a D2D surface from the DXGI back buffer to use as the D2D render target.
    d.m_d2dContext->CreateBitmapFromDxgiSurface(
        d.dxgiBackBuffer,
        &bitmapProperties,
        &d.m_d2dTargetBitmap);
    if (!d.m_d2dTargetBitmap)
        return 0;


    // Now we can set the Direct2D render target.
    d.m_d2dContext->SetTarget(d.m_d2dTargetBitmap);
    return true;
}

问题是这段代码:

auto de = D3D_DRIVER_TYPE_HARDWARE;

使用时,Direct2D 不写入任何内容,但EndDraw()返回 S_OK。如果我使用D3D_DRIVER_TYPE_SOFTWARE,一切正常。

我究竟做错了什么?

标签: winapidirectxdirect3ddirect2d

解决方案


推荐阅读