新機能を考える

DXRubyにはImageオブジェクト間の転送機能が無い。
ピクセル単位で取得と書き込みはできるから、がんばればなんとかなるだろうが、恐ろしく遅いであろうことは想像に難くない。
Cでそういった機能を作ればRubyでやるよりかは相当速いだろうが、結局ソフト描画になるから、俺的にはあまり期待できない。
そもそもImageオブジェクトを画面上に2個重ねれば実現できるわけで、必要なのかと言うと微妙な気もするが、サンプルシューティングではHPメーターを実現するのに苦労したわけで、そういったものを気楽に作るという意味ではあったほうがよい。


とりあえず、簡単なものを簡単に作るための機能はほぼ揃っているはずだ。
今後、追加するとすれば、ちょっと凝ったものを作るための機能で、そういったものであれば使い方がやや難しくなるのは仕方がない。
考えているのは今のところ2つあって、ひとつは昨日も書いたゲームループの分解&ユーザーへの開放で、もうひとつはSurfaceの導入だ。


Surfaceクラスを作るとすれば、newで適当なサイズのサーフェイスを作って、draw系メソッドで描画、Window.draw系でそいつを画面に描画する形になる。
しかしそんなものを作ったとして、できるようになるのは画面内でのクリッピングや画面のクロスフェードぐらいで、作るのに苦労する割りにはあまり意味がない。
そうではなく、ImageオブジェクトをSurfaceにしてしまうほうがよい。
Image.draw系メソッドを作って、テクスチャ上に他のイメージやフォントを自由に描画できるようにする。
この考え方で、最終的に画面に描画するイメージを画面サイズのシステム保持Imageオブジェクトとして、DXRubyシステムの画面更新処理はそれ1つを描画するようにすると、まさしくStarRubyのような感じになる。
ただ、Imageオブジェクトへの描画はバッチ的にまとめて処理ができない都合上、ハードウェアサポートがあったとしてもWindow.draw系より遅くなるから、DXRubyではそのような設計にはしないだろう。
もちろん、使う側がそのように使うのは自由だ。サンプルのdot.rbはそういう仕組みで動いている。


Imageオブジェクトを描画対象とするには、DirectX上でテクスチャをレンダーターゲットにしないといけない。
そうじゃないと完全ソフト描画するか、単純転送しかできなくなるからだ。
ハードサポートを受けられないと使うほうも作るほうも大変だ。
レンダーターゲットとして機能するということは、その情報はビデオメモリに存在していなければならず、テクスチャをD3DPOOL_DEFAULT指定にする必要がある。
そうすると今度はテクスチャのロックができなくなって、lineやcircleなどといった処理がいままで通りにできなくなる。
バイスロスト時に復元処理も必要になる。
これは既に機能追加ではなく、Imageクラスの再設計だ。
それだけのことをやって、使い物になるパフォーマンスが出るのかどうかも問題だ。
っていうか、ちょっとしたことをするためになんでこんな大掛かりな話になってるんだ。