【问题标题】:Failed LockRect of IDirect3DSurface9IDirect3DSurface9 的 LockRect 失败
【发布时间】:2017-12-21 18:18:32
【问题描述】:

我已经hook了IDirect3DDevice9接口的Present方法,我希望能够开始视频捕捉。

像这样的工作截图

if (GetAsyncKeyState('O') & 1) {
    pDevice->CreateOffscreenPlainSurface((rect.right - rect.left),(rect.bottom - rect.top),D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&back_buffer, NULL);
    pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back_buffer);
    D3DXSaveSurfaceToFile(L"C:\\screenshot.bmp", D3DXIFF_BMP, back_buffer, 0, NULL );

    IDirect3DSurface9_Release(back_buffer);
}

我似乎没能锁定表面。

HRESULT APIENTRY hook_Present(IDirect3DDevice9* pDevice, const RECT* pSourceRect,const RECT* pDestRect, HWND hDestWindowOverride,const RGNDATA* pDirtyRegion) {
    IDirect3DSurface9*back_buffer;
    D3DDEVICE_CREATION_PARAMETERS cparams;
    RECT rect;
    pDevice->GetCreationParameters(&cparams);
    GetClientRect(cparams.hFocusWindow, &rect);
    if (GetAsyncKeyState('R') & 1) {
        if(dx9Capturing == 0) {
            //Create the AVI file
            // etc code
            dx9Capturing = 1
        }
        else if(dx9Capturing == 1) dx9Capturing = 2; // stop capturing
    }

    if(dx9Capturing == 1) {
        // Capture the current frame
        pDevice->CreateOffscreenPlainSurface((rect.right - rect.left),(rect.bottom - rect.top),D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&back_buffer, NULL);
        pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back_buffer);
        D3DLOCKED_RECT  lockedRect;
        if(FAILED(back_buffer->LockRect(&lockedRect,&rect,D3DLOCK_READONLY))) {
            MessageBoxA(NULL, "Failed locking the back buffer!", "Error", MB_OK);
            return orig_Present(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
        }
        for(int i=0;i<rect.bottom;i++)
            {
                memcpy((BYTE*)pBits+(rect.bottom-i-1)*rect.right*BITSPERPIXEL/8,(BYTE*)lockedRect.pBits+i*lockedRect.Pitch,rect.right*BITSPERPIXEL/8);
            }
        back_buffer->UnlockRect();
        pAviFile->AddNewFrame(rect.right,rect.bottom,pBits);
    }

    return orig_Present(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}

【问题讨论】:

  • 当我在表面上调用 getDesc 时也失败了
  • 我也不能 pDevice->GetFrontBufferData(0, offscreen_surface)),GetFrontBufferData 失败...
  • 我也不能在 Present 中使用 GetAdapterDisplayMode,这就是我使用 GetCreationParameters 的原因
  • 当这些 API 调用失败时返回的 HRESULT 值是多少?
  • 0x8876086C(D3DERR_INVALIDCALL)

标签: c++ locking directx video-capture


【解决方案1】:

D3DERR_INVALIDCALL 表示后台缓冲区的大小不等于显示器的分辨率。例如,当您要捕获具有以下分辨率(1920 * 1080)的显示器时,必须创建相同大小的 DirectX9 的后台缓冲区。

【讨论】:

  • 这并不能真正回答问题。作为评论可能会更好
猜你喜欢
  • 1970-01-01
  • 2019-06-07
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
相关资源
最近更新 更多