SetWaitVSyncFlag(FALSE); にすると、DWM が無い環境で画面がティアリングする。
WaitVSync(1); を直前・直後に実行して、どちでも微妙にズレる。
でも DwmFlush(); の代わりに WaitVSync(1) を使うのは盲点だった。
自分のコードにも使っているにも関わらず、思考が Win32 API から放ってない…反省。
いろいろ試した結果:(VSyncFlag = TRUE の場合 ScreenFlip() 掛かる時間 )
DX_DIRECT3D_9
Window: ~16 ms / Window (DWM OFF): ~16 ms / Fullscreen: ~16 ms
DX_DIRECT3D_9EX
Window: ~16 ms / Window (DWM OFF): ~16 ms / Fullscreen: ~16 ms
DX_DIRECT3D_11
Window: < 1 ms / Window (DWM OFF): ~16 ms / Fullscreen: < 1 ms
DX_DIRECT3D_NONE を設定しても効果が無い( GetUseDirect3DVersion() は 1 を返す)
つまり DX_DIRECT3D_11 使う場合、DWM OFF のウインドウモード以外自力で待つ必要がある( WaitVSync(1); で十分 )
これは自分の PC (Windows 7 x64, Intel HD4000)だけの現象なのか分からない…テストプログラムをここで貼ります:
ーーーーーーーーーー
using System;
using System.Diagnostics;
using DxLibDLL;
namespace DXLib_FlipScreen_Test
{
class NOWIN32API
{
private volatile static bool FullScreen = false;
static void Main(string[] args)
{
DX.SetUseDirect3DVersion(DX.DX_DIRECT3D_11);
DX.GetDefaultState(
out int desktop_width, out int desktop_height,
out int desktop_color, out int desktop_refresh,
out int desktop_top_x, out int desktop_top_y,
out int desktop_pixel_w, out int desktop_pixel_h);
int game_width;
int game_height;
if (FullScreen) {
game_width = desktop_width;
game_height = desktop_height;
} else {
game_width = 320;
game_height = 240;
DX.ChangeWindowMode(DX.TRUE);
}
DX.SetGraphMode(game_width, game_height, desktop_color);
DX.SetAlwaysRunFlag(DX.TRUE);
DX.DxLib_Init();
Console.WriteLine($"DX Version: {(DXVER)DX.GetUseDirect3DVersion()}");
DX.DrawString(10, 10, "Press [Enter] to start testing.", DX.GetColor(255, 255, 255));
DX.DrawString(10, 30, "Press [Esc] during test to stop.", DX.GetColor(255, 255, 255));
DX.WaitKey();
DX.SetDrawScreen(DX.DX_SCREEN_BACK);
uint frame_counter = 0;
DX.WaitVSync(1);
long time_beginning = Stopwatch.GetTimestamp();
while (DX.ProcessMessage() == 0) {
frame_counter++;
// DRAW SOMETHING
DX.ClearDrawScreen();
int line_width = 32;
int speed = 3;
int x = (int)(frame_counter) % ((game_width + line_width) / speed);
DX.DrawBox(x * speed - line_width, 0, x * speed, game_height, DX.GetColor(255, 255, 255), DX.TRUE);
// END DRAW SOMETHING
long time_flip_begin = Stopwatch.GetTimestamp();
DX.ScreenFlip();
long time_flip_end = Stopwatch.GetTimestamp();
long time_flip_took = time_flip_end - time_flip_begin;
long time_vsync_begin = Stopwatch.GetTimestamp();
DX.WaitVSync(1);
long time_vsync_end = Stopwatch.GetTimestamp();
long time_vsync_took = time_vsync_end - time_vsync_begin;
Console.WriteLine($"Frame #{frame_counter:00} / Flip: {1000.0 * time_flip_took / Stopwatch.Frequency:00.00} ms / Wait: {1000.0 * time_vsync_took / Stopwatch.Frequency:00.00} ms");
if (DX.CheckHitKey(DX.KEY_INPUT_ESCAPE) == DX.TRUE || frame_counter == 600) {
long time_total = time_vsync_end - time_beginning;
Console.WriteLine($"Time total: {1000.0 * time_total / Stopwatch.Frequency} ms");
break;
}
}
DX.DxLib_End();
Console.ReadLine();
}
private enum DXVER : int
{
DX_DIRECT3D_9 = DX.DX_DIRECT3D_9,
DX_DIRECT3D_9EX = DX.DX_DIRECT3D_9EX,
DX_DIRECT3D_11 = DX.DX_DIRECT3D_11,
}
}
}
ーーーーーーーーーー