がりらぼ

WindowsRuntimeの応援ブログ

DirectXによるWindowsストアアプリゲーム開発入門vol.2 テキストを描画する

今回はテキストを描画します。
プロジェクトファイルを落としてください。
garicchi/DirectXSample · GitHub

TestDirectX_2_Textディレクトリ内のソリューションファイルを開いて実行してください。

今回の実行結果は、真っ青な画面に「I’m Love in it」と表示されます。

f:id:garicchi:20131219111905p:plain

Renderer.hを見てみましょう

wstring m_text;

//テキストを描画するためのリソース
ComPtr<ID2D1SolidColorBrush>  m_textBrush;	//ブラシ
ComPtr<IDWriteTextLayout> m_textLayout;		//テキストレイアウト
ComPtr<IDWriteTextFormat> m_textFormat;		//テキストフォーマット

wstring型のm_textがあります。この中には描画したいテキストが入ります。stringとwstringの違いは、ワイド文字であるかないかの違いです。
テキストを描画するには、テキストの色などを定義するブラシのID21SolidColorBrush、テキストのレイアウトを定義するIDWriteTextLayout、テキストのフォーマットを定義するIDWriteTextFormatの3つが必要となります。

RendererBase.cppを見てみましょう。
コンストラクタではm_textに表示したい文字列を代入しています。

//レンダラークラスのコンストラクタ 変数の初期化やリソースの確保などをします
RendererBase::RendererBase(const std::shared_ptr<DeviceResources>& deviceResources) :
m_deviceResources(deviceResources)
{
	m_text=L"I'm Love in it.";

	//リソース確保
	CreateDeviceDependentResources();
}

文字列前に「L」とついているのはこれがワイド文字列であることを表します。

CreateDeviceDependentResourcesメソッドでは、DeviceContextから、CreateSolidColorBrushメソッドで色とともにID2D1SolidColorBrushを生成します。
その後、IDWriteFactory2インターフェースのCreateTextFormatメソッドでテキストフォーマットを定義します。
今回はフォントが「Segoe UI」でフォーマットを定義します。

//リソースを確保するメソッドです コンストラクタからだけでなく、Mainクラスからも呼ばれます
void RendererBase::CreateDeviceDependentResources()
{
	//テキスト使用するブラシを確保します
	m_deviceResources->GetD2DDeviceContext()->CreateSolidColorBrush(ColorF(ColorF::White), &m_textBrush);

	//テキストに使用するフォーマットを確保します
	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",
		&m_textFormat
		);

}

Updateメソッドです。

//更新処理です 定期的に呼ばれるので変数の制御などはここでおこないます
void RendererBase::Update(DX::StepTimer const& timer)
{
	m_deviceResources->GetDWriteFactory()->CreateTextLayout(
		m_text.c_str(),
		(uint32) m_text.length(),
		m_textFormat.Get(),
		240.0f, // 入力テキストの最大幅。
		50.0f, // 入力テキストの最大高さ。
		&m_textLayout
		
		);
}

CreateTextLayoutを更新処理部におくのはパフォーマンス上もんだいがあるのではないかと思いますが、途中でテキストの内容が変更される可能性も考慮して、Updateメソッド内に置きました。
IDWriteFactory2インターフェースの、CreateTextLayoutメソッドでテキスト、テキストフォーマットから、テキストレイアウトを生成します。

Renderメソッドです。

// フレームを画面に描画します。
void RendererBase::Render()
{
	//デバイスコンテキストの確保
	ID2D1DeviceContext* context = m_deviceResources->GetD2DDeviceContext();
	
	context->BeginDraw(); //描画開始

	context->DrawTextLayout(Point2F(100.0f,100.0f),
		m_textLayout.Get(),m_textBrush.Get());

	
	context->EndDraw();	//描画終了
	
}

ID2D1DeviceContextインターフェースのDrawTextLayoutでテキストを描画します。

DirextXは高い自由度を実現するために、テキストを描画するだけでも多くの命令を呼び出す必要があります。
次回はこれらの処理をまとめて、もう少し簡易にテキストを表示できるようにしましょう。