復帰といいつつ
6ヶ月も放置してますね・・・。
原因としては仕事もあり、あまり自宅でプログラミングする時間がないというのが大きい気がします。
特に3Dとなるとかなり時間がかかるため手軽に出来ないのが残念です。
久々にDirectXSDKの最新を調べてみるとXAudio2なるものが増えてますね。
でもDirectX日本語ヘルプは2004年10月で止まってますし・・・。まだβみたいなので様子見かな・・・。
仕事でJava使ってますし、携帯アプリにでも手を出してみようかなと思っています。
他にもブログらしい手軽に書けるテーマを探す必要があるなと思って色々探していました。
一応見つけたには見つけたのですがやろうかどうか悩み中。プログラミング関係ないですし。
放置するよりはいいのかなぁ・・・。
スキンメッシュ用OBBの作成にて2
何とか解決しました。
ConvertToBlendedMeshメソッドを呼んだ後に、Remapメソッドを呼ぶ必要があったようです。
LPD3DXBUFFER bf;
if(FAILED(hr=pMeshContainer->pSkinInfo->ConvertToBlendedMesh(
pMesh, // 入力メッシュ
NULL,
pMeshContainer->pAdjacency, // 入力メッシュの隣接性情報
NULL, NULL, &bf,
&pMeshContainer->weight, // ボーンの重み
&pMeshContainer->cntBone, // ボーンの組み合わせテーブルに含まれるボーンの数へのポインタ
&pMeshContainer->pBoneBuffer, // ボーンの組み合わせテーブルへのポインタ
&pMeshContainer->MeshData.pMesh))) // 新しいメッシュへのポインタ
{
return hr;
}
DWORD *d=(DWORD *)bf->GetBufferPointer();
pMeshContainer->pSkinInfo->Remap(pMeshContainer->MeshData.pMesh->GetNumVertices(),d);
bf->Release();
こんな感じにして、OBBを作成してみると上手く行きました。
Remapのヘルプを見ると
「ターゲットの頂点バッファが外部的に順番変更された場合は、このメソッドを呼び出す必要があります。」
とあります。
ConvertToBlendedMeshメソッドはスキンインフォのメソッドなのに外部とは・・・。勝手にやってくれても良いと思いますけどね。
でもRemapメソッド使わなくても描写に何の影響もなかったのは謎です。
「Remap SkinInfo」でグーグルで検索しても日本語サイトでないですし、良く分からないメソッドです。
で。
やっとスキンメッシュOBBが完成しました。
DirectXサンプルの彼を使ってもちゃんとOBBできてます。(画像参照)
深さ3なのでちょっと荒いですけれども。
一応複数のメッシュコンテナが有る場合でもちゃんとOBB作れるようにしてあります。
これで大概のモデリングデータに対してはOBBが生成できるはずですが、余り自信なし(笑)
基本はサンプルの理論を参考にかなり無茶な方法で生成してるんで、生成に時間が掛かります。
やはりあらかじめ作成しておいて外部に保存しておき、公開するときはファイルから読み込むのがよさそうですね。
SkinMeshOBBという独立のクラスにして、渡すデータは何の拡張もしていないLPD3DXFRAMEだけなんで、組み込みやすく作ったつもりです。
スキンメッシュ用OBBのサンプルのサイト少ないので、公開したいところですが相変わらず付属テキスト作るの面倒なのでどうするか決めていません。まあ、
こちらのサイトのOBBTreeのサンプルをコピペしまくって作っているので流石に公開はマズイかも。
あとはHLSLでスキンメッシュできれば趣味の範囲としてはもう十分かな?
スキンメッシュ用OBBの作成にて
3Dゲームを作っているとどうしてもスキンメッシュ用OBBの作成が必要になります。
http://www.nomuraz.com/denpa/prog005.htm#IDPROG0028
を参考にして、製作しているのですが、上手く行きませんでした。
色々試してみたのですが、どうやらConvertToBlendedMeshメソッドを呼び出していると上手く行かなかいようです。
とはいえD3DXBONECOMBINATIONは必要で、外すわけにもいかないですし・・・。
このメソッド、一体何をしているのか良く分からなかったりしてどうすれば良いのかちょっとわかりませんね。
何か分かったらまた記事に書こうと思います。
マルチスレッドで読み込み中の画面を作成する3
読み込み画面を実装してから色々と試してみたら、D3DXLoadMeshHierarchyFromX関数で読み込み失敗することがありました。
どうやらスレッドセーフではなかったようです。
なんとかする方法はないかなーと探していたら、CreateDeviceにD3DCREATE_MULTITHREADEDというフラグを発見。
これで無事正常に動作しました。
しかしヘルプを見るとパフォーマンスが低下する可能性があるようです。
マルチスレッド自体も重そうな気もしますし、あまり3Dゲームで読み込み画面の実装は良くないのかもしれませんね。
フレームマネージャ4
今まではフレームオブジェクトの登録に
MyGame *m=new MyGame;
GetFrameManagerWins()->RegistFrameData(m);
としていたのですが、テンプレートを使って
GetFrameManagerWins()->RegistFrameDataMakeInstance<MyGame>();
とすると登録できるようにしました。
処理としては
template <typename T> bool RegistFrameDataMakeInstance(void){
T *dt=new T;
return RegistFrameData(dt);
}
っていうだけなのですが、deleteはフレームマネージャが勝手に行う仕様だったので、今までは
「RegistFrameDataメソッドの引数はnewで生成したものでなければならない。また、newは自分でやらなければならないのにdeleteはしてはいけない。」
という分かりづらい仕様だったのが、この方法にしたことで分かりやすくなりました。
テンプレートって意外なところで役立ちますね・・・。
本来は
template <typename T> T max(T a,T b){
return ((a>b)?a:b);
}
int i=max(20,10);
double d=max(1.0,5.1);
というように使うのが一般的なんでしょうけど。
マルチスレッドで読み込み中の画面を作成する2
フレームオブジェクトのRelease関数が呼ばれなかったりと色々と苦労がありましたが、なんとか完成しました。
CreateThread関数は標準ライブラリ使うとメモリリークすることがあるらしいので、_beginthread関数を使うことにしました。
簡単ですし、終わったら自動でCloseしてくれますし、読み込み画面の実装という点ではこれで十分だと思います。
で、HP更新のネタにもなるしサンプルプログラムとして載せようかと思ったのですが、付属テキストを作るのがめんどくさくなって
やめました(笑)
まあ、欲しいって人もいなそうですし、マルチスレッド使えば実現できるというのが確認できただけでも収穫かなぁと思うことします。
マルチスレッドで読み込み中の画面を作成する1
ゲーム機なんかではロード中にNow Loadingという文字とともに絵が出たりします。
コレを実装させたいなーと思っていたわけです。
1枚絵でいいならば、読み込みを始める前に1枚絵を表示させて、読み込み処理を行えばいいだけです。
しかし、文字が動いたり絵が変わったりさせたい場合があると思います。
PS2の大神なんかでは読み込み画面でボタンを押すと足跡が書かれていき、連打するとアイテムが手に入ったりしました。
PCではHDDからデータを読み込むことが殆どですので、適当に作っても大抵DVDなんかから読むより高速です。
しかし、ファイルをデコードしたりすることもあるのでそれなりに時間がかかるものです。
読み込み中の画面を表示させながら裏で読み込み処理を行う・・・。
こんな感じのシステムにする場合、どうすればいいでしょうか。
ここでマルチスレッドの出番です。
マルチタスクでなくマルチスレッドなのは、読み込んだデータを同じプロセスが使うからです。
今回タイトルに1が付いてますが、まだ試してないので本当に上手く行くか分からない為です。
後日完成したらその2を載せる予定です。
このマルチスレッドの実装方法ですが、どうやらOSによって違うみたいです。
Windowsの場合CreateThread関数を使うようです。
CreateThread関数の詳細は
http://wisdom.sakura.ne.jp/system/winapi/win32/win143.html
この辺を参考に。
WindowsAPI・・・なのかな?
処理速度はどの程度なのかちょっと気になりますが、遅く見積もっても0.1秒掛からないでしょうから、読み込み中の画面の実装という目的なら問題ないかと思います。多分。
第3引数は関数のポインタを渡すためメンバ関数を使いたい場合はスタティックにする必要があります。
今後はコレを使って読み込み画面の表示を作りたいと思います。上手く行くといいのですが。
フレームマネージャにこの機能つけて、サンプルプログラムとして公開するのもいいかな・・・?
でも欲しい人います?
あんま需要無い気も・・・。
ライブラリ化
この辺を参考にしつつ、今まで作っていたマネージャやら仮想コントローラやらをライブラリ化しました。
これで新しく作る時に毎回コピーしてくる必要がなくなって便利になりました。
何故かやたらファイルサイズが大きくなっていますが・・・。
インクルードしたファイルがごっそり入っているのかもしれませんね。