directx 游戏全屏模式截图


如题,在游戏全屏模式下如何使用directx来进行截图?在写下面函数遇到一个问题,就是全屏模式下CreateDevice失败,返回 DXERROR9(0x88760868, "D3DERR_DEVICELOST", "Device lost")

   
  bool ScreenShotByHwnd(HWND DesthWnd, bool bFullScreen /*= false*/)
  
{
TCHAR wndTexx[MAX_PATH] = { 0 };
::GetWindowText(DesthWnd, wndTexx, MAX_PATH);
_tcscat(wndTexx, _T("\n"));
OutputDebugString(wndTexx);

memset(&m_displayMode, 0, sizeof(m_displayMode));
m_hr = m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &m_displayMode);
if (FAILED(m_hr))
{
OutputDebugString(_T("GetAdapterDisplayMode failed\n"));
SafeRelease(m_pD3D);
return false;
}

cout << "AdapterDefault width :" << m_displayMode.Width<<endl;
cout << "AdapterDefault height :" << m_displayMode.Height<<endl;

RECT rtWnd;
::GetClientRect(DesthWnd, &rtWnd);

D3DPRESENT_PARAMETERS d3dParam;
memset(&d3dParam, 0, sizeof(d3dParam));

d3dParam.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dParam.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

if (bFullScreen) //全屏模式即非窗口模式
{
cout << "全屏模式" << endl;
d3dParam.Windowed = FALSE;
d3dParam.BackBufferWidth = 800;
d3dParam.BackBufferHeight = 600;

d3dParam.BackBufferFormat = m_displayMode.Format;
d3dParam.FullScreen_RefreshRateInHz = m_displayMode.RefreshRate;
HWND hFocusWnd = ::FindWindow(L"地下城与勇士", L"地下城与勇士");
d3dParam.hDeviceWindow = hFocusWnd;
m_hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hFocusWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dParam, &m_pd3dDevice);
}
else
{
cout << "窗口模式" << endl;
d3dParam.Windowed = TRUE;
d3dParam.BackBufferWidth = 0;
d3dParam.BackBufferHeight = 0;
d3dParam.BackBufferFormat = D3DFMT_UNKNOWN;
d3dParam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

d3dParam.hDeviceWindow = DesthWnd;

m_hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dParam, &m_pd3dDevice);
}

cout << "BackBufferWidth :" << d3dParam.BackBufferWidth << endl;
cout << "BackBufferHeight height :" << d3dParam.BackBufferHeight << endl;

if (FAILED(m_hr))
{
OutputDebugString(_T("CreateDevice failed\n"));
SafeRelease(m_pd3dDevice);
return false;
}

m_hr = m_pd3dDevice->CreateOffscreenPlainSurface(m_displayMode.Width, m_displayMode.Height,
D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &m_pd3dSurface, NULL);
if (FAILED(m_hr))
{
OutputDebugString(_T("CreateOffscreenPlainSurface failed\n"));
m_strLastErr = ToolFunc::FormatErrStr(GetLastError());
SafeRelease(m_pd3dDevice);
SafeRelease(m_pd3dSurface);
return false;
}

m_pd3dDevice->GetFrontBufferData(0, m_pd3dSurface);

// area to capture

RECT rtCapture;
::GetWindowRect(DesthWnd, &rtCapture);
m_hr = D3DXSaveSurfaceToFile(_T("D:\\Desktop.png"), D3DXIFF_PNG, m_pd3dSurface, NULL, &rtCapture);//s保存为png格式
if (FAILED(m_hr))
{
OutputDebugString(_T("D3DXSaveSurfaceToFile failed\n"));
m_strLastErr = ToolFunc::FormatErrStr(GetLastError());
SafeRelease(m_pd3dDevice);
SafeRelease(m_pd3dSurface);
return false;
}

SafeRelease(m_pd3dDevice);
SafeRelease(m_pd3dSurface);

return true;
}

directx C++

Pojet 11 years, 2 months ago

Your Answer