Admin * New entry * Up load * All archives 

C++&DirectXでプチプチゲーム制作をしています。文章力?気合で乗り越えるさ。

 

旧 ゲーム的な何か。

12«1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.»02
2010年01月の記事一覧

« 12月     02月 »

Posted on --:--:-- «edit»

Category:スポンサー広告

スポンサーサイト 

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

tb: --     com: --

go page top

Posted on 23:30:38 «edit»

Category:プログラミングとか

高速文字列描画クラス 

どうもこんばんは、Signalです。久しぶりの学校は流石につらいですね。眠くてたまりません。

さて、今日は自作の高速文字列描画クラスを紹介しようかと。
文字列描画と言えばDirectXを扱う以上は必ずぶつかる問題かと勝手に想像しています。少なくとも私は苦労しました。
一応前作品の「Project MARCHOSIAS」では「○×つくろー」さんの
ゲームつくろー!→DirectX9技術編→その5「高速フォント表示」
を参考にして文字列描画を実現してはいたのですが、残念なことに等幅表示までしか組めなかったので、今回は変幅表示もできるように組んでみました。

「車輪の再発明」という言葉がある通り、同じ過ちまたは苦労を繰り返すことはあまり望ましいことではありません。ちょっと引っかかりそうな部分を理解する足掛かりになればなー、と思います。

ちなみにこのクラスを作成した後に気付いたのですが、「○×つくろー」さんの所に「文字列描画クラス」はすでにありました。。なんでもありますね、ホント。
ゲームつくろー!→ツール編→その5「ビルボード文字列クラス」を拝見したのですが、私の頭では理解できず、苦労が水の泡、ということは免れましたが、間違いなく動作が速いのはあちらだと思いますね。

まぁ、プロにかなうはずもないので、私の方ではよりシンプルに、楽な方法を使って実用レベルにしていこうと思います。

・ID3DXFONTインターフェース
DirectXにはID3DXFONTと呼ばれるインターフェースがありまして、これを使えば相当簡単に文字列を表示することができます。SDKのサンプルの「Text3D」にて紹介されています。
しかし、DrawText関数を呼ぶたびに文字列表示用のテクスチャを生成するためパフォーマンスが非常に悪く、デバッグぐらいにしか使えません。
ただし、フォントの設定の幅は広く、等幅・変幅などの設定も容易なので、これとDirectX自慢のテクスチャ描画と組み合わせてクラスを作っていきます。

・描画の流れ
通常DrawText関数はバックバッファに直接表示しますが、今回はDrawText関数の呼び出しを最小限に抑えます。
テクスチャに1度文字列を貼ってそのテクスチャを表示することで1枚のテクスチャ並みの負荷に抑えようということです。
以下に流れを示します。

1.描画したいフォント、文字列を受け取る
2.D3DXCreateFont関数でフォントを作成
3. DrawText関数を呼び出す(フラグにDT_CALCRECTを指定)

テクスチャに文字列を書き込むためにはまず必要なテクスチャのサイズを計算しその大きさのテクスチャを作る必要があります。大きさを計算する方法はいくつかあるのですが、DrawText関数にフラグを指定することによって、その文字列を描画した場合に必要な領域のサイズを受け取ることができます(描画はされない)

4. CreateTexture関数で必要な大きさのテクスチャを作成する
5. GetSurfaceLevel関数でサーフェイスを取得
6. レンダリングターゲットをテクスチャに設定

4でテクスチャを作成する際、UsageにD3DUSAGE_RENDERTARGETを指定します。これによってそのテクスチャをレンダリングターゲットにすることができます。

7.テクスチャを透明色でClearする
8.テクスチャにDrawText関数でレンダリング(今度は実際に描画)
9.レンダリングターゲットを元に戻す

レンダリングターゲットを元に戻すためには、あらかじめバックバッファへのポインタが必要です。クラスという形で実装する場合は何らかの形でポインタを受け取っておく必要があります。私の場合は「バックバッファのポインタ」のポインタを受け取って関数を呼び出しました。また、今回はテクスチャに深度バッファを用意せず、省略しています(3Dモデルを描画しないため)

これで晴れて文字列が描画されたテクスチャが完成しました。後は煮ても焼いても構いません。
今回は、

10. 各種レンダリングステートを設定
11. 頂点バッファを用意
12. テクスチャを適用、DrawPrimitiveUpで描画

とくにひねりはないですね。ただ、2つほど注意点があります。
①線形補間は外す
②頂点座標を調整する(丸め誤差の解消)
①は当たり前かもしれませんが、引っかかるとしばらく悩むことになります←実体験
②も既知の問題ですね。各座標値に-0.5して誤差を解消しています。

以上が今回のクラスの描画ステップです。素人製なので初心者の方にもある程度理解できるかなー、と勝手に思っています。

・注意点
レンダリングターゲット用のテクスチャを作成した場合、CreateTextureの引数PoolをD3DPOOL_DEFAULTにする必要があります。そのため、デバイスロスト時は解放、再取得を手動で行う必要があります。これに関してはご自分で処理を記述してください。(私がまだやっていないのと、クラス化すると多少複雑化するため)

ファイルのダウンロード
コチラからお願いします。
readmeにも書きましたが、素人のコードなので正しく動くかわかりません。適当に改変して使ってくださいませ。

ではでは。
スポンサーサイト

テーマ: プログラミング

ジャンル: コンピュータ

tb: (0)     com: (3)

 Re: 高速文字列描画クラス

おはようございます、ディムRPです^^

これが「高速文字列描画クラス」ですか……。

というか読んでみて分かったことは、
文字を画像つーかテクスチャに貼る」。

「文字を画像にしちゃえば高速に描画される」って事なんですよね?

んで、そこで質問なんですが。
何故に直接描画するより画像として描画した方が早いんですか?

  by ディムRP

 Re: 高速文字列描画クラス

>ディムRPさん
コメントありがとうございます。あの分かりにくい記事を読んで理解してくださるとは、察しがいいですね。仰るとおりです。
詳しい仕組みを話すとなると私も説明できないので、表面上の話で説明しますね。

元々、DirectXはゲーム向けのライブラリとして誕生したため、初期のころからグラフィックの描画速度を重視して、ハードウェアの機能を最大限に引き出すように作られてきました。そのためテクスチャの描画は非常に早く作られています。

対してID3DXFONTは、DirectXの提供する機能でありながら内部的にはGDI描画と呼ばれる非常に重い描画機構を使っています。GDI描画は(多分)CPUのみで描画を行っており、グラフィックボードを使った高速な描画が全くできないため遅いのだと私は思ってます。

そのため、文字列を速く描画するためには、一度DirectXの得意なテクスチャに変換する必要があるというわけです。今のところはこのように自分で組み立てる以外に方法はないようです。便利な機能が出来るといいのですが。。この自由度がDirectXの特徴なので、妥協するより仕方ない感じです。

  by Signal

 管理人のみ閲覧できます

  by -

Comment-WRITES

go page top

Posted on 01:58:38 «edit»

Category:プログラミングとか

またタイムアップ 

やってしまいました。只今午前2時です。Signalです。
今日は1日中プログラミングをやって数学の問題集を申し訳程度に進めたところこんな時間です。

まず結果から話しますと、無事高速文字列描画クラスは完成しました。
いろいろ廻り道はしましたが、なかなか良いものが出来たんじゃないかと思います。時間に余裕のあるときに解説します。

後基礎機能で残るはファイルの非同期読み込みですが、これも見通しがつきました。
本当に「○×つくろー!」さんには感謝してます。素晴らしいです。
なんせほしいと思った機能の8割(実感)は載ってますから、何をするにも必須です。
若干頭が追いつかないこともありますが、お陰様でさまざまな技術を短期間で理解することが出来てます。

さて今日はこの辺で。
ではでは。明日(今日)は学校です。

テーマ: プログラミング

ジャンル: コンピュータ

tb: (0)     com: (4)

 Re: またタイムアップ

おはようございます。
今日は午後から学校のディムRPです^^

「高速文字列描画クラス」っかぁー。
というか自分も早く文字だけでも表示させたいけど。
まずは「自分なりのタスクシステム」を完成させます。

それにしても2時までご苦労様です。
というか学生プログラマーならあるよね?
宿題そっちのけで開発に集中しちゃうのとかw

「○×つくろー!」をちょっと覗いてみたけど、
レベルたけぇーな。しか言い様がなかったw

んで、タスクシステム(の改良)について質問なんですけど。
いいかな?
1。「タスクリスト」って一つだけでも問題ないですよね?
いわゆる「管理タスクリスト」を一つにして。必要があるオブジェクトをリストに加えて、ないやつをリストから消去。
2。タスクにキーを付けたとして検索には普通に「ハッシュ」ですよね?速度的に考えたら。

  by ディムRP

 Re: またタイムアップ

>ディムRPさん
コメントありがとうございます。
学校の勉強を後手後手に回すとこういう結末になることが多いですね。今日もまだ勉強してません。(只今23:30)

1の回答
タスクリストは個人的には複数あった方がよかったです。確かに識別用の変数を含めれば中で種類分けすることはできますが、今回のタスクシステムのように描画の順番の制御に手間がかかる場合ですと、複数のタスクリストを持って種類ごとに分けてしまって描画および移動の順番を固定した方が使いやすい気がしました。
また、タスクリストを分けることによってタスクリストが限界になった時のダメージを最小限にとどめることができます。

具体例を挙げましょう。
Project MARCHOSIASでは、自機タスクリスト、敵機タスクリスト、弾タスクリストなど10種類使っています。タスクはそれぞれ全く機能が異なるため、描画の場所なども異なってきます。そのため、1タスクリストだと設定変更などの処理が余計になってしまいます。また、弾幕を生成したときに、弾タスクでタスクリストが埋まってしまった場合、1タスクリストの場合その他の自機、敵機などのタスクも生成されなくなるという状態が発生します。それを防ぐためにも、複数タスクリストは(今の仕様に関しては) 有用だと思います。

2の回答ですが、あまりこだわる必要はないかと思います。ハッシュを使うのでしたらそのまま使ってしまってよいのではないでしょうか。
正直なところ私はアルゴリズムもろくにやっていないというヘタレでして、具体例を挙げられない、という情けない状況、というのも理由としてあるのですが、今回のようにタスク数の限界が見える場合(せいぜい数千タスク)という場合でしたら、描画などの比重が大きいので、ソートでそこまで手間取る必要なないと思います。

頼りない回答でホント申し訳ないですが、そういうことでお願いします。

  by Signal

 Re: またタイムアップ

こんばんわー^^

またまた、数学の問題とかやるんだからーw


文字列の高速描画って……
C言語は、文字列の処理が苦手とか聞いたことありますけど……

そういえば、文字列だけ、たくさん表示すると、処理が非常に遅くなってしまったことがありますw


それじゃ、学校とかいろいろ頑張ってね!

  by patole

 管理人のみ閲覧できます

  by -

Comment-WRITES

go page top

Posted on 01:13:09 «edit»

Category:プログラミングとか

文字列描画苦戦中 

ずーっと文字列描画に費やしてます。Signalです。
ホントは今日中に一応動くようにはしたかったのですが、描画がおかしいままタイムアップ。
明日(あるいはもっと後)にはまともな記事をかけるかもしれません。

ではでは。

テーマ: プログラミング

ジャンル: コンピュータ

tb: (0)     com: (0)

go page top

Posted on 22:48:46 «edit»

Category:雑談

あけましておめでとうございます 

あけましておめでとうございます。生きてます。

一応描画・入力周りのクラス化が終わって、タスクシステムの整理や文字列表示の手入れに入ったところです。
「書きたい!」ということがあれば更新したいと思います。正直沈みそうです。

ではでは。

テーマ: 日記

ジャンル: 日記

tb: (0)     com: (6)

 Re: あけましておめでとうございます

お久しぶりです。そして、
明けましておめでとうございます。
ディムRPです。

最近あんまり更新されていないので、ブログするの止めたのかな?と思い始めていましたが続けるみたいなので"少し"だけ安心しました。

でも自分的にはもう少し、
”僕は活動していますよ”的な事を示す記事を書いたり、
”まだまだ僕はいるよ”的な、アピールを発言を俺のブログにコメを残したりナタクさんのチャット部屋に参加してやってほしい。

まぁ、学業や部活やプログラミング等があり忙しいそうなので無理にとは言いませんが、”相互リンクを結んだブログ仲間”として頑張って貰いたい。

別に怒ってるわけではなく心配して言ってるので、
もし気を悪くされたら申し訳ない。

そしてプログラムのクラス化ファイトです^^
こっちもそろそろ新たな言語を学ぼうかと思います^^

  by ディムRP

 Re: あけましておめでとうございます

>ディムRPさん
コメントありがとうございます。

ここまで心配してくださっているとは。。申し訳ない限りです。
相互リンクしてくださった方々のためにも、頑張らねば、と思い直すきっかけになりました。
今後絶対にアピールを続ける!と宣言できるほどの自信はありませんが、なるだけやってみようとは思います。

そちらも新言語の取得頑張ってください。
D言語は名前しか聞いたことがなかったのですが、実践されると聞いて興味が湧いてきました。
参考にさせていただきますね。

こちらもペースアップと行きたいところです。お互い(まずは自分ですが)頑張りましょう。

  by Signal

 Re: あけましておめでとうございます

おはようございます。
何度もすみませんディムRPです。

そうそう。その意気ですよ?
勢いは大事ですからね。
あと気合。それさえあれば大丈夫^^

はい、無謀と分かっていながらも
新言語の取得を頑張ろうかと思いましてですね。
しかもD言語というマイナー言語ww

参考に、ですか?
いやいや自分なんか人の手本になれないですよw

というか僕的にはSignalさんを手本にしたい。
ブログは更新せずともプログラミングの方は着々とクラス化を進められており、
ブログは更新してるけどプログラミングが遅い僕とは大違い。

まぁ、これはお互いの利点を見習い合うしかありませんね。
そこでっ!相談なのですが、自分ことディムRPと「patole」さんを助けてくれませんかね?

ああ、大げさに言ってますけれど大した事じゃないです。
土曜日か日曜日の「ナタクさん」の所で、
タスクシステムについて講義してくれないかと思いましてね。

実はとあるゲームの処理が重くて、
オブジェクトが管理しきれていないという結論に至り、
それなら「タスクシステム」を使えばとネット上で調べてわかったんです。
が、イマイチ、よく分からないので
実際に使ってるSignalさんに特徴やらメリットやデメリットなど聞ければいいなと思いまして。

あの、どうですか? お願いできます?

  by ディムRP

 Re: あけましておめでとうございます

おめでとうございます^^

タスクシステムとかですか……

そうそう、ディムRPさんのいうように、タスクシステムを教えてほしいなと^^

そのとあるゲームとは、僕のゲームでありまして……

よろしくお願いします!w(って、いいのかな?

  by patole

 Re: あけましておめでとうございます

>ディムRPさん
お返事ありがとうございます。
今マイナーな言語も、ディムRPさんのような方の挑戦から普及していくものですし、私にはそのような勇気はないです;;
ちなみに私もプログラミングは遅いですよ、さすがに数年間やってきたのが効いて多少はごまかせるようにはなりましたが、所詮その程度です。
実際に完成した作品もなんだかんだで1作品でしかないですし、patoleさんの速度が不思議でならない。。

タスクシステムの件、了解しました。親との兼ね合いがあるのでチャットに出没出来るかはその時にならないとわかりませんが、私の知る範囲で協力しようと思います。

一応この場で言えることをいくつか先に言っておきます。
タスクシステムとは言いますがオブジェクトの管理としてはかなり基本的です。おそらくそちらで今使っているオブジェクト管理と大差ないとは思います。
後、ゲームの処理が重い場合は、真っ先に描画処理を見た方がいいかと思います。後重いとすれば、三角関数などを大量使用した場合だったり、バグだったりで、オブジェクト管理との関係は薄いんじゃないかと思います。
もっとも実際にソースを見て判断しないといけないので分かりませんが。。自分の経験としてとりあえず言っておきます。

  by Signal

 Re: あけましておめでとうございます

>patoleさん
おっと、書いてる途中にコメントされたみたいですね、詳細は上の通りです。
メダルゲーム、プレイさせていただきました。自分としては、あのようなゲームが短期間で作れるのが不思議でなりません。今度のチャットのときにでもソースを見せていただけるとありがたいです。

ではでは。

  by Signal

Comment-WRITES

go page top

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。