DirectX11、FreeType2、インスタンシング、アトラステクスチャを使用して超高速文字描画をする

【はじめに】

最近趣味で DirectX11 に触れていて、前々からやろうと思っていたことがありました。
それが今回やってみた文字(テキスト)描画です。
文字描画について色々調べてみると
・FreeType2、WindowsAPI、stb_freetype などで文字をビットマップ化
・ビットマップ化した文字をテクスチャにして四角形のポリゴンに貼り付ける
・テクスチャを文字ごとに作るのは DrawCall の増える原因になるので普通は 1 枚のテクスチャ(アトラステクスチャ)にまとめる
→ 同じテクスチャを貼り付けるが、UV を変更して文字ごとに合わせる
・文字一枚一枚を Draw していては CPU コストが多くかかるのでインスタンシングで描画すると高速化できる
などなど・・・

ということで実際に全部やってみようと思ってやってみました!

【実際にやってみた】

参考サイト
その5 高速フォント表示 その 67 改・高速フォント文字 その 69 インスタンシングでモデルを大量発生! FreeType でテキスト描画 FreeType を使った OpenGL でのテキスト描画

勉強した順序としては、

FreeType2 を使用して文字をラスタライズできるか確認する(コンソール画面)
DirectX11+WindowsAPI で板ポリゴンを何枚も表示できるようにする

板ポリゴンにテクスチャを貼る(スプライト化)

使用するテクスチャを文字をラスタライズしたものにする

アトラステクスチャにラスタライズしていない文字を書き込むようにする

文字列を読み込んで、文字のスプライトを複数枚出せるようにする

ベースラインに表示座標を合わせる

インスタンシングで文字を描画できるようにシェーダなどを変更

色付けや複数のフォントで文字表示できるように改良

と言った形です。

結果は地味ですが、意外とやることが多い(泣)
一つ一つ丁寧にステップアップしていく形が一番の近道だと思います!

なんだかんだで1週間ほどコツコツ時間を見つけてプログラミングして完成させることができました!

image

真ん中にアトラステクスチャを描画しています。細々と規則正しく並んでいるのが確認できると思います。
Bitmap Font Creater などのように隙間なく文字を詰め込むことができれば、もっとメモリを効率的に使用できると思います。

【最後に】

Unity などでは簡単に 2D テキストなどを表示できますが、実際の裏側では意外と面倒くさいことをやっているのだと体感できるので物好きにはおすすめです!
これを改良するのであれば、文字の大きさが等幅ではないものを隙間なく詰め込んで使用できるようにするともっと効率的で実用的になるのかなと思いました!