ID3D11Texture2D 到 ID2D1Bitmap,可以吗?

Posted

技术标签:

【中文标题】ID3D11Texture2D 到 ID2D1Bitmap,可以吗?【英文标题】:ID3D11Texture2D to ID2D1Bitmap, is it possible? 【发布时间】:2014-04-18 10:59:34 【问题描述】:

我正在开发一款游戏的扩展,它只打开一个 HDC 供插件开发者使用。

但是,我已经用尽了 GDI+/Direct2D 绘图的可能性,这些可能性对于我想要完成的图像效果(加法、混合、乘法混合等)来说已经足够快了。

我很清楚 Direct2D 提供了一个效果工具包,但它需要平台更新(对于 Windows 7),这根本不理想。

因此我只剩下 Direct3D。 MSDN/Google 搜索提供了很多方法来做 D2D -> D3D,但 ZERO 展示了如何做 D3D -> D2D。我知道有一种方法可以转换 D3D -> D2D,即映射和复制像素数据,但这是非常低效的,因为(如果我是对的)它从 GPU VRAM -> CPU/RAM -> GPU VRAM 传输。我可能只会将其用作最后的选择....

或者,如果有人知道如何从 D3D11 中的 RenderTarget 获取 HDC 以便我可以 BitBlt,它也可能有效。

如果有人能提供帮助,我将不胜感激。

【问题讨论】:

不是很清楚你的问题,你想要什么? 捕获 D3D 的 Backbuffer 作为 ID3D11Texture2D 并转换为 ID2D1Bitmap 以发送到 D2D,如果可能的话如何做到这一点。希望它足够清楚。 您应该描述一些有关业务逻辑的内容,您是否要在 D3D 和 D2D 之间进行实时同步? 是的,因为我使用 D3D 进行图像处理,所以我需要它几乎立即出现。 (但不需要每帧都更新,只在图像发生变化时更新) 【参考方案1】:

这应该可行:

bool ConvertID3D11Texture2DToID2D1Bitmap(ID3D11DeviceContext* ctx, 
                                         ID3D11Texture2D* texture, 
                                         ID2D1Bitmap* bitmap)

      ComPtr<IDXGISurface> dxgiSurface;
      HRESULT hr = bitmap->GetSurface(&dxgiSurface);
      if (hr != S_OK)
           return false;
      ComPtr<ID3D11Resource> d3dResource;
      hr = dxgiSurface.As(&d3dResource);
      if (hr != S_OK)
           return false;
      ctx->CopyResource(d3dResource.Get(), texture);

所有工作都在 GPU 上完成。您应该确保纹理和位图具有相同的格式。

【讨论】:

【参考方案2】:

您可以使用ID2D1RenderTarget::CreateSharedBitmap 创建与IDXGISurface 共享表面的ID2D1Bitmap

引用:...您可以将IDXGISurface 表面传递给CreateSharedBitmap 方法,以与Direct3D 共享视频内存并将Direct3D 内容作为ID2D1Bitmap 操作。

【讨论】:

【参考方案3】:

好的,我想通了。可能不是最有效的,但可以完成工作。 没有 memcpy,bitblt(尽管内存中的 CreateBitmap 内部可能有这些函数)。也避免了所有 DXGI 版本的废话。

    D3D11_TEXTURE2D_DESC td;
    m_backBufferTexture->GetDesc(&td);
    td.Usage = D3D11_USAGE_STAGING;
    td.BindFlags = 0;
    td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;

    m_pDevice->CreateTexture2D( &td, NULL, &(m_pNewTexture) );
    m_pContext->CopyResource(m_pNewTexture, m_backBufferTexture);
    m_pNewTexture->QueryInterface(__uuidof(IDXGISurface), (void**)&m_NewTextDXGI);

    DXGI_MAPPED_RECT bitmap2Dmap;
    m_NewTextDXGI->Map(&bitmap2Dmap,DXGI_MAP_READ);

    D2D1_PIXEL_FORMAT desc2d;
    D2D1_BITMAP_PROPERTIES bmpprops;

    desc2d.format = DXGI_FORMAT_B8G8R8A8_UNORM;
    desc2d.alphaMode = D2D1_ALPHA_MODE_IGNORE; // Adapt to your needs.      

    bmpprops.dpiX = 96.0f;
    bmpprops.dpiY = 96.0f;
    bmpprops.pixelFormat = desc2d;


    D2D1_SIZE_U size = D2D1::SizeU(
    dim.x,
    dim.y
    ); // Adapt to your own size.

    pRT->CreateBitmap(size,(void*)bitmap2Dmap.pBits,bitmap2Dmap.Pitch,bmpprops,&m_pD2DBitmap);
    m_NewTextDXGI->Unmap();

【讨论】:

嗨,我也在处理类似的情况,你能分享完整的代码吗?【参考方案4】:

看看Surface Sharing Between Windows Graphics APIs

您可以关注Direct3D 10.1 Device Sharing with Direct2D

部分

【讨论】:

以上是关于ID3D11Texture2D 到 ID2D1Bitmap,可以吗?的主要内容,如果未能解决你的问题,请参考以下文章

ID3D11Texture2D 到 ID2D1Bitmap,可以吗?

DirectX:以 DXGI_FORMAT_NV12 格式从 ID3D11Texture2D 获取 RGB 数据的最佳方法?

C#texture2d如何转换为cpu图像

MF SinkWriter 写入样本失败

ID3D11VideoDevice::CreateVideoDecoderOutputView 失败

C2259:“ID3D11ShaderResourceView”无法实例化抽象类 - DX11