DirectX9.0備忘録(日本語描画編)

DirectX9.0環境で日本語の描画の実装について。

その67 改・高速フォント文字
http://marupeke296.com/DXG_No67_NewFont.html


その67 改・高速フォント描画:サンプルプログラム
http://marupeke296.com/DXGSmp_No67_NewFont.html


フォントを用いた描画に関しては、既にこちらのサイトにしっかり書かれているので、
ここでは「このサイトを使って、自分のゲーム用のライブラリにどう起こしたか」を中心にメモしておきます。

作業の予定

いきなりクラス化するのは考える事が多すぎるので、とりあえずサンプルをコピーし、フォント描画の部分だけ取り出す。

フォント描画の部分を切ったり貼ったりして、自由な文字列を描画できる関数を作ってみる。

描画関数の引数などから、クラス設計を考える。

実際のゲームプロジェクトで、設計を元にクラス化する。


実作業ログ

サンプル用の新規プロジェクト作成。DirectX用のディレクトリ設定を毎回やるのは面倒なので「DXSandBox」と命名し、今後はこのプロジェクトでDirectX関係のサンプルを動かしたいと思う。

サンプルをコピペして、動作確認。特に問題はなかった。

サンプルは1文字の描画なので、どうすれば2文字以上描画出来るか調べる。

とりあえず描画に必要な情報を構造体にまとめてみる。

文字コードから、その構造体に描画情報をセットする関数を作る。

構造体で複数文字対応

DX文字列1

生成した文字画像とその設定を保持するFontCharacterクラス、
フォントの設定と、そのフォントで生成したFontCharacterを保持するFontクラスを作り、
FontクラスのDraw関数を呼ぶと文字列が描画されるようにした。

Font MSGothic;
MSGothic.Init( "MS ゴシック", 26, FW_BOLD );

MSGothic.Draw( X, Y, "テキスト" );


FontCharacterは、文字コードをキーにして、std::mapで管理。添字アクセス出来ないけど、検索速いからヘーキヘーキ!

DX文字列2


とりあえず文字列は描画できました。

あとは、色を変えたり、枠線つけたり、文字送りとか実装できたら完璧。


・悩んだ所

!どう関数を分けるか

各種処理の繋がりが分からないので、関数の分け方が悩ましい。

この場合は処理の分け方を考えるより、作りたい関数を決めて、その関数に合わせて処理を分けることで作業が、スムーズになった。

ただ正しい処理の順番にならないことがあるかもしれないので、その時はリファクタリングが必要になるかも。

!フォントテクスチャの管理方法

とりあえず、同じ文字の生成はしたくないので、std::mapを使って、文字コードをキーにして、テクスチャを持っているFontCharacterオブジェクトを保持しました。

std::map< UINT, FontCharacter * > m_FontCharacters;

void Font::CreateCharacter( HDC hDc, UINT nChara ) //文字作成
{
// ----- 文字追加 -----
std::map< UINT, FontCharacter * >::_Pairib p = m_FontCharacters.insert( std::map< UINT, FontCharacter * >::value_type( nChara, (FontCharacter*)NULL ) );
if( p.second )
{ //新しい文字を作る
p.first->second = new FontCharacter( hDc, nChara ); //生成
}
}


FontCharacter *Font::GetFontCharacter( UINT nChara ) //文字取得
{
std::map< UINT, FontCharacter * >::iterator it;
it = m_FontCharacters.find( nChara ); //検索
if( it != m_FontCharacters.end() )
{ //名前があった
return it->second;
}
else
{ //なかった
return 0;
}
}


ただ、一文字一文字で管理してるので、かなり効率が悪そうです。
その辺の管理のうまい方法を模索するか、ID3DXFont使うか…。

!Font.hでFontCharacter.hをインクルードしているのに、「FontCharacterがありません」というビルドエラーが出る。

FontCharacte.hのインクルード文と、Font.hで、両方のヘッダを読み込んでいるコモン的なヘッダをインクルードしていたので、FontCharacter.hのインクルード文を必要なものだけにしたら直った。

!FontCharacterのinline指定した関数が呼び出せない

inlineを消せば直った。

inlineにするとリンクできなくなる
http://social.msdn.microsoft.com/Forums/vstudio/ja-JP/6c754499-f4c2-4fbd-baba-f6c063be229b/inline?forum=vcgeneralja


どうやら、inline指定した関数は、その.cppでしか呼び出せないらしい。

ヘッダにいろいろ書くのはイヤだけど、

class FontCharacter
{
public:

// ----- コンストラクタ・デストラクタ -----
FontCharacter( HDC Hdc, UINT nChara );
~FontCharacter();

int GetNextOffset( void ){ return m_Glyphmetrics.gmCellIncX; } //次の文字をどこから始めるか

IDirect3DTexture9 *GetTexture( void ){ return m_pTex; } //テクスチャ
IDirect3DVertexBuffer9 *GetVertexBuffer( void ){ return m_pVertexBuffer; } //頂点バッファ
D3DXMATRIX *GetLocalMat( void ){ return &m_LocalMat; } //行列

private:

UINT m_nChara; //文字コード

TEXTMETRIC m_TextMetric; //文字情報
GLYPHMETRICS m_Glyphmetrics; //文字配置情報

IDirect3DTexture9 *m_pTex; //テクスチャ
IDirect3DVertexBuffer9 *m_pVertexBuffer; //頂点バッファ
D3DXMATRIX m_LocalMat; //行列

};


こんな感じにして、解決。
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
プロフィール

ぴお

Author:ぴお
ようこそ

自分のゲーム制作での備忘録や製作記録を書き留めておくブログです。

■やってるサービス
Twitter:piorimumu

Pixiv
http://www.pixiv.net/member.php?id=1126385

Twitter
このページのトップへ