Actually, if you are on Windows 8 it was possible before the update. The update (http://support.microsoft.com/kb/2670838) was only for allowing it to work on Windows 7 as well.
Here is a sample for D3D-D2D interop on Windows 8. I didn't get a chance to look at it, but it might be useful.
http://code.msdn.microsoft.com/windowsapps/Direct2D-Direct3D-Interop-ee641e46
Also, here's a quick example I threw together, using D2D to draw text to the backbuffer. It should also be possible to create a texture in D3D11, and then write to it with D2D. (I think you would use QueryInterface to get the IDXGISurface1 pointer from the texture, and then pass that to CreateDxgiSurfaceRenderTarget, but I'm not sure)
#include <Windows.h>
#include <d3d11.h>
#include <d2d1_1.h>
#include <dwrite_1.h>
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dwrite.lib")
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_CLOSE)
{
PostQuitMessage(0);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// create the window
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = hInstance;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = "Vector";
ATOM a = RegisterClassEx(&wcex);
RECT r = {0, 0, 800, 600};
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
HWND hWnd = CreateWindow(
(LPCSTR)a,
"Vector",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
r.right - r.left,
r.bottom - r.top,
NULL,
NULL,
hInstance,
NULL);
// create the D3D device and swap chain
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC swapChainDesc = { };
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = 800;
swapChainDesc.BufferDesc.Height = 600;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = true;
IDXGISwapChain *swapChain;
ID3D11Device *device;
ID3D11DeviceContext *context;
HRESULT hr = D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
&level,
1,
D3D11_SDK_VERSION,
&swapChainDesc,
&swapChain,
&device,
NULL,
&context);
// set up the D3D render target view to the back buffer
ID3D11Texture2D *backBuffer;
ID3D11RenderTargetView *backBufferView;
swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
device->CreateRenderTargetView(backBuffer, NULL, &backBufferView);
context->OMSetRenderTargets(1, &backBufferView, NULL);
// create the D2D factory
ID2D1Factory *factory;
D2D1_FACTORY_OPTIONS options;
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, &factory);
// set up the D2D render target using the back buffer
IDXGISurface *dxgiBackbuffer;
swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackbuffer));
ID2D1RenderTarget *d2dRenderTarget;
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED));
factory->CreateDxgiSurfaceRenderTarget(dxgiBackbuffer, props, &d2dRenderTarget);
dxgiBackbuffer->Release();
// create the DWrite factory
IDWriteFactory1 *writeFactory;
DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(writeFactory), (IUnknown**)(&writeFactory));
// create the DRwite text format
IDWriteTextFormat *textFormat;
writeFactory->CreateTextFormat(
L"Arial",
NULL,
DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
50,
L"",
&textFormat);
// create a brush
ID2D1SolidColorBrush *whiteBrush;
d2dRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &whiteBrush);
// draw the text
d2dRenderTarget->BeginDraw();
const WCHAR *text = L"Hello World";
d2dRenderTarget->DrawTextA(text, wcslen(text), textFormat, D2D1::RectF(0, 0, 800, 600), whiteBrush);
d2dRenderTarget->EndDraw();
ShowWindow(hWnd, true);
MSG msg = {0};
while (WM_QUIT != msg.message)
{
if (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
swapChain->Present(0, 0);
}
}
}