2

スクリーンショットを撮る最速の方法を見つけようとしています。これまでのところ、GDI または DirectX のいずれかを使用できることがわかりました。GDI を使用すると 35 ミリ秒で画面をキャプチャできますが、DirectX フロント バッファを使用すると平均 73 ミリ秒かかります。これよりもさらに高速な方法が必要です。この目的には、DirectX でバック バッファーをキャプチャするのが良い方法のようです。私は同じことをするために次のコードを使用しています:

    D3DDISPLAYMODE  ddm;
    D3DPRESENT_PARAMETERS   d3dpp;

    if((g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))==NULL)
    {
        ErrorMessage("Unable to Create Direct3D ");
        return E_FAIL;
    }

    if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm)))
    {
        ErrorMessage("Unable to Get Adapter Display Mode");
        return E_FAIL;
    }

    ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));

    d3dpp.Windowed=WINDOW_MODE;
    d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    d3dpp.BackBufferFormat=ddm.Format;
    d3dpp.BackBufferHeight=nDisplayHeight=gScreenRect.bottom =ddm.Height;
    d3dpp.BackBufferWidth=nDisplayWidth=gScreenRect.right =ddm.Width;
    d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
//  d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
    d3dpp.SwapEffect=D3DSWAPEFFECT_COPY;
    d3dpp.hDeviceWindow=hWnd;
    d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
    d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;

    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&g_pd3dDevice)))
    {
        ErrorMessage("Unable to Create Device");
        return E_FAIL;
    }

    if(FAILED(g_pd3dDevice->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &g_pSurface, NULL)))
    {
        ErrorMessage("Unable to Create Surface");
        return E_FAIL;
    }

g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&g_pSurface);
D3DXSaveSurfaceToFile("d:\\v\\temp.bmp",D3DXIFF_BMP,g_pSurface,NULL,NULL);

問題は、出力ファイルのサイズが 5MB であるにもかかわらず、出力に黒色しか表示されないことです。同じコードで GetFrontBufferData を使用すると、画面を正常にキャプチャできます。私は何か間違ったことをしていますか?私を助けてください..

4

2 に答える 2

1

バックバッファからスクリーン ショットをキャプチャすることはできません。

フロントバッファとバックバッファの関係は次のように機能します。バックバッファがワイプされ、一度に 1 つのドローコールでシーンが描画されます。準備が整うとすぐにフロントバッファで反転され、バックバッファが再びワイプされている間、フロントバッファが表示する最終画像を取得します。

理論的には、必要なデータがバックバッファーにあるポイントがありますが、この状態を確実に取得できるとは思いません。フロントバッファは、このタスクのために設計されています。

于 2012-10-30T09:44:02.253 に答える
0

スクリーンショットを撮る方法は次のとおりです。

IDirect3DSurface9 *offscreenSurface = 0;
d3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &offscreenSurface);
D3DXSaveSurfaceToFile( filename, D3DXIFF_BMP, offscreenSurface, 0, 0 )

このコードはが呼び出される前に実行されることに注意してください。 Present

于 2013-02-14T23:08:02.743 に答える