#include "pch.h" #include "SampleFpsTextRenderer.h" #include "Common/DirectXHelper.h" using namespace $ext_safeprojectname$; using namespace Microsoft::WRL; // 初始化用于渲染文本的 D2D 资源。 SampleFpsTextRenderer::SampleFpsTextRenderer(const std::shared_ptr& deviceResources) : m_text(L""), m_deviceResources(deviceResources) { ZeroMemory(&m_textMetrics, sizeof(DWRITE_TEXT_METRICS)); // 创建独立于设备的资源 ComPtr textFormat; DX::ThrowIfFailed( m_deviceResources->GetDWriteFactory()->CreateTextFormat( L"Segoe UI", nullptr, DWRITE_FONT_WEIGHT_LIGHT, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 32.0f, L"en-US", &textFormat ) ); DX::ThrowIfFailed( textFormat.As(&m_textFormat) ); DX::ThrowIfFailed( m_textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR) ); DX::ThrowIfFailed( m_deviceResources->GetD2DFactory()->CreateDrawingStateBlock(&m_stateBlock) ); CreateDeviceDependentResources(); } // 更新要显示的文本。 void SampleFpsTextRenderer::Update(DX::StepTimer const& timer) { // 更新显示文本。 uint32 fps = timer.GetFramesPerSecond(); m_text = (fps > 0) ? std::to_wstring(fps) + L" FPS" : L" - FPS"; ComPtr textLayout; DX::ThrowIfFailed( m_deviceResources->GetDWriteFactory()->CreateTextLayout( m_text.c_str(), (uint32) m_text.length(), m_textFormat.Get(), 240.0f, // 输入文本的最大宽度。 50.0f, // 输入文本的最大高度。 &textLayout ) ); DX::ThrowIfFailed( textLayout.As(&m_textLayout) ); DX::ThrowIfFailed( m_textLayout->GetMetrics(&m_textMetrics) ); } // 将帧呈现到屏幕。 void SampleFpsTextRenderer::Render() { ID2D1DeviceContext* context = m_deviceResources->GetD2DDeviceContext(); Windows::Foundation::Size logicalSize = m_deviceResources->GetLogicalSize(); context->SaveDrawingState(m_stateBlock.Get()); context->BeginDraw(); // 定位在右下角 D2D1::Matrix3x2F screenTranslation = D2D1::Matrix3x2F::Translation( logicalSize.Width - m_textMetrics.layoutWidth, logicalSize.Height - m_textMetrics.height ); context->SetTransform(screenTranslation * m_deviceResources->GetOrientationTransform2D()); DX::ThrowIfFailed( m_textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING) ); context->DrawTextLayout( D2D1::Point2F(0.f, 0.f), m_textLayout.Get(), m_whiteBrush.Get() ); // 此处忽略 D2DERR_RECREATE_TARGET。此错误指示该设备 // 丢失。将在下一次调用 Present 时对其进行处理。 HRESULT hr = context->EndDraw(); if (hr != D2DERR_RECREATE_TARGET) { DX::ThrowIfFailed(hr); } context->RestoreDrawingState(m_stateBlock.Get()); } void SampleFpsTextRenderer::CreateDeviceDependentResources() { DX::ThrowIfFailed( m_deviceResources->GetD2DDeviceContext()->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &m_whiteBrush) ); } void SampleFpsTextRenderer::ReleaseDeviceDependentResources() { m_whiteBrush.Reset(); }