Add directwrite to example.
This commit is contained in:
parent
92d1f24613
commit
d1ec8b4f68
5 changed files with 235 additions and 21 deletions
|
@ -10,6 +10,13 @@
|
|||
#include <d3dcompiler.h>
|
||||
#include <d3d12sdklayers.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d3d11on12.h>
|
||||
#include <d2d1_3.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
#include <dwrite.h>
|
||||
|
||||
Win32DxWindowInterface::Win32DxWindowInterface(Win32DxInterface* dxInterface)
|
||||
: mDxInterface(dxInterface)
|
||||
{
|
||||
|
@ -35,7 +42,9 @@ void Win32DxWindowInterface::onRender()
|
|||
|
||||
// Execute the command list.
|
||||
ID3D12CommandList* ppCommandLists[] = { mCommandList.Get() };
|
||||
mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
|
||||
mDxInterface->getCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
|
||||
|
||||
renderD2d();
|
||||
|
||||
// Present the frame.
|
||||
mSwapChain->Present(1, 0);
|
||||
|
@ -75,8 +84,8 @@ void Win32DxWindowInterface::populateCommandList()
|
|||
mCommandList->DrawInstanced(3, 1, 0, 0);
|
||||
|
||||
// Indicate that the back buffer will now be used to present.
|
||||
barrier = CD3DX12_RESOURCE_BARRIER::Transition(mRenderTargets[mFrameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||
mCommandList->ResourceBarrier(1, &barrier);
|
||||
//barrier = CD3DX12_RESOURCE_BARRIER::Transition(mRenderTargets[mFrameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||
//mCommandList->ResourceBarrier(1, &barrier);
|
||||
|
||||
mCommandList->Close();
|
||||
}
|
||||
|
@ -102,12 +111,6 @@ bool Win32DxWindowInterface::initialize(mt::Window* window)
|
|||
|
||||
void Win32DxWindowInterface::loadPipeline(mt::Window* window)
|
||||
{
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
mDxInterface->getDevice()->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue));
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
|
||||
swapChainDesc.BufferCount = FrameCount;
|
||||
|
||||
|
@ -125,7 +128,7 @@ void Win32DxWindowInterface::loadPipeline(mt::Window* window)
|
|||
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain;
|
||||
mDxInterface->getFactory()->CreateSwapChainForHwnd(
|
||||
mCommandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it.
|
||||
mDxInterface->getCommandQueue(),
|
||||
hwnd,
|
||||
&swapChainDesc,
|
||||
nullptr,
|
||||
|
@ -136,6 +139,19 @@ void Win32DxWindowInterface::loadPipeline(mt::Window* window)
|
|||
swapChain.As(&mSwapChain);
|
||||
auto mFrameIndex = mSwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
// Query the desktop's dpi settings, which will be used to create
|
||||
// D2D's render targets.
|
||||
float dpiX{ 0.0 };
|
||||
float dpiY{ 0.0 };
|
||||
mDxInterface->getD2dFactory()->GetDesktopDpi(&dpiX, &dpiY);
|
||||
|
||||
D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(
|
||||
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
dpiX,
|
||||
dpiY
|
||||
);
|
||||
|
||||
// Create descriptor heaps.
|
||||
{
|
||||
// Describe and create a render target view (RTV) descriptor heap.
|
||||
|
@ -157,6 +173,25 @@ void Win32DxWindowInterface::loadPipeline(mt::Window* window)
|
|||
{
|
||||
mSwapChain->GetBuffer(n, IID_PPV_ARGS(&mRenderTargets[n]));
|
||||
mDxInterface->getDevice()->CreateRenderTargetView(mRenderTargets[n].Get(), nullptr, rtvHandle);
|
||||
|
||||
D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET };
|
||||
mDxInterface->get11On12Device()->CreateWrappedResource(
|
||||
mRenderTargets[n].Get(),
|
||||
&d3d11Flags,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PRESENT,
|
||||
IID_PPV_ARGS(&mWrappedBackBuffers[n])
|
||||
);
|
||||
|
||||
// Create a render target for D2D to draw directly to this back buffer.
|
||||
Microsoft::WRL::ComPtr<IDXGISurface> surface;
|
||||
mWrappedBackBuffers[n].As(&surface);
|
||||
mDxInterface->getD2dContext()->CreateBitmapFromDxgiSurface(
|
||||
surface.Get(),
|
||||
&bitmapProperties,
|
||||
&mD2dRenderTargets[n]
|
||||
);
|
||||
|
||||
rtvHandle.Offset(1, mRtvDescriptorSize);
|
||||
}
|
||||
}
|
||||
|
@ -223,6 +258,24 @@ void Win32DxWindowInterface::loadAssets()
|
|||
// Create the command list.
|
||||
mDxInterface->getDevice()->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), mPipelineState.Get(), IID_PPV_ARGS(&mCommandList));
|
||||
|
||||
// Create D2D/DWrite objects for rendering text.
|
||||
{
|
||||
mDxInterface->getD2dContext()->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush);
|
||||
mDxInterface->getDirectWriteFactory()->CreateTextFormat(
|
||||
L"Verdana",
|
||||
NULL,
|
||||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
50,
|
||||
L"en-us",
|
||||
&mTextFormat
|
||||
);
|
||||
mTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
|
||||
mTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
|
||||
}
|
||||
|
||||
|
||||
// Command lists are created in the recording state, but there is nothing
|
||||
// to record yet. The main loop expects it to be closed, so close it now.
|
||||
mCommandList->Close();
|
||||
|
@ -286,11 +339,42 @@ void Win32DxWindowInterface::loadAssets()
|
|||
}
|
||||
}
|
||||
|
||||
void Win32DxWindowInterface::renderD2d()
|
||||
{
|
||||
D2D1_SIZE_F rtSize = mD2dRenderTargets[mFrameIndex]->GetSize();
|
||||
D2D1_RECT_F textRect = D2D1::RectF(0, 0, rtSize.width, rtSize.height);
|
||||
static const WCHAR text[] = L"11On12";
|
||||
|
||||
// Acquire our wrapped render target resource for the current back buffer.
|
||||
mDxInterface->get11On12Device()->AcquireWrappedResources(mWrappedBackBuffers[mFrameIndex].GetAddressOf(), 1);
|
||||
|
||||
// Render text directly to the back buffer.
|
||||
mDxInterface->getD2dContext()->SetTarget(mD2dRenderTargets[mFrameIndex].Get());
|
||||
mDxInterface->getD2dContext()->BeginDraw();
|
||||
mDxInterface->getD2dContext()->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
mDxInterface->getD2dContext()->DrawText(
|
||||
text,
|
||||
_countof(text) - 1,
|
||||
mTextFormat.Get(),
|
||||
&textRect,
|
||||
mTextBrush.Get()
|
||||
);
|
||||
mDxInterface->getD2dContext()->EndDraw();
|
||||
|
||||
// Release our wrapped render target resource. Releasing
|
||||
// transitions the back buffer resource to the state specified
|
||||
// as the OutState when the wrapped resource was created.
|
||||
mDxInterface->get11On12Device()->ReleaseWrappedResources(mWrappedBackBuffers[mFrameIndex].GetAddressOf(), 1);
|
||||
|
||||
// Flush to submit the 11 command list to the shared command queue.
|
||||
mDxInterface->getD3d11DeviceContext()->Flush();
|
||||
}
|
||||
|
||||
void Win32DxWindowInterface::waitForPreviousFrame()
|
||||
{
|
||||
// Signal and increment the fence value.
|
||||
const UINT64 fence = mFenceValue;
|
||||
mCommandQueue->Signal(mFence.Get(), fence);
|
||||
mDxInterface->getCommandQueue()->Signal(mFence.Get(), fence);
|
||||
mFenceValue++;
|
||||
|
||||
// Wait until the previous frame is finished.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue