DirectX9の思想

DirectX11が出ようかというこの時代にいまだにDirectX9なのは、WindowsXPではDirectX9までしか使えないからだ。
Windows7が出ようがこの状況はまだ数年変わらないだろう。
そういうことでDXRubyも当分DirectX9だ。


DirectX9のDirectGraphicsでは、描画系の関数は基本的にDrawPrimitive系でまとめられている。
いろんなエフェクトなどはレンダーステートで設定するから、呼び出す関数のほうは簡素だ。
ところがこのDrawPrimitive系の関数、描画先に選べるのはレンダーターゲット指定されたテクスチャかサーフェイスのみなのだ。
レンダーターゲット指定するにはビデオメモリにデータを置かねばならず、ロックできない。
つまり、自由に高速に読み書きできて、しかもハードウェア描画までサポートされるサーフェイスというのは存在しない。
この部分が古いゲームの作り方と根本的に異なり、ライブラリやゲームの仕組みを設計する際のネックとなる。


まあ、昔はVRAMアクセスが遅いという理由で、仮想VRAMをシステムメモリにおいて、ソフトでそこに描画して、垂直同期に合わせてVRAMに転送、という感じだった。
いつの時代だよそれ。
DirectDrawでも、ハードがサポートしない描画については自分でソフトでやるから、基本的には似たような発想だ。
もちろん、DirectGraphicsでもシステムメモリに領域を取得するオフスクリーンサーフェイスはあるから、ソフトで描画して転送することもできるが、それではいまどきの高性能なハードを活かせないし、だいいち作るのが大変だ。
そこで、DirectXの制限とできることをどのようにライブラリの仕様の中に隠蔽し、できる限り自由に、自然に、高速に使えるようにするにはどうすればいいのか、という方向で考えるわけだ。
ある意味、その結果がDXRubyの仕様である。
まだよくわかってない時期に作ったわりには、いま考えてもそれなりに理にかなった構造になっていて助かる。


DirectXのレンダーターゲット指定というのは、データとしての保存用ではなく、あくまでも最終描画用のバッファ領域だと考えることができる。
バックバッファ以外にレンダーターゲット指定したものを作ったとしても、それはビデオメモリ上の存在であり、デバイスロストで消えるものだから、それをデータが保証されるべき保存用に使うことはできない。
ハードウェア描画したものをコピーしてシステムメモリに置こうとしても、デバイスロストしていたら描画されないのだから、不安定で危険極まりない。
一応、デバイスロストしていたらそこでRuby側の動作も停止してしまって、復帰するまで動かさない、という手もある。
バイスロストは普通起こらないし、起こったとすればゲームが続行できる状態ではないはずだから、そのときに画像処理をしようとしているRubyスクリプトが動作し続ける意味があるのか、という話だ。
いまでもタイトルバー掴んでウィンドウ動かすと止まるし、それでいいような気もする。
閑話休題


システムメモリにサーフェイスやテクスチャを置くと、ハードで描画できないから、全てソフトでやらないといけない。
ソフトでやれば、ハードによる結果の差もないし確実だが、遅い。
うーむ。
DicretXでできること・それらの特性と、Rubyっぽさ・扱いやすさを考えて、その橋渡しをするのがDXRubyの役目であって、別々の文化・思想を融合させようと言うのだから、どうにもやっぱり簡単なことではない。