问题
I am working on a extension to a game which only opens a HDC for addon developers to draw on.
However, I have exhausted GDI+/Direct2D drawing possibilities that is fast enough for what I want to accomplish - image effects(Additive, Blend, Multiply Blend etc).
I am well aware that Direct2D offers a effects toolkit however, that requires a platform update (for Windows 7) and that is not ideal at all.
Hence I am left with only Direct3D. MSDN/Google Search offers lots of ways to do D2D -> D3D, but ZERO shows how to do D3D -> D2D. I know there is a method to convert D3D - > D2D and that is to map and copy pixel data, but that is highly inefficient as (if I am right) it transfers from GPU VRAM -> CPU/RAM -> GPU VRAM. I will probably only use that as a last alternative....
Alternatively, it might also work if someone has any idea on how to grab a HDC from RenderTarget in D3D11 so that I can BitBlt.
I would be grateful if anyone can help with this.
回答1:
ok I figured it out. Probably not the most efficient, but does the job. No memcpy,bitblt (although inside the CreateBitmap from memory might have those functions inside). Avoids all the DXGI version crap too.
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();
回答2:
Take a look at Surface Sharing Between Windows Graphics APIs
you can focus on section Direct3D 10.1 Device Sharing with Direct2D
回答3:
You can use ID2D1RenderTarget::CreateSharedBitmap to create ID2D1Bitmap
that shares surface with the IDXGISurface
.
Quote: ... you can pass an IDXGISurface
surface to the CreateSharedBitmap
method to share video memory with Direct3D and manipulate Direct3D content as an ID2D1Bitmap.
回答4:
This should work:
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);
}
All the job is done on GPU. You should ensure the texture and the bitmap have same format.
来源:https://stackoverflow.com/questions/22383209/id3d11texture2d-to-id2d1bitmap-is-it-possible