C++11 从ID3D11Texture2D获取用于绘图的GDI DC

C++11 从ID3D11Texture2D获取用于绘图的GDI DC,c++11,gdi,directx-11,directx-9,texture2d,C++11,Gdi,Directx 11,Directx 9,Texture2d,我在directx9中有一个实现,我使用GDI DC来渲染图形。 但directx11中的类似代码没有获得GDI DC,而是引发无效调用异常 directx9中的实现: IF_DX9ERR_THROW_HR(m_spIDevice->CreateTexture(UINT(cSizeOverlay.cx), UINT(cSizeOverlay.cy), 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_spIOver

我在directx9中有一个实现,我使用GDI DC来渲染图形。 但directx11中的类似代码没有获得GDI DC,而是引发无效调用异常

directx9中的实现:

IF_DX9ERR_THROW_HR(m_spIDevice->CreateTexture(UINT(cSizeOverlay.cx), UINT(cSizeOverlay.cy), 1, D3DUSAGE_DYNAMIC,  D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_spIOverlay, nullptr));
m_spIOverlaySurface = nullptr;
IF_DX9ERR_THROW_HR(m_spIOverlay->GetSurfaceLevel(0, &m_spIOverlaySurface));
D3DSURFACE_DESC descOverlay;
::ZeroMemory(&descOverlay, sizeof(descOverlay));
IF_DX9ERR_THROW_HR(m_spIOverlaySurface->GetDesc(&descOverlay));
// fill the texture with the color key
CRect cRect(0, 0, descOverlay.Width, descOverlay.Height);
HDC hDC = nullptr;
IF_DX9ERR_THROW_HR(m_spIOverlaySurface->GetDC(&hDC));
::SetBkColor(hDC, colKey);
::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, cRect, nullptr, 0, nullptr);
IF_DX9ERR_THROW_HR(m_spIOverlaySurface->ReleaseDC(hDC));
directx11中的实现:

D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = gsl::narrow_cast<UINT>(width);
desc.Height = gsl::narrow_cast<UINT>(height);
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;

ID3D11DevicePtr device = renderer->Device();
ID3D11Texture2DPtr  texture2D;
IF_FAILED_THROW_HR(device->CreateTexture2D(&desc, nullptr, &texture2D));    
// get texture surface
IDXGISurface1Ptr dxgiSurface1 = tex2D;

IF_FAILED_THROW_HR(dxgiSurface1->GetDC(FALSE, &m_overlayDC));
//Draw on the DC using GDI
if (!m_overlayDC) // we have lost the device
    THROW_PE(IDS_ERR_NO_VIDEO_HARDWARE);
::SetBkColor(m_overlayDC, m_effectConstants.m_keyColor);
::ExtTextOut(m_overlayDC, 0, 0, ETO_OPAQUE, overlayRect, nullptr, 0, nullptr);
//When finish drawing release the DC
dxgiSurface1->ReleaseDC(nullptr);

m_overlayDC = nullptr;
D3D11_TEXTURE2D_DESC DESC;
零内存(&desc,sizeof(desc));
描述宽度=gsl::窄铸件(宽度);
描述高度=gsl::窄铸件(高度);
desc.ArraySize=1;
描述格式=DXGI格式\u B8G8R8X8\u UNORM;
描述用法=D3D11\u用法\u动态;
desc.BindFlags=D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags=D3D11\u CPU\u访问\u写入;
desc.MipLevels=1;
desc.SampleDesc.Count=1;
desc.miscsflags=D3D11_资源_MISC_GDI_兼容;
ID3D11DevicePtr设备=渲染器->设备();
ID3D11Texture2DPtr texture2D;
如果失败,抛出(设备->创建纹理2d(&desc、nullptr和纹理2d));
//获取纹理表面
IDXGISurface1Ptr dxgiSurface1=tex2D;
如果失败,则抛出(dxgiSurface1->GetDC(FALSE,&m\u overlydc));
//使用GDI绘制DC
如果(!m_overlydc)//我们丢失了设备
抛出PE(ID、错误、无视频、硬件);
::SetBkColor(m_overlydc,m_effectConstants.m_keyColor);
::ExtTextOut(m_overlydc,0,0,ETO_不透明,overlyrect,nullptr,0,nullptr);
//完成绘图后,释放DC
dxgiSurface1->ReleaseDC(nullptr);
m_overlydc=nullptr;
编辑:我更改了D3D11_纹理2D_描述,如下所示:

    CD3D11_TEXTURE2D_DESC texDesc(DXGI_FORMAT_B8G8R8X8_UNORM
    , gsl::narrow_cast<UINT>(targetSize.width), gsl::narrow_cast<UINT>(targetSize.height), 1U, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);

ID3D11DevicePtr device = renderer->Device();
ID3D11Texture2DPtr  texture2D;
IF_FAILED_THROW_HR(device->CreateTexture2D(&texDesc, nullptr, &texture2D));

// get texture surface
IDXGISurface1Ptr dxgiSurface1 = texture2D;

IF_FAILED_THROW_HR(dxgiSurface1->GetDC(FALSE, &m_overlayDC));
//Draw on the DC using GDI
if (!m_overlayDC) // we have lost the device
    THROW_PE(IDS_ERR_NO_VIDEO_HARDWARE);
::SetBkColor(m_overlayDC, m_effectConstants.m_keyColor);
::ExtTextOut(m_overlayDC, 0, 0, ETO_OPAQUE, overlayRect, nullptr, 0, nullptr);
//When finish drawing release the DC
dxgiSurface1->ReleaseDC(nullptr);

m_overlayDC = nullptr;
CD3D11_TEXTURE2D_DESC texDesc(DXGI_格式_B8G8R8X8_UNORM
,gsl::窄投影(targetSize.width),gsl::窄投影(targetSize.height),1U,1,D3D11_绑定_着色器_资源| D3D11_绑定_渲染_目标);
ID3D11DevicePtr设备=渲染器->设备();
ID3D11Texture2DPtr texture2D;
如果失败,抛出(设备->创建纹理2D(&texDesc、nullptr和&texture2D));
//获取纹理表面
IDXGISurface1Ptr dxgiSurface1=纹理2d;
如果失败,则抛出(dxgiSurface1->GetDC(FALSE,&m\u overlydc));
//使用GDI绘制DC
如果(!m_overlydc)//我们丢失了设备
抛出PE(ID、错误、无视频、硬件);
::SetBkColor(m_overlydc,m_effectConstants.m_keyColor);
::ExtTextOut(m_overlydc,0,0,ETO_不透明,overlyrect,nullptr,0,nullptr);
//完成绘图后,释放DC
dxgiSurface1->ReleaseDC(nullptr);
m_overlydc=nullptr;
现在,GetDC()引发异常:应用程序进行了无效的调用。调用的参数或某些对象的状态不正确。 启用D3D调试层,以便通过调试消息查看详细信息。
HResult:0x887A0001,协作室:2170,代码:1

您选择的格式、用法和绑定标志组合与D3D11\u资源\u杂项\u GDI\u兼容不兼容

如果启用,您将获得调试输出,以通知您此限制。Direct3D调试设备是一种理想的方法,可以找出您为什么会获得
E_INVALIDARG

D3D11错误:ID3D11Device::CreateTexture2D:D3D11_RESOURCE_MISC_GDI_COMPATIBLE需要设置D3D11_BIND_RENDER_目标标志。[状态#创建错误#103:CREATETEXTURE2D#u INVALIDMISCFLAGS]

修复后,您将获得:

D3D11错误:ID3D11Device::CreateTexture2D:D3D11_资源_杂项_GDI_兼容要求D3D11_使用情况_默认值。[状态#创建错误#103:CREATETEXTURE2D_INVALIDMISCFLAGS]```

最后:

D3D11错误:ID3D11Device::CreateTexture2D:D3D11_资源_杂项_GDI_兼容需要B8G8R8A8格式。[状态#创建错误#103:CREATETEXTURE2D#u INVALIDMISCFLAGS]

综上所述,这是可行的:

D3D11_TEXTURE2D_DESC desc = {};
desc.Width = ...
desc.Height = ...
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;

Microsoft::WRL::ComPtr<ID3D11Texture2D> texture2D;
DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&desc, nullptr, &texture2D));
D3D11_TEXTURE2D_DESC DESC={};
描述宽度=。。。
描述高度=。。。
desc.ArraySize=1;
描述格式=DXGI格式\u B8G8R8A8\u UNORM;
描述用法=D3D11\u用法\u默认值;
desc.BindFlags=D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET;
desc.MipLevels=1;
desc.SampleDesc.Count=1;
desc.miscsflags=D3D11_资源_MISC_GDI_兼容;
微软::WRL::ComPtr texture2D;
DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&desc、nullptr和&texture2D));

当执行CreateTexture2D()和调试输出时,限制都在

哪一行有错误以及Direct3D调试输出是什么?如下所示:无效参数错误。HResult:0x80070057,协作室:7(WIN32),代码:87这是完全合乎逻辑的,因为您没有遵守上列出的D3D11\u资源\u杂项\u GDI\u兼容的限制。它必须有
D3D11\u BIND\u RENDER\u TARGET
和format
DXGI\u format\u B8G8R8A8\u UNORM