« レンダーレスモード | メイン | コメントRSSファイル »

2005年12月26日

吉里吉里 ムービー拡張日誌2:: メニューが出ない

    

ヘルプを見てレンダーレスモードを実装するも、書かれている通りに動かない。
違うメソッドがコールされて初期化が進まない。
いろいろと試すが良くわからず、ふとサンプルがあるのではないかと見てみたらあった。
するとDirect3Dの初期化のタイミングやネゴシエーション用のメソッドの呼び出すタイミングが違う・・・・・・
ヘルプでは
IVMRSurfaceAllocator9::InitializeDevice
InitializeDevice メソッドは、Direct3D デバイスを初期化する。
とか書いているのに、サンプルではこの中でDirect3D デバイスの初期化なんてやってない。
Direct3D デバイスの初期化はコンストラクタの中でやっていた。
それはともかく、サンプルを参考に実装したら動くようになったのだが絵が出ない。
いろいろと悩んで、ふとIDirect3DDevice9::Clearを呼ばないようにしたら絵が出るようになった。

最初は次のように呼び出していた。
IDirect3DDevice9::Clear
IDirect3DDevice9::BeginScene
IDirect3DDevice9::StretchRect VMRでレンダリングされた画像をバックバッファ絵コピー
IDirect3DDevice9::EndScene
IDirect3DDevice9::Present

Clearでバックバッファをクリアして、StretchRectでバックバッファへコピーしているはずなのに絵が出ない。
VMRのレンダリング対象がバックバッファになっているのかとも思ったが、そうでもないようだ。
なぜClearを呼ばなければ絵が出るのかあれこれ考えていて思い出した。
3D関連のコマンドはキューにためられて一気に実行される。
これはビデオカードとドライバの作りによるが、大体のビデオカードはそうなっていると聞いたことがある。
つまり、2Dのコマンドとは実行タイミングが違うために描画された後に消してしまっていた可能性がある。
まあ、これらは推測でしかないが。
でも、バックバッファの全面にビデオを描画するのでClearは必要ない。
と言うか、ない方が速い。

これで、うまく絵が出るようになり、リセットや初期化を直したりしてフルスクリーンとウィンドウを何度切り替えてもうまく動くようになった。
が、フルスクリーン時にメニューが出ない。
正確に言えばちらちらと出ている。
どうも、ビデオの画像に毎回消されているようだ。
Zオーダーをいじったりいろいろとやってみるが、よくわからず。
諦めかけていたが、ふと思った。
フルスクリーンって何? と。そしてそこからいろいろと考えていて思った。
レンダーレスモードのアロケーターとイメージプレゼンターでは、フルスクリーンモードの時は、DirectXをフルスクリーンモードで初期化している。
吉里吉里側もフルスクリーンモードに切り替えている。
競合するのではないか?
そもそもVMR側はフルスクリーンモードで初期化する必要があるのだろうか?
子ウィンドを使って、ウィンドウモードで初期化しても描画できるのではないか?
と思い至り、フルスクリーンモードをやめて、ウィンドウモードで初期化するようにした。
うまくいった。
フルスクリーン時でもメニューが表示される。

後はデバイスの能力を取得して出来るだけ多くの環境に対応できるようにするのと、エラー発生時にうまく対処するようにして、より安定するようにしていくのみ。
もう少しでVMR&WMVは出来そうだな。



投稿者 Takenori : 2005年12月26日 07:47



コメント

IDirect3DDevice9::Clear
IDirect3DDevice9::BeginScene
IDirect3DDevice9::StretchRect
IDirect3DDevice9::EndScene
IDirect3DDevice9::Present
上記の流れでビデオの再生をフルスクリーンで行うと、
ビデオ再生画面の裏にすべてのウィンドウが隠れてしまい、全く表に
出てこない状態になってしまいます。

フルスクリーンでメニューが出せたとのことですが、
具体的にどのようなコードを記述したのか、具体的にご教授
いただければ幸いです。

投稿者 迷い : 2006年10月24日 12:23

迷いさん、こんばんは。

本文にもありますが、メニューの出る出ないは描画メソッドの呼び出し順とは関係ないようです。
問題は、DirectXの初期化とウィンドウ関係です。
基本的には以下のようにすれば表示できたと記憶しています。

VMRはレンダーレスモード
メインウィンドウのクライアント領域を覆うように子ウィンドウを作る
その子ウィンドウを描画対象とするようにDirect3Dをウィンドウモードで初期化
バックバッファのサイズはビデオのサイズに合わせる
ビデオの描画対象のバックバッファにはこのDirect3D Deviceから得たものを使う
フルスクリーンの切り替えは、メインウィンドウを使って別のDirect3D(吉里吉里ではDirect Draw)で初期化して行う

メインウィンドウのサイズが変わったら子ウィンドウのサイズも変えたり、リセット時には子ウィンドウを再生成する必要があったと思います。
その他細かい部分は去年のことなので忘れてしまいました。

なお、吉里吉里2のソースコードは公開されているので、ソースコードはそちらを参照してください。

それでは。

投稿者 Takenori : 2006年10月30日 20:07


comments powered by Disqus
Total : Today : Yesterday : なかのひと