2013-07-23 12 views
5

私は、画面をWindows上にキャプチャし、その結果、最速の方法を決定する方法を試していました。最も一般的なのは明らかにGDIの方法です。そしてそれはパフォーマンスにおいてもまともです。システムの負荷と静的/非静的画面の内容によって、画面キャプチャレートは27〜47fps(Windows 7、Intel [email protected]、8GB RAM)の範囲でした。DirectXを使用してWindows上で画面をキャプチャする

GetFrontBufferData()APIを使用したDirectXフロントバッファアプローチでは、パフォーマンスは同等でしたが、低速側(わずか48fpsに達することができませんでした)ではわずかでした。

Fastest method of screen capturing私はgetRenderTarget()とgetRenderTargetData()を使って提案された方法で試してみましたが、コメントに示唆されているように、私が得るのは黒い画像です。ここでは、デバイスの初期構成を含め、私の完全なコードは次のとおりです。

IDirect3DSurface9* pRenderTarget=NULL; 
    IDirect3DSurface9* pDestTarget=NULL; 
    // sanity checks. 
    if (g_pd3dDevice == NULL){ 
     return; 
    } 
    HRESULT hr; 
    // get the render target surface. 
    hr = g_pd3dDevice->GetRenderTarget(0, &pRenderTarget); 
    // get the current adapter display mode. 
    //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode); 

    // create a destination surface. 
    hr = g_pd3dDevice->CreateOffscreenPlainSurface(1600, 900, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pDestTarget, NULL); 
    //copy the render target to the destination surface. 
    hr = g_pd3dDevice->GetRenderTargetData(pRenderTarget, pDestTarget); 

    D3DLOCKED_RECT lockedRect; 
    hr =pDestTarget->LockRect(&lockedRect,NULL, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY); 

    for(int i=0 ; i < 900 ; i++) 
    { 
     for(int j=0; j < 1600; j++){ 
      memcpy((BYTE*) data + i * 1600 * 3 + j * 3, (BYTE*) lockedRect.pBits + i* lockedRect.Pitch + j * 4, 3); 
     } 
    } 
    pDestTarget->UnlockRect(); 
    // clean up. 
    pRenderTarget->Release(); 
    pDestTarget->Release(); 

とデバイスの初期化部分のため:

g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION); 
D3DPRESENT_PARAMETERS PresentParams; 
memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS)); 
PresentParams.Windowed = TRUE; 
PresentParams.SwapEffect =D3DSWAPEFFECT_DISCARD; 
g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL ,GetDesktopWindow(),D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,&g_pd3dDevice); 

上記のコードに間違いを指摘してください。どんな提案も大歓迎です。私もGetBackBuffer()APIを試してみましたが、画像データを取得できませんでした。

EDIT:

は私のユースケースは、DirectX経由GetFrontBufferData()を使用してのみ行われているように見えるデスクトップ画面をキャプチャすることでした。 GetBackBuffer()/ GetRenderTargetData()は、このケースを呼び出す正しいAPIではありません。参考:The desktop capture with DirectX does not workおよびHow to get the screenshot of the desktop from back buffer with DirectX

しかし、デスクトップ画面をキャプチャしたり、GDIの方法を最適化するためのより速い方法の提案は歓迎します。

+1

私は 'GetRenderTarget'がデバイスのバックバッファを返すように感じます。あなたは 'GetFrontBufferData'関数を見たいでしょう。 –

+0

私は質問で述べたようにGetFrontBufferData()を使用しましたが、正常に動作します。しかし、GDIの方法に比べてパフォーマンスは向上しません。私は、もしあれば、より速いアプローチを探していました。 –

+0

私はscreencaptureアプリケーションも作成しています。 [Here](http://stackoverflow.com/q/31286503/4794952)は私の問題へのリンクです。ゲームをキャプチャすると黒い画面が表示され、他のアプリケーションの場合はキャプチャされた画面が戻されます。フルスクリーンゲームで動作させる方法はありますか? – newbie2015

答えて

2

スクリーンショットを撮る前に何かをレンダリングしましたか?

  • GetFrontBufferData - この機能は、画面のデータ
  • GetRenderTargetDataを得る - あなたは何をレンダリングしていない場合、この機能は、レンダーターゲット

からのデータには、あなたは間違いなく、ブランクを得ます取得画像。

+0

私はおそらく文脈から外れています。私の使用例は、デスクトップ画面のデータを取得することです。だから、GetRenderTargetData()が正しいAPI呼び出しではないことを示唆していますか?あなたはレンダリング部分を詳しく教えていただけますか? –

+0

ここであなたの答えを確認http://stackoverflow.com/questions/12859894/the-desktop-capture-with-directx-does-not-work/12863143#12863143 ..そう、GetFrontBufferData()は唯一のAPIですDirectXでデスクトップ画面をキャプチャするために使用されます。 –

+1

はい、GetRenderTargetData()は、デスクトップではなく、アプリケーションのレンダーターゲットからデータを取得するために使用されました。 – zdd

関連する問題