Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

DXライブラリのSetWaitVSyncFlag、いつ使うの?こういう時でしょ!

More than 1 year has passed since last update.

メリークリスマス!そしてハッピーバースデー私!was-blue.0793ことSeiten Minagawaです。
僭越ながら私が令和元年、2019年のDxLib Advent Calendarを主催してみましたが、今年のDxLib Advent Calendarはいかがだったでしょうか?
今回のDxLib Advent Calendarのラストはあまり知られていない関数、SetWaitVSyncFlag関数について考えてみる記事で締めくくろうと思います。

まえがき

垂直同期を待つかどうかを設定するための関数、SetWaitVSyncFlag。
今回はこの「SetWaitVSyncFlag」で垂直同期を切るべき場面を考えてみました。

そもそも垂直同期とは?

簡単に言えば、モニターへの描画が完了するまで処理全体を停止し、描画処理と更新処理の間隔を双方一定となるように処理の間隔を調整することです。
例えば、60FPSでしか描画できないのに1000FPSで描画処理・更新処理を行ってしまうと、描画が追いつかず問題になることがありました。
"ありました"と過去形なのは、筆者が制作した垂直同期を切るようにしているアプリをいくつかの環境で使ってみても、描画関連の問題が起きたことがなく、むしろ一部のゲームの記事では垂直同期を切ることを推奨している記事が見受けられたためです。

垂直同期を切るべき場面

音楽ゲーム

音楽ゲームは一般的に正しいタイミングの時間が使用されます。
そうなった時、60FPSの型にはめてしまうと1フレーム単位、つまり1/60秒(16ms)単位でしか判定できず、1ms、またはそれ以上で精度を判定したい場合に都合が悪いです。(特にいわゆる"キー音"があるゲームでは)
そんな時は、垂直同期を切って16msより速い間隔で判定するようにするべきです。
懸念されるのはティアリングですが、近年のモニターでそのような問題が発生するケースはほぼないと考えています。

絶対に特定のFPSで動かしたいゲーム

例えば格闘ゲームは、1/60秒単位で同時押しやコマンド入力の受付時間を設定しているケースが多いです。
「ゲームは絶対に60FPSで動く!」と思いがちですが、実はこのFPSは環境依存です。
これを環境依存せずに絶対に特定のFPSで動かしたい場合は、垂直同期を切り自前のFPS制御を行うことになります。

fps.cpp
const int refrashtime = 1000 / 60;
int sectiontime = GetNowCount();
while (ProcessMessage() == 0)
{
    if (GetNowCount() - sectiontime >= refrashtime)
    {
        sectiontime = GetNowCount();
        Update();
        Draw();
    }
}

SetWaitVSyncFlagの注意点

SetWaitVSyncFlag関数は、Windows版ではDirectXとの兼ね合いでDxLib_Initを呼ぶ前にしか使えません。
Android版では、DxLib_Init関数を呼んだ後でもSetWaitVSyncFlagで垂直同期を切るか切らないかを動的に切り替えることができますが、Windows版でも動的に垂直同期を切り替えたい場合は、以下のようにします。
(コードを平易にするためグローバル変数を使用していますが、一般的にはクラス変数などに閉じ込めて管理するようにします)

vsync.cpp
//垂直同期を切るかどうか切り替えるグローバル変数
bool vsyncflag;

while (ProcessMessage() == 0)
{
    if (vsyncflag) WaitVSync(1);
    Update();
    Draw();
}

コードのライセンスについて

Apache License 2.0にします。著作権者名は「Seiten Minagawa」としてください。

Seiten_Minagawa
所属組織は私主宰の同人サークルの名前です。 C++メインにJava、VB.NET、C#、JavaScriptをやります。 もう1つの顔は一次創作作家。アイコンのキャラも創作キャラです。 実はwas-blue.0793の中の人。 アイコンは卯月凪沙さん。
https://aquamarinesky.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away