3Dのワールド空間で表示します。
2Dのワールド空間でも表示できます。
テキスト枠に使用した画像です。ペイントで15分ぐらいで作成しました。
これをDDSファイルに変換し使用します。
今回は テキストの描画になります。
テキストを描画する機能は既に実装しておりましたが、
ASCII(アスキー)コードを使用する仕様だった為、
英語しか使用出来ず、ひらがなや漢字は使えませんでした。
今回実装するにあたり、ひらがなや漢字も使用できるようにします。
元になるライブラリをどうするか探したところ、
DirectXTKのSpriteFontが良さそうだったので
これで行くことにしました。
(理由としてはC++であること、とてもシンプルな仕様だったことです)
DirectXTKは古いライブラリである為か、問題が結構出ました。
その内容を以下に列挙します。
1、MakeSpriteFont
DirectXTKのSpriteFontでテキストを表示する場合、
別途spritefontビットマップファイルという文字情報が必要になります。
これはDirectXTKに含まれるMakeSpriteFont.exeで作成出来ますが
ひとつ問題があるとのことです。
Googleで検索すると多くサイトで出てきますが、
どうもファイルの作成に多くの時間がかかり
12時間使っても完成しないとのこと。
この修正にはカスタマイズしたMakeSpriteFont.exeを使うようですが
このファイルを配布していた方は現在作業を停止しており、
ファイルを得ることは出来ないようです。
詰んだかと思いましたが、実際に処理に時間がかかるのか確認したところ
問題無く普通に終了出来ました。
どうやら、以前に修正がされていたようです。
ただしポイントとして、/FastPackコマンドラインオプションを使う必要があるようです。
// 使用例
./MakeSpriteFont.exe "MS ゴシック" myfile.spritefont /FontSize:12 /FastPack /CharacterRegion:32-126 /CharacterRegion:0x3000-0x30ff /CharacterRegion:0xff01-0xffe5 /CharacterRegion:0x4e00-0x9fff
2、LNK2019: 未解決の外部シンボル
SpriteFontの動作確認を行なう為、仮のプロジェクトを組んだところ
上記エラーが発生しビルドに失敗するというもの。
原因としては、DirectXTKの関数の呼び出し規則(__fastcallなど)は、
XM_CALLCONVで管理されています。
XM_CALLCONVは、VisualStudioの”拡張命令セットを有効にする”オプションで変更出来ます。
これの値がDirectXTKとプロジェクトで一致していなかった為、
LNK2019: 未解決の外部シンボルが発生していました。
3、DirectX::BasicEffect
DirectX::BasicEffectクラスを使用する場合、
以下のファイルをインクルードする必要がありますが
これをそのまま行うとエラーになりました。
#include <Effects.h>
WindowsSDKの同名のヘッダファイルがあり、
そっちを参照する為のようです。
設定を変更するのも良いですが、
フルパスで書いた方が楽なのでそうしました。
#include <C:\Development Environments\DirectXTK\Inc\Effects.h> // フルパスで記入する。
4、DirectX::PrimitiveBatch
PrimitiveBatchクラスは
#include <VertexTypes.h> も必要です。
基本的にDirectXTKは、以前のXNA版の情報と混ざって
情報が公開されているようで、細かいところが少しづつ
違っているように見えます。
それを踏まえて情報収集する必要がありました。
以下は、テキストとテキスト枠を表示する例になります。
表示形式は、3Dのワールド空間と2Dのワールド空間を選択出来ます。
// テキストの表示テスト
HOUZMETHOD_VD sprite_font_effect_t::text_out_test(const ID3D11DeviceContextPtr& device_context)
{
try
{
// テストの為にテキストとテキスト枠を表示させます。
HRESULT hr = S_OK;
// d3ddeviceポインタが必要な場合、コメントアウトして使ってください。
// (今のところ必要はありません。)
//ID3D11DevicePtr d3ddevice;
//device_context->GetDevice(&d3ddevice);
// InputLayoutでワーニングが出る場合、コメントアウトしてください。
// (今のところ他のところでその処理が入っている為、必要はありません。)
//if( m_input_layout)
// device_context->IASetInputLayout(m_input_layout);
// フォントの表示方式を3Dまたは2Dに切り替えます。
DirectX::XMMATRIX world_view_proj;
DirectX::XMFLOAT2 batch_position, font_position;
float_t batch_scale, font_scale;
extern bool gui_b_directxtk_font_world_on_3d;
if( gui_b_directxtk_font_world_on_3d)
{ // 3D World
DirectX::XMMATRIX world = DirectX::XMMatrixScaling( 1, -1, 1); // World座標はY座標が逆になっている為修正します。
world_view_proj = world * m_view * m_proj; // View行列と射影行列は普段使用しているものを流用します。(この例ではTranspose()による転置が必要でした。
// 入力している値はどれも適当です。
batch_position = { -3, -5};
font_position = { -3 + 8 * 0.01, -5 + 8 * 0.01};
batch_scale = 0.01;
font_scale = 0.01;
m_p_SpriteBatch->SetRotation( DXGI_MODE_ROTATION_UNSPECIFIED); // これで行列が適用されます。
}
else
{ // 2D World
world_view_proj = DirectX::XMMatrixIdentity();
// 入力している値はどれも適当です。
batch_position = { 32,180};
font_position = { 32 + 16,180 + 16};
batch_scale = 1.0;
font_scale = 1.0;
m_p_SpriteBatch->SetRotation( DXGI_MODE_ROTATION_IDENTITY); // これで行列が適用されなくなります。
}
// Begin()関数により、描画の開始を行います。
m_p_SpriteBatch->SpriteBatch::Begin(
DirectX::SpriteSortMode_Deferred,
nullptr,
nullptr,
nullptr,
m_p_rasterizer_state,
nullptr,
world_view_proj); // world_view_proj行列はここで渡します。
// SpriteBatchによりテキスト枠を描画します。
m_p_SpriteBatch->Draw(
m_p_srv_diffuse_map, //_In_ ID3D11ShaderResourceView* texture,
batch_position, // XMFLOAT2 const& position,
nullptr, // _In_opt_ RECT const* sourceRectangle,
DirectX::Colors::White, // FXMVECTOR color = Colors::White,
0, // float rotation = 0,
DirectX::XMFLOAT2( 0, 0), // XMFLOAT2 const& origin = Float2Zero,
batch_scale, // float scale = 1,
DirectX::SpriteEffects_None,// SpriteEffects effects = SpriteEffects_None,
0.0 // float layerDepth = 0
);
// 表示するテキストを作成します。
// テキストの内容は適当に、1文字づつ表示させます。
tstring_t str1 = _T("念願の アイスソードを\n手にいれたぞ!");
const size_t str1_size = str1.size();
static int_t s_int = str1_size;
str1.erase( str1_size - s_int);
s_int = s_int > 0 ? s_int - 1 : str1_size;
// SpriteFontによりテキストを描画します。
m_p_SpriteFont->DrawString(
m_p_SpriteBatch.get(),
str1.c_str(),
font_position, // XMFLOAT2 const& position,
DirectX::Colors::Black, // FXMVECTOR color = Colors::White,
0, // float rotation = 0,
DirectX::XMFLOAT2( 0, 0), // XMFLOAT2 const& origin = Float2Zero,
font_scale, // float scale = 1,
DirectX::SpriteEffects_None,// SpriteEffects effects = SpriteEffects_None,
0.0 // float layerDepth = 0
);
// End()関数により、描画の終了を行います。
m_p_SpriteBatch->End();
}
catch( const general_exception&)
{
throw; }
}
次回も引き続きSpriteFontを行う予定です。