楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル

log

2011.10.11 C++:MIDIの実装


今回、背景を新しいものに差し替えてみました。それとさらにMIDIをBGMとして再生
できるようになったのですが、ネット上のMIDIファイルを無断でお借りしていたので
動画では音をOFFにしています。ぜひ、想像でお楽しみください苦笑;

といっても、手持ちのMIDIの半分くらいしか正常に再生できないんですよね。。
自作読み込みで実装しているせいなので、MCI等を使えばお手軽に読み込めたりする
のですが、これだとループ再生したときに音が途切れてしまうのです。あぁ、難しや。

しかし色々工夫していた甲斐あってメモリ使用量が70MBから15MBまで下がりました。
別に高速化した訳ではないですが、読み込みが軽くなった分喜びは大きかったりします。

2011.10.06 C++:パーティウォークスルー

ファイル 368-1.jpg

ようやく画面内のキャラクタ数が増えてきて、賑やかになってきました!

これもLWO,LWSファイルが読み込めるようになったおかげなのですが、同時に少し
妙なバグにてこずってしまいました。内容としては、Debugモードでは正常に
動作するが、ReleaseモードではLWOモデルで読み込んだスキンメッシュモデルだけ
ぐちゃぐちゃに描画されるというものです。で、これはVC外から実行した場合の話で
VC内からだとReleaseモードでも正常に描画されるという。

このバグを見つけたときは、LWO読み込み関数を調べたり、マルチレンダーターゲット
をOFFにしたり、デバイスの設定を変更したり等して色々調べてみましたが、、ようやく
分かった答えが。なんと、初期化していないbool変数を利用して描画分けしていたので
スキンメッシュモデルが背景モデルとして描画されていた、というだけのことでした…;
うーん、通りでプログラム上は問題ないように見える訳だ。問題の部分がごっそり
抜けてしまっているのですから苦笑。別個の関数からアクセスしているので、警告が
表示されるわけでもないですし。なかなかにやっかいなバグでした。。それにしても、
コンパイルするモードによって初期化される値が違うということのようですね。不思議だな。

2011.09.25 C++:コンストレイント続き


今度はボーンの方向をコンストレインさせるのではなく、ボーンのBank軸回転のみを
コンストレインさせる関数を作成したので、これでようやく頭を指定座標に向かせられる
ようになりました。

角度制限がついていないと流石に酷いので、とりあえず急ごしらえで角度制限機能を
つけてみました。処理としては、プレイヤー以外のキャラクターはプレイヤーのモデルが
正面にいる場合はプレイヤーの方向を向くようになっています。

まだ内分処理もしていないのでぎこちないですが、静的なモーションだけだった頃と
比べると妙なリアリティが感じられるようになりました。

2011.09.25 C++:向きコンストレイント

ファイル 366-1.jpgファイル 366-2.jpg

指定ボーンを指定座標の方向に向かせる機能を作成してみました。
本当はIKをやってみたかったのですが、IKを組んでいる過程でつまづく部分が多かった
ので、実際は単純な機能からやってみようかなというのがきっかけだったりします;

出来たことは出来たのですが、今のところ問題は2つあります。
1つ目は角度制限機能をつけていないので、曲がってほしくない範囲まで曲がって
しまうこと。もう1つはBank軸回転がどの向きを向くか予測がつかないということです。

2つ目について詳しく説明するとします。Bank軸というのはボーンの方向を回転軸とした
回転のことですが、ボーンの向きは定まってもボーンの方向を回転軸とした向きは、
言ってしまえばどれをとってもいい訳です。なので腕に対して使用した上の画像では
特に問題がありませんでしたが、頭に対して使用した下の画像では頭の正面の向きが
キャラによって異なっています。

まあ、一般的な3Dソフトの向きコンストレイントも同様の現象が起きるので、そういう
ものなのかもしれませんが。なにかいい解決方法が無いかなあ。

2011.09.09 C++:マルチレンダーターゲットの不都合

グローとSSAOがやりたかったので、とりあえずHLSLとレンダーターゲット周りを
改良していたのですが。いままでウィンドウモードで作業していたところ、どうやら
フルスクリーンモード時に正常に描画されていなかったことが発覚!

色々試してみて、マルチレンダーターゲットをOFFにすることで元に戻ったのでした。
それで、ネットでいくつか調べてみるとどうやら画面のビット深度とレンダーターゲットの
ビット深度が同じでないと駄目みたいなようです。
ttp://maverickproj.web.fc2.com/pgMemo.html

それで、画面のビット深度を調べてみましたが…これが同じ32Bitなんですよね。
なので、試しにD3DFMT_A8R8G8B8からD3DFMT_X8R8G8B8に変更して
みると、とりあえずRGB部分は正常に描画できましたが、この場合ウィンドウモードに
してみるとZバッファが利いていないかのような不自然な描画になるという怪奇現象。。

うーん、漠然とした感じなのですが。今まではDirectXの仕様にそった不都合という
のは度々ありましたが、これはDirectXの仕様というよりGPUの不備による
トラブルのような気がしてきました。以前からフルスクリーンモードはMSAAが
利かないので敬遠してましたが、どうやら擬似フルスクリーンにした方がよさそうだ。

しかしながら、自分が思いついたSSAO。頑張れば出来そうな気がしますが、針の
穴を通すかのようなかなりピンポイントの調節をしないとそれっぽくならなさそうです。
思いつきやすい処理であっても実装しづらい、というのは中々にやっかいである。

2011.08.28 C++:ビルボードビームとデバッグ用関数

ファイル 364-1.jpg

今回はビルボードビームを作ったり、新しく可変長引数が使いたいなと思ったので
ちょっとデバッグ用関数を作ってみたりしてみました。

実を言うと、ビルボードビームの実装自体はほぼ9割方、かなり前に組んでいたので
すが、そんなことをすっかり忘れていてふと再発見しただけなのでした苦笑。
とりあえず、テクスチャも用意してないけどサクッと確認。画像の白いライン部分が
ビルボードビームの実装です。基本的にはパーティクルと同じでビルボードの応用
ですが、ビルボードビームのポリゴンは完全にカメラと向かい合う訳ではないので
Zソートは出来ないんですよね。。さて、どうしたもんかと思いましたが。解決方法として
不透明なテクスチャのビルボードビームを描画した後にポストエフェクトでぼかすのが
一番都合がいいかなと思いました。

それと、デバッグ用のメッセージを表示する関数を作ったのでちょっと公開してみます。

// デバッグ用メッセージをダイアログで表示させる関数
void DebugMessege(
char* TitleMessage, // ダイアログのタイトル用文字列
char* Parameter, ... // メッセージ用文字列(可変長引数)
// printf()のように、Parameterの第1引数は書式文字列、
// 第2引数以降は変換するパラメータのリストを記述する
){
// メッセージ用文字列配列を作成
char ErrorMessage[1024];
// 可変長引数にアクセスするためのポインタ
va_list argument_pointer;
// 可変長引数Parameterの先頭引数のポインタを取得
va_start(
argument_pointer,// 可変長引数の先頭引数のポインタを格納
Parameter // 取得する可変長引数
);
// 可変長引数リストのデータを書式文字列に従って文字配列に書き込み
// cf.vsprintf_s()の第4引数部分は普通ならば関数に渡された
// 可変長引数の1番目の要素から始まりそうだが、
// vsprintf_s()の第3引数に直接Parameterを指定している
// ので可変長引数の2番目の要素からアクセスされる?
vsprintf_s(
ErrorMessage, // 文字列の格納先変数
sizeof(ErrorMessage),// 連結した文字列のサイズ
Parameter, // 書式文字列
argument_pointer // 変換するパラメータのリスト
);
// 可変長引数へのアクセスを終了したことを伝える
va_end( argument_pointer );
// メッセージをダイアログで表示。
MessageBox( NULL, ErrorMessage,
TitleMessage, MB_OK | MB_ICONSTOP );
// cf.デバッグウィンドウに出力する場合
// OutputDebugString( ErrorMessage );
}

コメント部分に書いておきましたが、vsprintf()の実装が今ひとつ分からなかったり。。
とりあえず簡単にメッセージを表示できるようになったからいいですけどね。
それにしても、、日記内にプログラム記述するのがちと面倒くさいな笑。

2011.08.26 C++:ひさしぶりなプログラミング

最近プログラム触ってなかったな、と思ったので。ちまちまとプログラムの修正を
したりしていました。新しく追加したのは、データの暗号化/復元化くらい…苦笑;

それとつい先ほど寝ぼけまなこでうつろうつろしながら、高速でSSGIとSSDOを
実装する方法を思いついたので、いそいそとメモし終わったところです。
上手く実装できれば、自分のようなへっぽこ環境でも結構綺麗なグラフィック
表現ができるようになるわけですが。。さて、どうなるやら。

今までの経験上、なぜか寝ぼけた状態が一番ひらめきが多いんですよね。
普段が人一倍頭が固いせいなのか、、他の人も同じようなものなのか。不思議です。

2011.03.18 C++:OpenGLはじめました。

最近になってまた少し寒くなってきましたが、、「もっと熱くなれよっっ!」と思うこの頃。

前からOpenGLの勉強を少しずつ積み重ねていたので、今までDirectX一辺
倒で制作していましたが今回少しだけOpenGLのプログラムを組んでみることに
しました。とりあえず頂点バッファの実装まで出来て、思うことがあったので、
そのことについてのメモを残しておきます。

インディーズデベロッパの方の多くがDirectXでの開発なのではないかなと推測して
いるのですが、それの大きな原因となっているのがOpenGLはDirectXと
比べてより低レベル実装なAPIであるということなんだと思っています。具体的には
D3DXのようなヘルパー関数が標準で実装されていなかったり、デフォルトの
描画処理周りがスタック構造になっている、等など。

ヘルパー関数についてはDirectXで自作実装していれば容易にそこから持って
これそうですが、DirectXが左手座標系なのに対してOpenGLは右手座標系
ですから、そのあたりでやっぱり少し面食らう訳なのです。
「OpenGLでも作ってみたいけど、色々と面倒そうだし資料少ないし実際
DirectXと変らないでしょ?」という感じでそのままDirectXの制作に戻る
のも頷けます。自分もそうでした笑。

ただ色々とOpenGLを調べてみると、低レベルAPIであるおかげでDirectXでは
触ることすら許されない部分が自分でカスタマイズできるという利点もある訳です。
例えばOpenGLだと頂点バッファをそれぞれ座標用バッファ、法線バッファ、UV
バッファのように分離してそれぞれを指定して描画ができます。

ここから何ができるのかというと、以前制作したボクセルは必ず頂点位置が一定
間隔でスナップするので、頂点座標のバッファはリサイクルできるわけなのです!
DirectXだとリサイクルしようにもUV等の他の共有できない情報が邪魔してしまう
のですが、OpenGLだとそれが可能になります。これは嬉しい。

他にもトライアングルストリップの他にクアッドストリップ(トライアングルストリップ
の4角ポリゴン版)等があったりと、DirectXでこれあったらいいなと思っていた機能が
ちらほらある感じで、3DソフトでOpenGLを使っているものが多いのが何故なのか
妙に頷けるような気がしました。どうでしょう、OpenGL触りたくなったでしょう?笑


追加:
よくよく考えて後から調べてみると、DirectXでもSetStreamSource()の
ストリーム番号を指定することで複数バッファで描画できるということを知りました。
あらら、自分の無知を晒してしまいました。。まだまだDirectXでも新しい発見が
ありそうですね、頑張ろう!

2011.03.16 C++:ボクセルことはじめ

ファイル 340-1.jpg

流体表現をやる前のことはじめとしてボクセルを実装してみました。
手前の白いワイヤーの形状がボクセルで表現しています。とりあえず形だけは
できましたが、まだ法線計算もできていないし、UVも計算できていないです。。

ボクセルが出来たところで、ちょっとリアルタイム流体表現の話でもしてみます。

昨今のリアルタイム流体表現は、自分が知る限り大きく2つの表現に分かれるかと
思います。ボクセル表現とスクリーンスペース表現です。
・ボクセル
 等間隔グリッドごとの情報を元にサーフェイスを生成。
 利点:分割数次第でスクリーンスペースと比べて滑らかになる。
 欠点:分割数が多いほど頂点計算やロック処理が重い。
・スクリーンスペース
 ハイト情報のパーティクルを一時バッファに描画し、バッファをブラーした後、
 バッファのハイトを元に法線を計算してレンダーバッファを描画。
 利点:サーフェイス生成を行わないので効率が良い。
 欠点:複数回描画なのでピクセルシェーダ負荷が大きい。

こんなところでしょうか。自分が思う限り、ボクセルはサーフェイス生成が面倒な上に
半透明の形状は不得意な印象なのでスクリーンスペースの方が実装が楽かな
という気がします。はい、「なぜボクセルにした!」という話になりますね笑。

リアルタイムのサーフェイス生成は近年のGPUでようやくそれなりにできるように
なったかなという感じですが、今後よりこの動きが加速するんじゃないかというのを
見越しての実装です。何より、動的にオブジェクトを生成できるっていうのは楽しい
ことだと思うんですよね。昔のゲームでも、例えばアイテムを合成したり町づくりが
できたりといった要素が入っているものは楽しかった印象があります。
実は3Dになってから逆にサーフェイスやオブジェクトが少し静的になった部分が
あるなと以前から思っていましたが、嬉しいことにようやくそれを乗り越えられるような
いい時代がやって来たのかもしれません。…て、一体何をいっているのやら笑。

2011.03.11 C++:LWS読み込み

ファイル 337-1.jpg

LWSファイルからのモーション読み込みがある程度出来てきたので、さっそく
新しいモデルの方をプログラム上に読み込んでみました。
毎度のことながら、とても試行錯誤することになりましたが、実装できて本当に
よかったです。デバッグで画面が立ち上がる前の「うまくいくかな?それともまた
失敗だろか?」っていうもやもやの中でうまくいったときの喜びは大きかったでした。

それで、今回は何に苦戦したかといえば。今までウェブ上で調べていたらLWの
回転順序はY-X-Zだと書かれていたので、そうとばかり考えていたのですが、
実はそうではないんですよね。確かにレイアウト上ではY軸を動かせば他の2軸も
拘束しているように見えるし、Z軸を動かしても他の2軸は動かないので、Y-X-Z順
に回転しているんだなと思うのが普通なのですが、プログラム上での実際の回転
順序はZ-X-Yなんです、これが。

それで、回転順序は合っているとばかり思っていた上にスキニング後の位置が
ボーンの長さよりも長くなったりしていたので、オフセット情報がおかしいのだろう
とばかり考えていて、結局無駄な時間を過ごしてしまいました。どうやらスキニング
の場合は回転と平行移動の行列を交互に掛け合わせるので、回転順序が違うだけ
で親空間からの距離も変わるみたいですね。

それと後になってから色々と考えてみましたが。結局Z-X-Y回転なのにGUI上では
Y-X-Z回転のように見える謎がよく分からずに終わりました。例えるなら天動説と
地動説のように、地球からみれば太陽は地球を中心に回って見えるけど太陽から
みれば地球は太陽を中心に回って見えるような感じで、相対的に逆転してみえる
ものなのかな、と。なんともあやふやな答えしか出せませんでしたが、いずれ分かる
ようになったらまたそのときにでもメモしようかと思います。

そういえば、実装してみて思いましたが。モーション情報が読み書きできるように
なったので、モーションファイルのコンバータが作れそうだなと思いました。
現状だとBVH、DAE、VMD当たりのフォーマットについてはある程度把握できて
いるので、機会があれば実装しようかなと考え中です。昔の自分だったら、
フォーマット調べても「何コレ?分からん。。」で終わっていたのですが。それなりに
成長したのかもしれないな。