I'm relatively new to D3D11 and I'm trying to take advantage of IDXGISurface1->GetDC to do some GDI drawing on the surface before Present. So far, I've been unsuccessful.
Can someone set me straight?
Looking at the docs for GDI compatible textures and some old posts here on gamedev, I think I'm meeting the requirements. However, when I call g_pSurface1->GetDC, I get an error:
DXGI ERROR: IDXGISurface1::GetDC: GetDC can only be called for textures that were created
with the D3D10_RESOURCE_MISC_GDI_COMPATIBLE flag. [ MISCELLANEOUS ERROR #89: ]
For one thing, I don't understand the reference to the D3D10 flag (?). My understanding is that CreateDeviceAndSwapChain automatically creates a texture for the backbuffer.
Here's the code I use to create the device/swapchain:
IDXGIFactory1 *pDXGIFactory;
HRESULT hResult = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pDXGIFactory);
if (FAILED(hResult)) {
MessageBox(NULL, DXGetErrorDescription(hResult), TEXT("CreateDXGIFactory1"), MB_OK);
return 0;
}
// Use the first adapter
IDXGIAdapter1 *pAdapter;
hResult = pDXGIFactory->EnumAdapters1(0, &pAdapter);
if (FAILED(hResult)) {
MessageBox(NULL, DXGetErrorDescription(hResult), "EnumAdapters1", MB_OK);
return 0;
}
pDXGIFactory->Release();
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(scd));
scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // BGR type specified in the docs
scd.SampleDesc.Count = 1;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.BufferCount = 1;
scd.OutputWindow = g_hWnd;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Windowed = TRUE;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
hResult = D3D11CreateDeviceAndSwapChain(
pAdapter,
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
D3D11_CREATE_DEVICE_DEBUG |
D3D11_CREATE_DEVICE_BGRA_SUPPORT |
D3D11_CREATE_DEVICE_SINGLETHREADED,
NULL,
0,
D3D11_SDK_VERSION,
&scd,
&g_pSwapChain,
&g_pd3dDevice,
NULL,
&g_pImmediateContext
);
I create the rendertargetview from the backbuffer texture:
// Create a render target view
ID3D11Texture2D* pBackBuffer = NULL;
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hr))
return hr;
hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))
{
MessageBox(NULL, DXGetErrorDescription(hr), "Failed to create render target view", MB_OK);
return hr;
}
Here's the render routine:
HDC hdc;
IDXGISurface1* g_pSurface1 = NULL;
HRESULT hr = g_pSwapChain->GetBuffer(0, __uuidof(IDXGISurface1), (void**)&g_pSurface1);
if (SUCCEEDED(hr))
{
hr = g_pSurface1->GetDC(FALSE, &hdc); // <------------- Error occurs here -----------
if (SUCCEEDED(hr))
{
TextOut(hdc, 5, 5, "Hello", 5);
g_pSurface1->ReleaseDC(NULL);
}
SafeRelease(g_pSurface1);
}
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);
Thanks for any help.
EDIT: Just to clarify, if I comment out the render routine above, the app works fines (but without the TextOut, of course).