トップページ > 記事閲覧
フルスクリーン時のちらつきについて
名前:とらきす 日時: 2017/06/25 15:05

1920x1080, 60Hzのモニタにフルスクリーンで描画をすると、インターレース表示のようなちらつきが生じます。(縦方向にブレているといった印象です) いわゆる裏画面描画はきちんと実装できている筈で、事実、同様のソースでChangeWindowMode(true)を実行すると綺麗に描画されるのですが… SetGraphModeの解像度を大きくする程、ちらつきも激しくなるように見えます。 なにか、原因はあるのでしょうか?それとも、こちらの環境下のみの現象なのでしょうか? 拙いコードかとは思いますが、なにかマズそうな実装がありましたら、教えていただけませんでしょうか。 ちなみに、dixq様のサイトよりfps固定の処理を引っ張ってきています。 //main.cpp #include "DxLib.h" #include "data_sys.hpp" #include "mngr_fps.hpp" #include "mngr_input.hpp" int WINAPI WinMain(_In_ HINSTANCE hInsatnce, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { SetOutApplicationLogValidFlag(false); SetFullScreenResolutionMode(DX_FSRESOLUTIONMODE_DESKTOP); SetFullScreenScalingMode(DX_FSSCALINGMODE_NEAREST); SetFullSceneAntiAliasingMode(0, 0); SetWaitVSyncFlag(false); SetMainWindowText("DxLib"); SetWindowSizeChangeEnableFlag(false); SetWindowSizeExtendRate(1.0); SetAlwaysRunFlag(true); SetMouseDispFlag(true); ChangeWindowMode(true); SetGraphMode(1920, 1080, 32); if (DxLib_Init() == -1) { return -1; } SetDrawScreen(DX_SCREEN_BACK); class Fps fps; class Keyboard key; class Mouse mouse; class Joypad joy; while (1) { if (ProcessMessage() != 0) { break; } ClearDrawScreen(); fps.Avg(); key.Update(); mouse.Update(); joy.Update(); fps.Draw(); //ここに処理を書く ScreenFlip(); fps.Wait(); } DxLib_End(); return 0; } //mngr_fps.hpp #pragma once //fpsの管理 class Fps { private: int timeStart; //fps算出開始時の時間 unsigned char countFlip; //再描画された回数 double timeFps; //算出されたfps public: Fps(); void Avg(); //fpsの平均を算出 void Draw(); //fpsを描画(暫定) void Wait(); //指定したfpsになるよう処理を待機 }; //mngr_fps.cpp #include "DxLib.h" #include "data_sys.hpp" #include "mngr_fps.hpp" Fps::Fps() { timeStart = 0; countFlip = 0; timeFps = 0; } void Fps::Avg() { if (countFlip == 0) { timeStart = GetNowCount(); } if (countFlip == CONST_FPS_VALUE) { int a = GetNowCount(); timeFps = 1000.f / ((a - timeStart) / CONST_FPS_VALUE); timeStart = a; countFlip = 0; } countFlip++; } void Fps::Draw() { DrawFormatString(0, 0, GetColor(255, 255, 255), "%.1f", timeFps); } void Fps::Wait() { int a = countFlip * 1000 / static_cast<int>(CONST_FPS_VALUE) - (GetNowCount() - timeStart); if (a > 0) { Sleep(a); } }
メンテ

Page: 1 |

Re: フルスクリーン時のちらつきについて ( No.1 )
名前:おにぎり 日時:2017/06/25 19:49

ScreenFlipの前にVsync待ち(fps.Wait())が無いといけない気がしますが、 どうでしょうか。
メンテ
Re: フルスクリーン時のちらつきについて ( No.2 )
名前:おにぎり 日時:2017/06/25 19:50

それと、 これもtrueにしておいた方がいいような気がします SetWaitVSyncFlag(false);
メンテ
Re: フルスクリーン時のちらつきについて ( No.3 )
名前:とらきす 日時:2017/06/25 20:34

>>ScreenFlipの前にVsync待ち(fps.Wait())が無いといけない気がしますが、 どうでしょうか。 これは…どうなのでしょう。試してみたところ、描画結果に大きな違いはないようでした。 dixq様のサイトや管理人様HPのサンプルプログラムの方ではwaitの方が先でしたので、そちらに合わせた次第です。 >>それと、 これもtrueにしておいた方がいいような気がします SetWaitVSyncFlag(false); こちらに関しては、fpsが、falseだと60.0固定、trueだと59.0固定という結果になりました。この1の差は何…? SetWaitVSyncFlagと自前(バリバリ流用ですが)で実装したfps管理部分の役割が競合しているように思えたのでfalseにしていたのですが…うーん、わかりません とりあえず、ご指摘頂いた箇所の変更による改善は見られませんでした… スペックは十分足りているはずですし…
メンテ
Re: フルスクリーン時のちらつきについて ( No.4 )
名前:管理人 日時:2017/06/25 21:28

> インターレース表示のようなちらつきが生じます。(縦方向にブレているといった印象です) こちらの現象は「テアリング」若しくは「ティアリング」と言って、モニタの更新タイミング( 垂直同期( V-SYNC ) )を無視して 画面処理を行った際に発生する現象で、DXライブラリを使用した場合は SetWaitVSyncFlag( FALSE ) ; を実行すると 垂直同期を無視した画面処理を行うことになるので、この「テアリング」が発生します DxLib_Init の呼び出し前に実行している SetWaitVSyncFlag(false); こちらの false を true に変更することでテアリングは発生しなくなるはずですが、もしそれでも発生するとのことでしたら、 環境に依存した原因かもしれません… ( ところで載せていただいたコードでは ChangeWindowMode(true); が記述されていますが、こちらは実際のコードでは無いと 考えて良いのですよね? ) > 事実、同様のソースでChangeWindowMode(true)を実行すると綺麗に描画されるのですが… ウィンドウモードの場合は、モニタの更新タイミングが無視されるかどうかは OS 次第なので、ウィンドウモードの場合は SetWaitVSyncFlag の設定に関係なく、Windows Aero が ON の場合は垂直同期が考慮され、Windows Aero が OFF の場合は垂直同期が無視されます 意図的に Aero を OFF にしない限りは Windows7 以降は Aero が ON の状態なので、SetWaitVSyncFlag( FALSE ) ; を実行していても ウィンドウモードではテアリングが発生しないのは OS が垂直同期を考慮した画面処理を行っているからだと思います
メンテ

Page: 1 |

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

   クッキー保存