現在VC++6.0でMFCのSDIを独学修行中です。
BMPファイルをfileダイアログを使用して、読み込んでOnDrawで表示すると、
再描画する際に画面がチカチカする現象がおきてしまいます。
一度別メモリに書き込んで一度に描画するようにしたのですが
その方法はうまくいきませんでした・・・・。
もしかして、原因は描画を行うタイミングにあるのでしょうか?
描画が行われていない、Vブランク期間のタイミングで描画を行えるように
しようと思ったのですがやり方がまったく分からなくて困っています。
描画をVブランクのタイミングで行い、全体の処理を60/1フレームで行えるように
するにはどうしたらよいのでしょうか?
どなたかご存知の方がいらっしゃったら、どうかよろしくお願いします。
また、他の良い方法を知っている方がいらっしゃったらご教授ください。
>描画をVブランクのタイミングで行い、全体の処理を60/1フレームで行えるように
>するにはどうしたらよいのでしょうか?
DirectXを使うしかないんじゃないかな・・・。
他に方法があるなら俺も知りたいです。
再描画を行う際にC***View::Invalidate(BOOL bErase)を呼んで
再描画すると背景を一度消去するかどうかをbEraseで制御する
ことができます。
Invalidate(FALSE)で再描画するとちらつきを防止できると思い
ますよ。
>もしかして、原因は描画を行うタイミングにあるのでしょうか?
それもありますが、今回の場合はそれ以前の問題のようです。
(1) まず、CWnd::OnEraseBkgnd()をオーバーライドし、FALSEを返してみて下さい。
あとこれに関する仕様を読んでみて下さい。
>一度別メモリに書き込んで一度に描画するようにしたのですが
>その方法はうまくいきませんでした・・・・。
正しくやれば必ず成功します。
ちなみに微塵もティアリングを起こさせない事は不可能です。
DirectXのWindowモードで垂直帰線待機付きの描画も同様です。
( 念の為の確認ですが、この方法は
メモリDC(裏画面)に1フレームの絵に必要な全描画を行い、
それが終わった後に通常DCにブリットしている訳ですよね? )
(2) >描画が行われていない、Vブランク期間のタイミングで描画を行えるように
>しようと思ったのですがやり方がまったく分からなくて困っています。
(1)で期待通りの結果が得られるはずですので不要だと思います。
がどうしてもやりたいという時の為にお話致します。
DirectX7以前のIDirectDraw?::WaitForVerticalBlank()が役に立つでしょう。
これは「垂直帰線を待機する」だけを行います。
DirectX8以降ではその機能は用意されていません。フリッピング機能と統合しています。
>描画をVブランクのタイミングで行い、全体の処理を60/1フレームで行えるように
>するにはどうしたらよいのでしょうか?
GDIでやるなら上記機能が使えるでしょう。
DirectX GraphicsならIDirect3DDevice?::Preset()と
IDirect3D?::CreateDevice()の解説を参照して下さい。
>Invalidate(FALSE)で再描画するとちらつきを防止できると思いますよ。
前述(1)の方法でないと完全な阻止は難しいです。
自分が再描画指令を出す時はこれでOKです。が、再描画指令はWindowsも行います。
私が知る限り、(1)は再描画時のあらゆる背景消去を潰せる方法です。
もう一度メモリDCにすべての描画を行ってから、通常DCに
転送する処理を作ってみたところ、ほとんどチラつかなくなりました。
前の処理はどこか正常に動作していないところがあったようです。
すいません・・(^ ^ );
これからもっと修行して早く上達できるようになりたいです。
皆さんご教授ありがとうございました。