Получить GDI DC от ID3D11Texture2D для рисования - PullRequest
0 голосов
/ 28 января 2019

У меня есть реализация в 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, как показано ниже:

    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;

Теперь исключение выдается из GetDC (): приложение совершило недопустимый вызов.Либо параметры вызова, либо состояние какого-либо объекта были неверными.Включите уровень отладки D3D, чтобы увидеть подробности в сообщениях отладки.HResult: 0x887A0001, объект: 2170, код: 1

1 Ответ

0 голосов
/ 30 января 2019

Комбинация выбранных вами флагов формата, использования и привязки несовместима с D3D11_RESOURCE_MISC_GDI_COMPATIBLE.

Если вы включите Direct3D Debug Device , вы получите выходные данные отладкисообщить вам об этом ограничении.Отладочное устройство Direct3D - это идеальный способ выяснить, почему вы получаете E_INVALIDARG.

D3D11 ОШИБКА: ID3D11Device :: CreateTexture2D: D3D11_RESOURCE_MISC_GDI_COMPATIBLE требует, чтобы флаг D3D11_BINDRGDET установлен.[STATE_CREATION ERROR # 103: CREATETEXTURE2D_INVALIDMISCFLAGS]

Затем, исправив это, вы получите:

D3D11 ОШИБКА: ID3D11Device :: CreateTexture2D: D3D_DD_D_D_D_D_D_D_D_D_D_D_D_D_T_T_T_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_д_дд.Да_дл.[STATE_CREATION ERROR # 103: CREATETEXTURE2D_INVALIDMISCFLAGS] ``.

И, наконец:

D3D11 ОШИБКА: ID3D11Device :: CreateTexture2D: D3D11_RES_RES_RES_RES_RES_RES_RES_RES_RES_RES_RES_RISG_RG[STATE_CREATION ERROR # 103: CREATETEXTURE2D_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));

Все ограничения прописаны в Документах Microsoft

...