トップページ > 記事閲覧
WaitVSyncの仕様について
名前:homu 日時: 2015/09/05 12:10

WaitVSync関数を用いた垂直同期についての質問です。 SetWaitVSyncFlag(FALSE); を実行して, 描画の際には WaitVSync(1); ScreenFlip(); という手順を踏んでいるのですが, 画面がカクついてしまいます。 SetWaitVSyncFlag(TRUE); の場合と, 上のような場合では, どのような違いがあるのでしょうか? DxLib_Init の後でも垂直同期信号を待つかどうかを変更する必要が出てきたので, 以下のページを参考にしました。 ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=1445 ここではこの方法を用いると一部の環境では上手く動作しないとありますが, "グラフィックスに弱い環境" と書いてあったので, 何か別の原因があるのではないかと思っています。 グラフィックボードは, nVIDIA の GeForce GTX 580 を使用しています。 以下のコードでも, SetWaitVSyncFlag関数を使用するときに TRUEにするかFALSEにするかでカクつき具合がかなり変わりました。 FALSEにすると右に動く線が時々引っかかるようなイメージです。 int tmpx = 0; while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { if (GetWindowUserCloseFlag(TRUE)) break; ClearDrawScreen(); tmpx = (tmpx+2)%640; DrawBox(tmpx, 0, tmpx+30, 480, GetColor(255, 0, 0), 1); WaitVSync(1); ScreenFlip(); } このコードでは確認出来ませんでしたが, 実際に作ろうとしているプログラムでは, WaitVSync(1); を ScreenFlip(); の後に書くことで カクつきは軽減 (もしくは無くなっている?) されているように感じました。 よろしくお願いします。
メンテ

Page: 1 |

Re: WaitVSyncの仕様について ( No.1 )
名前:管理人 日時:2015/09/03 01:07

> SetWaitVSyncFlag(TRUE); > の場合と, 上のような場合では, どのような違いがあるのでしょうか? SetWaitVSyncFlag(TRUE); の場合は、垂直同期を待ってから裏画面の内容を表画面に転送する という一連の処理を Direct3D が一括で行います 対して WaitVSync(1); ScreenFlip(); の場合は Direct3D を使用しているプログラム側が 垂直同期を待つ処理と裏画面の内容を表画面に転送する処理をバラバラに行います Direct3D は別のスレッドで( 非同期で )動作しているので、WaitVSync(1); の実行が終わり 垂直同期が来た直後に ScreenFlip(); を実行しても、垂直同期というシビアなタイミングの間に 裏画面から表画面への転送が行われない可能性があり、それが画面がカクつく原因になっています なので、「垂直同期を待ってから裏画面の内容を表画面に転送する」という一連の処理を Direct3D 側で行う場合のように正確なカクつきの無い転送ができない状態になっています WaitVSync(1); を ScreenFlip(); の後に書くことでカクつきが軽減されるのは、 WaitVSync(1); を ScreenFlip(); の前に書いた場合は毎フレーム確実に「垂直同期の間での 裏画面から表画面への転送が間に合った」「間に合わなかった」という微妙なタイミングでの 転送処理が発生せず、安定して垂直同期が始まる前のタイミングで裏画面から表画面への 転送が行われるので、結果的に動作が安定しているように見えるのだと思います Windows環境は垂直同期の処理のようなマイクロ秒〜数ミリ秒レベルで制御したい処理は大抵大雑把にしか 制御できないので( 無理矢理精密に制御しようとすると、多くの場合OSのバージョンが変わったり グラフィックカードが変わったりすると正常に動作しなくなります・・・ )、本件でも ScreenFlip(); の前に WaitVSync(1); を実行するのが一番良い選択だと思います
メンテ
Re: WaitVSyncの仕様について ( No.2 )
名前:homu 日時:2015/09/03 16:33

回答ありがとうございます。 このままの仕様だとあまり安定させられそうにないので, SetWaitVSyncFlag(TRUE); は前提として, 描画方法を改善してみようと思います。 > WaitVSync(1); を ScreenFlip(); の前に書いた場合は毎フレーム確実に「垂直同期の間での > 裏画面から表画面への転送が間に合った」「間に合わなかった」という微妙なタイミングでの > 転送処理が発生せず、安定して垂直同期が始まる前のタイミングで裏画面から表画面への > 転送が行われるので、結果的に動作が安定しているように見えるのだと思います 前に書いた場合に安定する ということは, やはり後に書いた場合に安定したように感じるのは 気のせいということなのでしょうか...?
メンテ
Re: WaitVSyncの仕様について ( No.3 )
名前:管理人 日時:2015/09/03 23:34

すみません、「後」と書くべきところが「前」になっていました、正しくは -------------------- WaitVSync(1); を ScreenFlip(); の後に書くことでカクつきが軽減されるのは、 WaitVSync(1); を ScreenFlip(); の後に書いた場合は毎フレーム確実に「垂直同期の間での 裏画面から表画面への転送が間に合った」「間に合わなかった」という微妙なタイミングでの 転送処理が発生せず、安定して垂直同期が始まる前のタイミングで裏画面から表画面への 転送が行われるので、結果的に動作が安定しているように見えるのだと思います -------------------- となります m(_ _;m
メンテ
Re: WaitVSyncの仕様について ( No.4 )
名前:homu 日時:2015/09/04 00:58

何度もすみませんが, > ScreenFlip(); の前に WaitVSync(1); を実行するのが一番良い選択だと思います これも, 後に実行する方が良いということですか?
メンテ
Re: WaitVSyncの仕様について ( No.5 )
名前:管理人 日時:2015/09/04 02:02

> > ScreenFlip(); の前に WaitVSync(1); を実行するのが一番良い選択だと思います > > これも, 後に実行する方が良いということですか? その通りです orz 間違いだらけで申し訳ありません
メンテ
Re: WaitVSyncの仕様について ( No.6 )
名前:homu(解決) 日時:2015/09/05 13:12

そうなのですね。スッキリしました。 ありがとうございます。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存