6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DirectXTKのMakeSpriteFontの問題と解決策

Last updated at Posted at 2018-10-10

#DirectXTKのMakeSpriteFontの問題と解決策

##はじめに
DirectX11からDirectX9に存在したD3DXライブラリが標準搭載されなくなった。そのせいで、便利なクラスが使えなくなった。Font表示も同様、使えなくなった。一応、D3DXライブラリのDX11版は存在するものの、ライブラリを個別にインストール・使用しなければならない(参考:DirectX 補助ライブラリ - Wikipedia)。

Font表示処理を独自に実装することは可能だが、こういう汎用的な処理はフリーウェアとして存在するのが望ましい。そこで登場するのが「DirectX Tool Kit=DirectXTK」である。

DirectXTKとは?

DirectXTKは、C++ で作られている。February 24, 2012に最初のリリースが行われた。DirectXTKが提供する機能は、Oct 10, 2018の時点で以下の通り(参考:DirectXTK)。

ヘッダ名 内容
Audio.h XAudio2を使用した低レベルのオーディオAPI(Audioパブリックヘッダ用のDirectXTK)
CommonStates.h 一般的に使用されるD3Dステートオブジェクトを提供するファクトリ
DDSTextureLoader.h 軽量なDDSファイルテクスチャローダー
DirectXHelpers.h D3Dプログラミングのための色々な C++ヘルパー
Effects.h 一般的なレンダリングタスク用の組み込みシェーダのセット
GamePad.h XInputを使用したゲームパッドコントローラヘルパー
GeometricPrimitive.h キューブや球などの基本図形を描画します。
GraphicsMemory.h 動的グラフィックスのメモリ割り当てを管理するヘルパー
Keyboard.h キーボードステートトラッキングヘルパー
Model.h .CMO、.SDKMESH、または.VBOファイルから読み込まれたメッシュの描画
Mouse.h マウスヘルパー
PostProcess.h 一般的なプリプロセス処理用の組み込みシェーダのセット
PrimitiveBatch.h ユーザプリミティブを簡単かつ効率的に描画する方法
ScreenGrab.h 軽量なスクリーンショットセーバー
SimpleMath.h DirectXMathの簡略化された C++ ラッパー
SpriteBatch.h シンプルで効率的な2Dスプライトレンダリング
SpriteFont.h ビットマップベースのテキストレンダリング
VertexTypes.h 一般的に使用される頂点データフォーマットの構造
WICTextureLoader.h WICベースのイメージファイルテクスチャローダー
XboxDDSTextureLoader.h Xbox OneのDDSTextureLoader専用アプリケーション

今回はFontを描画したいので SpriteFont.h の SpriteFontクラスを使う。このSpriteFontクラスは、「spritefontデータ」を作成しておく必要がある。このデータには、テクスチャ・テクスチャ情報・フォント描画に必要な情報が含まれている。このデータを作成するのがDirectXTKに含まれている「MakeSpriteFont.exe」だ。以下はそのフォルダ構造である。

Picture 2018-10-10 18_02_03.png

MakeSpriteFontフォルダに MakeSpritFont.exe がある。
Picture 2018-10-10 18_03_34.png

##MakeSpriteFontの問題点

MakeSpriteFont.exeは「使用するフォントの文字を切り出して、テクスチャファイルと付属情報を生成し、「spritefontデータ」にするツールだ。使用する文字の数が多ければ、それだけ変換に時間を要す。加えてそのアルゴリズムが問題で、テクスチャ画像の空き領域を1ピクセル単位で探しているらしい。漢字がだいたい2万文字あるので、変換に多大な時間が必要になる。ちなみに、私の環境では12時間経っても終わらなかった( Intel Core2Quad 2.85 GHz)。

##MakeSpriteFontの解決策
既にこの問題について解決策を提示し、記事にしてくれてる方がいた。ZeroGramさんのDirectXTKでフォント表示、日本語対応(2013/4/29)である。記事の日付が2013/4/29なのでとても古い。ここで書かれている内容が現在(Oct 10, 2018)でも通用するのかを検証してみた。

**結果からいうと上手くいった。**その御蔭で「spritefontデータ」の作成が約1分で完了した。大幅な時間改善である。

以下にその手順を記す。

  1. ZeroGramさんのサンプルプログラム MakeSpriteFontModify.zip をダウンロードする。
  2. zipを展開すると、modifyフォルダに2つのファイルがある(GlyphPacker.cs, TrueTypeImporter.cs)。
  3. DirectXTK/MakeSpriteFontフォルダに、TrueTypeImporter.cs をコピーする。
  4. DirectXTK/MakeSpriteFontフォルダの、GlyphPacker.cs をテキストエディタで開く。
  5. ZeroGramさんの GlyphPacker.csのArrangeGlyphs関数を探して、関数ごとコピーする。MakeSpriteFontフォルダGlyphPacker.cs の ArrangeGlyphs関数と差し替える
  6. ZeroGramさんのGlyphPacker.csからPositionGlyph関数を探し、関数ごとコピーする。MakeSpriteFontフォルダGlyphPacker.cs の ArrangeGlyphs関数の後に「貼り付け」る
  7. DirectXTK/MakeSpriteFontフォルダの MakeSpriteFont.csproj をVisualStudio2015 で開き、ビルドする。

##MakeSpriteFontの解決策の結果
以下のコマンドを実行すると、約2万5千字もの漢字変換が行われる。所要時間は約1分。オリジナルよりも変換時間が短縮され、データも問題なく変換された。実際に表示させた所、問題なく表示された。

MakeSpriteFont.exe "MS ゴシック" myfile.spritefont /FontSize:12 /CharacterRegion:32-126 /CharacterRegion:0x3000-0x30ff /CharacterRegion:0xff00-0xffef /CharacterRegion:0x4e00-0x9fff  /CharacterRegion:0x2000-0x2fff

MakeSpriteFont.exeに渡すCharacterRegionオプションの意味は以下の通り。

説明 オプション
アスキー文字 /CharacterRegion:32-126
ひらがなカタカナ /CharacterRegion:0x3000-0x30ff
記号 /CharacterRegion:0xff01-0xffe5
全角漢字 /CharacterRegion:0x4e00-0x9fff
全角特殊記号 /CharacterRegion:0x2000-0x2fff

【コマンドプロンプトで実行した結果】は以下の通り。
Picture 2018-10-10 18_42_09.png

【DirectX11でSpriteFontクラスを使って表示させてみた結果】は以下の通り。
Picture 2018-10-10 18_46_53.png

##まとめ
ZeroGramさんのサイトにある解決法で、問題は解決した。ただし、差し替え対象の2つのファイルをまるごとコピーすることはできず、ファイルの一部を直接編集しなければならなかった。GitHubに公開されている MakeSpriteFont.exe は、常に更新されているせいで、2018年現在だと今回のような対応が必要になった。

ZeroGramさん、ありがとうございました。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?