折角 WindowsMobile 5.0 の SDK を触ったので Direct3D Mobile も試してみました。
WindowsMobile 5.0 には DirectX 系 API が含まれていて、 Direct3D Mobile や DirectDraw を使用することができます。
携帯電話でも 3D のアプリが当たり前に存在していて 3D アクセラレータチップが乗っている時代です。 PDA でも 3D アクセラレータが使えるハードとして Axim X51v 等があるようす。 (しかも Axim は PowerVR )
残念ながら ZERO3 はアクセラレータ無しですが Direct3D は動きますので実験してみます。
以前 MI Zaurus で 簡単な 3D Engine を作成したことがあります。
6年以上も前なので、
さすがにハードウエアは
30〜60MHz 程度の CPU (SH3) に 16bit bus でした。
bus が弱いせいでかなりメモリに足を引っ張られます。
とても QVGA 320x240 pixel を全部転送していては
処理が間に合いません。
そのため bus 速度から逆算し、 1/30 sec (30fps) でおおよそ 5 回分の 画面転送を稼げるように レンダリング領域を 160x160 pixel に制限しました。
5回といっても読み込みと書き込みですでに2回 Bus を通るので ぎりぎりの数値であることがわかります。
実際はポリゴンの重なりもあるし、 プログラムコードなど描画以外のメモリアクセスも必要です。
また上記のリストからわかるように、 30fps を死守するためには Z-Buffer へアクセスする余裕もありません。 アプリケーションはできるポリゴンが限り重ならないように作って Z sort を使います。
逆に CPU は bus に足をとられて待っている状態なので 演算には余裕があります。 できるだけテクスチャを使わずに、ライティングやグーロー等の シェーディング計算をして pixel を描いた方が バスアクセスが少ないので高速でした。
また当時作った 2D ゲームのキャラクタが、 できる限り穴あき (テクスチャの抜き) でデザインされていたのも バスアクセスを減らすためでした。
初代 iPAQ は StrongARM の 206MHz です。 噂に違わず、移植した 3D Engine とゲーム (ChiRaKS PocketPC) は SH3 の MI Zaurus と比較にならないほど高速に動いてくれました。
このゲームは MI Zaurus 版のベタ移植で 高速化等の工夫もまじめにやってないないのに 100fps を余裕で越えてしまいます。 30fps 制限のウエイトを入れなければゲームになりませんでした。 320x240 : 160x160 = 3 : 1 なので、 フルスクリーンでも十分稼動したでしょう。
そういえば Direct3D が登場した 1996 年頃の PC は Pentium 133〜166MHz でした。Mono の Ramp Driver だけど CPU でもそこそこ動きました。
W-ZERO3 や Axim 等 今の PDA は StrongARM 後継の XScale で 416〜624MHz あります。 FPU は無いけれど、 XScale の Wireless MMX 命令も駆使すれば Software のみでもそこそこパフォーマンスが出るかもしれません。 さすがに解像度 640x480 でのレンダリングは厳しいかもしれないですが。
Direct3D Mobile の API set は非常に見慣れたものです。 DirectX8 / X9 世代の Direct3D を使ったことがあれば API を見ただけで意味がわかるでしょう。 ただし Shader はなく固定機能命令のみとなっています。 D3D8 base らしいですが Shader が無ければ DirectX8 と 9 の違いはそれほど大きくないはずです。
Desktop PC の DirectX SDK ではもう DirectX10 の preview が 始まっておりすぐ目前に迫っているわけですが、 DirectX9 なら相互で動くように lib 化して作っておくことも可能でしょう。
また D3DX 相当の Utility Library として D3DMX もあります。 こちらは必ずしも D3DX と互換性があるわけではなく、 数値演算と Texture 読み込みのヘルパーになっているようです。
Mobile らしい特徴として固定小数演算のサポートがあります。
固定小数演算は 32bit の 16.16 形式で D3DMVALUE 型に 32bit int 相当として格納します。
また同じように D3DMVALUE 型には 32bit の浮動小数値 (float型) の bit image を格納することも可能です。 これは sizeof(float) == sizeof(_int32) が前提となっていて、 Desktop PC の Direct3D で SetRenderState() に float を DWORD 型で渡す場合と同等です。
D3DMVALUE が固定小数なのか浮動小数なのかどこで区別するのか不思議ですが、 なんと Direct3DMobilieDevice の API には 型を指定する引数が追加されています。 例えば次のような指定になります。
IDirect3DMobileDevice::SetTransform( D3DMTS_VIEW, &viewMatrix, D3DMFMT_D3DMVALUE_FIXED ); |
3番目の引数が D3DMFMT_D3DMVALUE_FIXED だったり D3DMFMT_D3DMVALUE_FLOAT になったりするわけです。
PDA や携帯など Mobile デバイスで使われることが多い ARM 系や SH3 系の CPU は FPU が無いケースが多いので CPU で演算する場合は D3DMFMT_D3DMVALUE_FIXED の方が都合が良いでしょう。 その方が高速に演算できます。 (GA 3D Engine も 16.16 固定小数演算を使っていました)
だけど搭載している 3D アクセラレータの方が 最初から浮動小数演演算を行っている可能性があるので、 デバイスに値を渡すときに変換が入るかもしれません。
逆に MIPS 系や SH4 のように FPU を持っていたとしても、 3D アクセラレータ側が固定小数演算を行っている可能性もあります。 この場合も Driver に値を渡した後に 固定小数への変換が発生します。
そのためアプリケーション側で CPU 演算せずに そのままドライバに渡す頂点データなどは、 CPU ではなく Driver のフォーマットにあわせて 用意することになるでしょう。
Device がどちらの format で処理しているのかは D3DMDEVCAPS の DevCaps を調べるとわかります。 D3DMDEVCAPS_NATIVEFLOAT の bit が立っていれば Float を受け付けるハードウエアです。
DirectDraw はすでに Desktop PC の最新版 DirectX では 存在しておらず、完全に D3D に統合されています。
ただし上位互換性は保たれており、 DirectX9 が動作する現在の PC 及び OS でも DirectX8 以前のアプリケーションがそのまま動作します。 そのため DirectX6 や DirectX7 の API を呼び出して 描画することもできます。 もちろん DirectDraw を利用することもできます。
同じように、DirectX Mobile でも DirectX6 と互換性がある 描画 API として DirectDraw が搭載されているようです。 ( IDirectDraw4/IDirectDrawSurface5 )
機能的には Direct3D Mobile と重なる部分も多いですが 3D アクセラレータが乗っていないけど 2D ハードウエアのアクセラレータが存在する場合に FullScreen や flipping を使いたいとか、 ゲームなどの移植しやすさの点でメリットがあると考えられます。
以前の WindowsCE でゲームの描画に使われていた GAPI は、 VRAM の Lock による CPU からの直接アクセスをサポートしたものでした。 CPU が読み書きするために必要な Pixel Format や VRAM の並び順が情報として与えられ、 それを元に CPU が直接読み書きをしています。 必要最低限でわかりやすいですが、 blt 等の描画転送アクセラレータがあっても 活用していないことになります。
実際に W-ZERO3 の DeviceCaps 値を調べてみました。
意外なことに W-ZERO3 も NATIVEFLOAT でした。
このリストは こちら にアップした d3dmcaps.exe で 作成出力することができます。
[メニューに戻る] | [ZAURUS総合] | [Direct3D] | [Ko-Window] | [Win32] | [WinCE] | [携帯電話] | [その他] |
フルパワー全開 | Hyperでんち |