DirextX 7 SDK (つまり、コードの使用 LPDIRECTDRAWSURFACE7
など) に対してプログラムされ、フルスクリーンで実行されるソフトウェアがあります。主なタスクは、信頼できる方法で外部トリガーに応答して画面に何かを配置することです。これは、Windows XP で非常にうまく動作します。基本的に、ソフトウェアは何らかのトリガーを待ち、トリガーされると、新しいフレームを作成し、それをバックバッファーに入れ、DX にバッファーを反転するように指示します。その結果、トリガーからフレームが効果的に画面に表示されるまでのおおよその遅延は、ビデオ カードとドライバーによって異なりますが、60Hz 画面では 3 フレームまたは 50 ミリ秒です。これは、すべて NVidia カードを実行しているさまざまなシステムでテストされています。ハイエンドのカードを搭載した一部のシステムでは、2 つのフレームを取得することさえあります。
ただし、Windows 7 で同じソフトウェアを実行すると (他のソフトウェアがまったくインストールされていない場合)、5 フレーム未満になることはありません。パイプラインのどこかで、OS またはドライバー、またはその両方が 2 つの余分なフレームを消費することを意味します。これは、アプリケーションにとってほとんど受け入れられません。Aero/デスクトップ コンポジション/別のドライバー バージョン/別のビデオ カードを無効にしようとしましたが、役に立ちませんでした。
- これはどこから来たのですか?これはどこかに文書化されていますか?
- 簡単に修正する方法はありますか?DirectX 7 が古いことは知っていますが、より新しいバージョンに再度コンパイルするためのアップグレードは膨大な作業になる可能性があるため、別の種類の修正が必要です。コードで設定できるフラグでしょうか?
関連すると思われるコードをいくつか編集します。
表面/裏面の作成:
ddraw7->SetCooperativeLevel( GetSafeHwnd(),
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED )
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof( desc );
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE |
DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
desc.dwBackBufferCount = 1;
ddraw7->CreateSurface( &desc, &primsurf, 0 )
DDSCAPS2 surfcaps;
ZeroMemory( &surfcaps,sizeof( surfcaps ) );
surfcaps.dwCaps = DDSCAPS_BACKBUFFER;
primsurf->GetAttachedSurface( &surfcaps, &backsurf );
描画される前にフレームをレンダリングするために使用されるサーフェスの作成:
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
desc.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT );
desc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
LPDIRECTDRAWSURFACE7 surf;
HRESULT r=ddraw7->CreateSurface( &desc, &surf, 0 )
レンダリング ループOnIdle
:
//clear surface
DDBLTFX bltfx;
ZeroMemory( &bltfx, sizeof(bltfx) );
bltfx.dwSize = sizeof( bltfx );
bltfx.dwFillColor = RGBtoPixel( r, g, b );
backsurf->Blt( rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx )
//blit some prerendered surface onto it, x/y/rect etc are calculated properly)
backsurf->BltFast( x, y, sourceSurf, s&sourceRect, DDBLTFAST_WAIT );
primsurf->Flip( 0, DDFLIP_WAIT )
primsurf->Blt(&drect,backsurf,&srect,DDBLT_WAIT,0);