なぜデバイスロストが問題になるのか

DirectXを直接使うプログラミングをする場合、デバイスロストの動作を理解してゲームを設計しなければならない。
テクスチャを全てレンダーターゲットにしてハードウェア描画をしながら使う、ということをすると、デバイスロストで全てを失うことになるから、じゃあどうしようか、と考える必要がある。
DirectXの難しいところの一つはそれで、DXRubyはそれを意識しなくていいように、アノ手コノ手で隠蔽しているのだ。
基本的に厄介な問題というものは対処法が場合によりマチマチで、やりかたは直接パフォーマンスと柔軟性に影響する。
パフォーマンスと柔軟性はトレードオフの関係にあるから、作るゲームに必要最低限の柔軟性を確保することになる。
両立できるぐらいなら、DirectXのレベルで対策されているはずのものだからだ。
DXRubyではパフォーマンスを追及してはいるが、あくまでも最大限の柔軟性を確保することを前提としている。
これからも現状の柔軟性は死守する方針だ。
Imageオブジェクトへの描画が自由にできたらいいな、とは思うが、それがどんな微妙な条件だとしても保証されない可能性があって、ユーザーが意識して対策しなければならないのなら、採用できない。
掲げるものはRubyで気軽なゲームプログラミングだ。


Imageオブジェクトは画像データではあるが、クラスの一つであって、Rubyにとっては単純なデータだ。
そのイメージでいくと、書き込んだデータは保持されるべきであって、他の、OSやハードウェアの状態により破壊されていいものではない。
使う側は普通はそんなことを想定しない。
俺自身そうであって、サンプルのdot.rbはまさにそれが大前提のプログラムになっている。
書き込んだ瞬間にデータが変更され、その時点から読み出しが可能となる、そういうふうに使う側は考えるし、それが自然だ。
これはImageオブジェクトとWindow.draw系によるスクリーン描画の大きな違いの一つで、スクリーンはRubyのデータではないから読み出せない&1フレームごとに見える状態になるから、裏で描画順ソートや描画をまとめて処理できる。
描画順ソートをしようと思ったらWindow.draw系によるスクリーン描画は必須なのだ。


そういうわけで、Imageオブジェクトをレンダーターゲットにすることは、前回のデバイスロストの話も含めて考えると、諦めざるをえない。
画像データを扱うRubyのオブジェクトである以上、パフォーマンスや多機能さよりも大切なものがあるからだ。
逆に、パフォーマンスや多機能さを持ちつつ、デバイスロストの可能性まで表に出したものを追加するのはアリかもしれない。
ちょっと凝ったものを作るための、ちょっと難しい機能として。
それがSurfaceクラス・・・と考えていたのだが、ひょっとして機能的にはWindowモジュールとほぼ同等になるような気がして、もういっそのことWindowもクラスにしてウィンドウ非表示状態のWindowオブジェクトをSurfaceとして扱えるとか、複数ウィンドウの表示も可能にしちゃうとか。
可能性としては面白いが発想が飛躍しすぎなのでそれは置いといて、まあなんしかレンダーターゲットになるSurfaceという概念を新規に追加するのはいいかもしれない。
そこにlineとかcircleとかで絵が描けたり、そこからimageオブジェクトを生成したりできればいいのだろうが、そもそもそんなことができるならimageオブジェクトがそうなっているはずで、それができないからSurfaceクラスを作るわけで、やっぱりそういうことはできない。
どうしても微妙に使いにくいものになりそうだ。
このあたりはまだまだ悩むことになるだろう。