プログラマの憂鬱[第5回]

■ Dragon プログラミング Tips

DC用のWindowsCEのことをDragonというらしいです。アルバイトで とあるゲームの移植を依頼されたんですが、WindowsCEとSegaライ ブラリのどちらがいいか選べと開発初期段階で言われ、短い開発期 間しかないこともあって、プログラミングに慣れているWindowsで 作ることにしました。開発キットにはサンプルプログラムが結構多 く含まれており、ある程度は不自由はしないようになっていますが、 開発が進むにつれサンプルだけでは資料不足になってしまい、サポ ートに聞くことも多々ありました。さらに、奥底に秘められたバグ が僕ら開発陣(約2名)を苦しめる結果となってしまいました。一応、 開発セミナーをやっているみたいですがそれではサポート不足らし くバグを見つけては報告するといったようなことが結構多かったで す。もうちょっとしっかりしてもらいたいものですな。

DC用のゲームをやっていて動作が遅いと思ったことはないでしょう か?GD-ROMのアクセスが非常に遅かったり、画面表示が遅かったり することが結構あるんじゃないでしょうか。はっきり言って、これ らは全てハードのせいじゃないと思うんです。ちゃんとハードの特 性などをある程度理解し、それに見合った実装方法を選べば高速に なるはずです。こだわりすぎると、かえってめんどくさくなるけど ...。プログラムを高速化するのに重要なのは、“いかにハードウ ェアと直接付き合えるか”ということにあると思います。ハードウ ェアとの直接対話を避けていると自然とパフォーマンスを落とす結 果につながると思います。

画面に絵を表示したい場合、最初にテクスチャ用VRAMに画像を読み 込み、次に描画命令を使って表示用VRAMに描画するでしょう。たっ たこれだけのことですが、このステップの中にはパフォーマンスを 落とす要因が結構含まれていたりします。

16ビットテクスチャを高速に表示したかったり、パレット化テクス チャを使いたい場合には、Optimized形式のテクスチャを使うのが 普通でしょう。この形式のテクスチャを使うとき、通常の(サンプ ルでもやっているような)方法では、作業用サーフェス(一般形式) に読み込んでOptimized形式の実行用テクスチャにLoadするという 手順を踏むことになりますが、これは効率が非常に悪くなります。 なぜなら、DirectXが内部で最適化処理を暗黙に行っているためで、 その処理にかなりの時間を消費するうえに、特定の条件下では必ず といっていいほど失敗します。

最初にすぐ思いつく解法は、直接Optimized形式で予めデータを作 っておき、Optimized形式の実行用テクスチャに直接読み込むこと です。この場合暗黙の変換処理が入ることもなく効率的に処理で きます。ただ、これはDirectXだけの場合であってSegaライブラリ だったら考える必要もないと思います、たぶん。この解決法によ って、とりあえずはファイルの読み込み速度が劇的に向上しまし た(体感できるほど)。しかしながら、この方法には不便ことが一 つあって、最初の1回だけテクスチャ全体を更新したら、ゲーム の途中で部分的にテクスチャを更新するのが難しくなってしまう ということです。なぜなら、最適化テクスチャは線形の計算式 (y*x_width+x)でピクセル位置が求められないからです。これは、 テクスチャの更新によるテクスチャアニメーションができないこ とを意味します。

この部分的に更新できないという問題にはずいぶん悩まされました。 どうしても部分的にテクスチャを更新しなければならない状況にあ ったので、このままでは開発がしばらく停止するかと思われました。 最悪の場合、実行用テクスチャ(Optimized形式)から作業用テクス チャ(Optimized形式)にロードし、さらに通常形式のテクスチャに ロードして更新したあとにさっきと逆の操作を行うのですが、この 処理の間に2回の重い処理(最適化処理)が入ってしまうので、この 方法だけは絶対に避けなければなりませんでした。ところが、この 問題はあっさり解決してしまいました。その問題につまった日に、 疲れて家に帰ったあとに風呂に入りながら考えるとすぐに解法が浮 かびあがったんです。

理論は非常に単純です。まず、メモリ上のイメージとテクスチャ上 のイメージがどのように違うかというと、


といった具合になります。メモリ上の線形領域[1]に格納されたデ ータは、テクスチャ上の矩形領域[1]に対応します。ここで注目し たいのはメモリ上に線形に格納されたデータがテクスチャ上では矩 形領域として対応しているということです。すなわち、メモリに線 形に書き込むことでテクスチャの矩形を更新できるのです。1テク セルごとの更新をあきらめて数テクセル四方を1ブロックとして更 新するようにすればテクスチャの部分更新は可能になるのです。た だし、無秩序に書き込んでもテクスチャがめちゃくちゃになってし まうのでちゃんとルールを決めてやる必要があります。ルールは、 (1)更新ブロックのサイズが2の累乗であること、(2)更新領域の原 点(左上)がブロックサイズの倍数であること、ということになりま す。あとは、更新ブロックごとに最適化したデータを作成しておけ ば、単純なメモリ転送だけでテクスチャを部分更新することができ ます。僕は、この方法を勝手に正方領域分割法と名づけました。会 社の人は、この方法を知らなかったみたいのでセミナーでも無かっ たんじゃないでしょうか。これは、便利便利。

- 2000年1月31日 -

[戻る]