「DirectX」に関する日記(3)

<前 次>

ソーティングとDirectMusic

こないだの限界突破したLineConstructorとByteEdit、今日アップしました。

NeoMuplのDirectMusicをどのように使うか決めるため調べものしてました。
MIDIの再生にはDirectShowよりもDirectMusicのほうが、読み込みが速かったり演奏が正確だったりして適しているのですよ。
で、DirectMusicですが、DirectX 7 for Visual Basicが、機能面や手軽さからよさそうだったので使うことにしました。
そうそう、自動ソート機能も実装しました。
ファイル名順、タイトル順、再生日時順の3つを、昇順と降順の2種類用意したので、合計で6種類のパターンから選べます。
曲を追加したときに並べ替えられるのはもちろんのこと、再生日時順のときだけ、再生するたびに並べ替えが実行されます。

なんて広いステージ!

ふにゃさんの追加用極悪ステージを作っています。
なんというか、もう、めげそうです。
ふにゃさんのスペックの限界まで広いステージを作ってるんですが、やっと今下から2割ほど使い切ったところです。
空間を広く使うとどうしても大きな空白ができてしまうのですが、その部分にまで意味のあるコースを作ってしまうといくらなんでも探すのが大変すぎるということで、その部分にはわざわざ来てくれた人のために何かブロックで絵でも描いておこうかと思っています。

NeoMuplは、DirectShowだけでなくMIDIに関してはDirectMusicも使えるように方法を思案中です。
やっぱりMIDIのループ再生にはDirectMusicが一番向いていると思うのですよ。

DirectDrawは遅かった

で、yaneDirectDrawとyaneDIBDrawの性能を比較してみました。
結果はWikiに書いてあります。
圧倒的というか、話になりませんね。
yaneDirectDraw、単純な等倍転送以外、使い物になりません。
で、全てを拡大する可能性のあるこのゲームでは使えないというわけです。
何しろ一つ転送するのに10ms以上かかるということは、よくあるキャラを二人描いたら60FPSは達成できなくて、五人描いたら20FPSすら出なくなります。

ツールのこと

DirectMusicで現在のボリュームなどを得るためにはボリュームチェンジのMIDIメッセージを横取りしてその値を漏らさず見ておけば現在のボリュームは把握できるというわけです。
IDirectMusicToolを使えばそれができるらしいので現在調査中です。
他にも通知イベントを使えばやりたいことが色々できそうな気がしてます。

Bomber丸WorldのページのCBWWindowのページを更新しました。
今日BGMシステムを作ろうと思ってBGM用のウィンドウ作ろうと思ったらCBWWindowの仕様を忘れてしまっていて、取り急ぎ作ったものです。
結局これに時間とられてBGMシステムできなかったんですがね。

実時間のこと

なんとかうまくいきました。
MusicTimeを0にしていたのがまずかったようです。
RefTimeを0にすることで即座にメッセージ送信。
ついでに言えばPチャンネルを設定しておけばMIDIメッセージ側でのチャンネルの設定は不要になるみたいです。

コントロールすること

う~む、DirectMusic、コントロールチェンジを送るのが全然うまくいきません。
そもそもPチャンネルというのが曲者で、そしてトラックやらなにやらもSMFとは違っていて、もう何がなんだかわかりません。

そういえばうぃーの値段出ましたねー。
25000円ですってねー。
高いですねー。
まず本体で25000円。
コストパフォーマンスはともかく決して安い買い物ではありません。
やっぱみんなで遊びたいよね。ということでコントローラを4つそろえるためにリモコン&ヌンチャク3800+1800=5600円が追加3つで16800円。
昔のゲームも遊びたいよね。5000ポイント分のプリペイドカード+クラシックコントローラ5000円。
やっぱりクラシックコントローラも4人分集めるために1800*3=5400円。
はじめてのWii買うとリモコン1個つくので実質4800-3811=1000円。
大作の一つぐらいはもっておきたいのでゼルダ6800円。
合計すると、25000+16800+5000+5400+1000+6800=61000円。
プレ捨て3に匹敵しますがな。

そうそう、ボンバーマンの裏技のコンテンツを半分ほど書きました。
他にもいろんなステージのゴール出現条件なんかを書いてました。

ループすること

で、実際やってみました。
とりあえずループの設定だけ。
これは特別難しいことではなかったので、変数名を逆にして全然動かなくなったこと以外はスムーズに進みました。
Bomber丸Worldへの応用も結構すんなりいけるかな…?

できること

DirectMusicで何ができるのかを確認していました。
1.全てのMIDIメッセージを送ることができる
2.ソフトシンセは鳴らない音が多い
3.ボリュームやパンなどのコントロールチェンジによるパラメータは取得できない
4.マスターxxx系は反応が遅い
5.転調ができる
まあ、色々と面倒ですな。
前にサンプル代わりにアップしたDirectMusicとMFCの練習プログラムを改造して色々試しています。

白紙撤回を白紙撤回

2006/06/18(Sun)の日記で書いたことですが、白紙撤回したことをまた白紙撤回しようと思います。
つまり、今日の日記の内容は、その日の日記の、「しかし、です。」より前と同文です。

そうそう、プログラミングコーナーのDirectX7のコーナーも更新しようと考えてます。
いちいちヘルプ立ち上げるのが面倒なんで自分のサイトに必要なことが書いてあればやりやすいんですな。
いっそのことプログラミングコーナー全体をそういうものに変更しちゃおうかしらと考えている今日この頃。

母さん。・・・母さん!!

マザー3買ってきましたよ。
第一章が終わったところですが…ええ、この段階で早くも「ハッピーエンド」はありえなくなったわけですね。
まさか64版からあったあのセリフがどうでもいい知らせと最悪の知らせをもってきたものだとは想像もしてませんでした。
いや、でも、その、なんかね、正直、やっぱりマザー3は3Dであってほしかった。
やっぱりどうしても3Dのゲームを無理矢理ドット絵に落とし込んだようなゲームにしか見えないんですよ。
無益な戦闘を避ける手段は今回はダッシュらしいですね。
弱い敵なら蹴散らせます。

そうそう、プログラミングのページを更新しました。
DirectShowはどうにもDirectXとは別枠のような気がしたのでDirectXとは別のページに書いてます。
参照設定の方法も違いますしね。

一気に進む

はい、もう一気にできそうですね。
ループ処理も演奏位置を変更するだけで可能。
100ナノ秒精度ですよ。
ループ演奏・演奏後の処理など、基本的な処理が早くもできました。
あとはBGMモードを付け加えれば基本機能が出揃うわけです。
そうそう、データ記録周りを少し整理しました。
レジストリに記録する場合とINIファイルに記録する場合で同じものを記録する処理を2回書いていたのですがここを統一して書くのが一回で済むようにしました。
そして、忘れてませんよ。
NeoMuplは進んだら進んだだけたとえ中途半端でもアップします。

そういえば弟がメトロイドプライム2を買ってきていました。
グラフィックについては1がすごすぎたから別に驚かなかったんですがこれもやっぱりバンジョーと同じくやりすぎなほどの正当進化の予感がひしひしと伝わってきています。
そういえば最近爆ボン以外のゲーム記の更新が滞ってるな。
ま、いいけど。

DirectShow

MusicPlayer3の怪しい挙動にどうにも我慢ならん!
と、NeoMuplの開発のほうに行こうとしたのですが、現在のVC++6での開発状況が、MFCに挫折して自分でWindowsライブラリを作ると意気込んで作っていて色々面倒くさそうな作業がたまっていたことに気付き、C#にあっさり移行したのはよいのですが、手抜きのため導入したYanesdk.NETではMP3が鳴らせないしMIDIは左側からしか聞こえてこないしで今回の用途には使い物にならず、だったら自前で作るかと思ったらDirectX9には日本語ドキュメントがないしDirectMusicへの対応が怪しかったりで結局どっちもうまくいきそうにありませんでした。
そういえばDirectShowのヘルプに「Microsoft Visual Basic でDirectShow API のかなりのサブセットにアクセスできるが、Visual Basic のサポートは完全ではない。」って書いてあったけど、これはほとんど使えますと解釈してよいのかな…?
去年の12月にVBはいったん捨てたんですが実は再生用DLLを作る必要すらなく、VBオンリーでいけたようです。
最初からダメだと諦めて別の方法を探すって、うちの悪い癖だな。

青と白

ブルーリゾートとホワイトアイス完成です。
今度はブラックシティ…アルタイルタワーはでかいから大変そうですが…。

そうそう、DirectX10SDKをダウンロードしました。
VC++6では引き続きDX8ですが.NETには.NET用のSDKがあるようなので。
そうそう、VC++6と.NETといえば、前の更新のときにわかったのですがVS2005EEって、最適化ができるんですね。
VC++2005EEは最適化ができるけどWindowsネイティブプログラムは作りにくい。
VC++6.0SSはWindowsネイティブプログラム作り放題だけど最適化ができない。
そしてVC++2005EEではスタティックリンクライブラリが作れます。
となれば、VC++2005EEでスタティックリンクライブラリを、目いっぱい速度優先にして作り、VC++6.0SSでそれを利用してソフトを作るのはどうかと思ったわけです。
プラットフォームSDKを使わなくて済んで、効率のよさが求められるアルゴリズムではVC++2005EEでライブラリを作って、メインのVC++6.0SSに組み込むんです。
次の更新は、VC++6.0SSで、直接コードを書いて最適化なしで実行するのと、最適化されたライブラリを呼び出して実行する場合の実行時間を比較する、ってのがいいかな。
で、早速ライブラリ一つ作ってみたんですが、もうびっくりするほど簡単でした。
ソースのCPPファイルを追加して一個関数書いてコンパイルしたらそれだけで一個の関数があるライブラリの完成。
難しそうだったら効率は度外視しようかと考えていたのですが、これはさすがに度外視するにできませんね。

3Dの結末

どないしよー。
それでDirectDrawとDirect3Dでやってみようと思ったんだけど3D部分にドット絵を置いたらやっぱりドット抜けが起こって元の木阿弥なのです。
じゃあそもそも3Dでやりたかったことって何だったのか。
まずマップの前後関係のためのZバッファはZソートによって完全に無意味になっています。
エレコやギャモンは、正直、ポリゴンでさえあればなんだっていいし、アクセラレータを使わずとも自前の計算で充分何とかなるポリゴン数に収まるはずなのでこの点でもあまり意味はないわけです。
そしてDirectDrawだけではできないこと、半透明処理…やねさん、またライブラリ貸してもらいます。

バージョンダウン

えっとですね、描画エンジン、マップ表示の段階が出来上がりました。
結果はというと・・・・
・・・・
・・・・
惨憺たる結果でした。全くお話にもなりません。
ハードウェア的な相性もあるのでしょうが、これではドット絵など使えたものではありません。
とにかく今わかったことは、DirectX8はドット絵の描画にはとても使えたものじゃないということ。
おそらくDirectX9でも10でも同じことでしょう。
将来この問題が改善されるとしても私はもうそんなものに興味はありません。
逆にバージョンを下げてDirectX7を使えばDirectDrawというドット絵に特化したコンポーネントがあります。
そしてDirectDrawはDirect3Dの描画先として使うこともできます。
バージョンを落として不自由なことはありません。
プレイできる層が増え、更に表現力まで高まるのなら、それを使わない手はないでしょう。

ちなみに画像はDirect3D8で小さなドット絵を貼り付けたポリゴンを等倍でレンダリングした結果を拡大表示させたものです。
小さくレンダリングした時点でドットが潰れ、更に拡大表示する段階で画像が大きく歪んでしまっています。

1136812679.png

再利用性

もう言ったと思いますが、Bomber丸Worldのグラフィックは2Dに見せかけた3Dにしています。
そして今日作ったのはテクスチャ管理システム。
今回はRPGである都合上、画像をふんだんに使いますので、その画像を効率よく処理する仕組みが必要というわけです。
3Dで作るということで画像の表示はポリゴンにテクスチャを貼って表示させるわけですが、RPGのマップだと同じマップチップをいろんなところで表示したり、戦闘画面では同じ種類の敵が複数登場したりと、同じ画像が複数の場所で使われるケースが多いため、使う数だけ同じ画像のテクスチャを作っていては無駄であり、特にマップチップだと同じテクスチャ(それも結構でかいやつ)が何百枚と作られて、まともに動かせる状態ではなくなってしまいます。
だから、同じ画像のテクスチャを作ろうとしたときは前に作ったテクスチャを代わりに使うようにするわけですが、RPGでは場面の切り替わりと共にさっきまで沢山使われていた画像が今度は全く使われなくなるというケースもあり、逆にもう使われなくなった画像はどんどん破棄していく仕組みが必要なわけです。
ちなみにふにゃさんでは画像再利用をマップキャラ(ふにゃやギヤバネなど)に使っていたのですが、画像のサイズは高が知れているし、どのキャラもその後近いうちに再び使われる可能性が高いということで、読み込み時間を減らすため、破棄するのは絶対に使われなくなってから、つまり、ゲーム全体の終了時のみになっていたりします。
話を戻しますと、幸いにしてDirectXの全てのインターフェースはそのための参照カウントシステムを持っているため、ファイル名とテクスチャを関連付けてリスト(実際にはSTLのmap)に記憶しておき、あるファイルのテクスチャを使うときはリストからファイル名に対応するテクスチャを探し出し、見つかったらテクスチャの参照カウントを1増やしてからそのポインタを確保しておき、見つからなかったらテクスチャを作成した上でリストに追加、逆に使い終わったときは必ずリストにあるはずのテクスチャを探し出して参照カウントを1減らし、0になったらテクスチャを破棄(これは自動で行われる)した上で、リストからもテクスチャの情報を削除。
これで、常に必要な分のテクスチャだけがメモリ上に置いてあるということになります。
もしかしたらこういうことはDirectXが勝手にやってくれてて自分は無駄なことをやっているだけという可能性もありますが、まあそれにしても無駄はリスクに比べればそう大きなものでもないのでよしとしましょう。

悪魔の潜む幼帝とその師

アキヤメキャラに「悪魔の潜む幼帝とその師」を掲載しました。
まだ作り始めるめどさえ立っていない「Bomber丸World2」からです。
1には名前すら登場しません。

同じく100題に29番を追加。耳です。

昨日のDirectMusicはどうにかなりました。
あんまり演奏結果自体はよくないんですけど動作自体は正しいようです。
やっぱりSMFを使って無理やり切り替えるパネルγ方式のほうがしっくりくるなぁ。

今日の絵は女の子と頭蓋骨。
頭蓋骨のほうは一応資料を見ています。

1124289879.png

在室者管理

さてと、チャットの在室者管理でも作りますかね。
入室時:member.dat読み込み→入室者チェック→member.datにデータがなければmember.datに入室者を追加して入室メッセージを表示→member.datを更新
ログ表示時:m読み込み→長期ROMの人がいた場合自動退室させてm保存→在室者を表示
発言時:m読み→発言者がmになければエラー→最終発言時間を更新してm保存→ログ表示
退室時:m読→退室者いなければ何もせず→いたら削除&m保&退室メッセージ
てな具合でどうでしょ。

DirectMusicProducerで作ったデータを再生しようとして見事に挫折。
どう頑張っても全く音が鳴らないしエラーが出るんですよぉ。

今日は「Bomber丸World」の海音楽裏。
短調です。

日記カテゴリに「掲示板」と「チャット」追加しましたよ。

1124204328.mid

ドット絵レンダリング

どこぞの掲示板でちょっと触りの部分を書いたのですが、ここではもうちょっと具体的な話をします。
ドット絵作成には、重要な特徴をつかんで他を省略するということが大事になってきます。
それは人間の感性によるものが大きいので3Dレンダリングエンジンに計算させることは困難ですが、そもそも3Dモデル自体基本的に人間の感性で作られているものなんだから、特徴の重要さもやはり人間の感性を数値化して3Dモデルにデータとして組み込めばよいのではないかと思っています。
では重要度はどうやって組み込めばいいか。
じっくり描くのなら手描きで充分。リアルタイムにレンダリングしてこその3Dなので、とりあえずDirectXかOpenGLで使えるものがよいでしょう。
となれば、扱えるデータはある程度絞られてきます。
例えば、テクスチャとして、重要度マップを組み込む。
特定の範囲の色と重要度を対応付け、小さい場合は重要度の低い部分はレンダリングしない。
難しいのは、1ドット幅の輪郭。まあこれは頑張って計算すれば何とかなる。
ってなわけで、気が向けば実際に作ってみたいと思います。

<前 次>