如何解决D3D9DeviceEx CheckDeviceState() 重置后返回 S_PRESENT_MODE_CHANGED
当我将 D3D9Ex 设备重置为 S_PRESENT_MODE_CHANGED
状态(在我合上笔记本电脑的盖子时发生)时,设备状态一直处于 S_PRESENT_MODE_CHANGED
状态。
测试设置是:
应用程序代码并不太花哨,只是简单地启动了一个窗口。在渲染循环中,它只是用淡蓝色清除窗口:
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#pragma comment (lib,"d3d9.lib")
IDirect3D9Ex* d3d;
IDirect3DDevice9Ex* d3ddev;
int blue;
void initD3D(HWND hWnd);
void render_frame(HWND hWnd);
void cleanD3D(void);
LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WParaM wParam,LParaM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdshow)
{
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc,sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBrush)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,L"WindowClass",L"Our First Direct3D Program",WS_OVERLAPPEDWINDOW,300,800,600,NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdshow);
initD3D(hWnd);
MSG msg;
while (TRUE)
{
while (PeekMessage(&msg,PM_REMOVE))
{
TranslateMessage(&msg);
dispatchMessage(&msg);
}
if (msg.message == WM_QUIT)
break;
render_frame(hWnd);
}
cleanD3D();
return msg.wParam;
}
void cleanD3D(void)
{
d3ddev->Release();
d3d->Release();
}
LRESULT CALLBACK WindowProc(HWND hWnd,LParaM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
void initD3D(HWND hWnd)
{
Direct3DCreate9Ex(D3D_SDK_VERSION,&d3d);
D3DPRESENT_ParaMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_disCARD;
d3dpp.hDeviceWindow = hWnd;
d3d->CreateDeviceEx(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&d3ddev);
}
void render_frame(HWND hWnd)
{
HRESULT state = d3ddev->CheckDeviceState(NULL);
if (state == S_OK) {
blue = (blue + 2) % 255;
}
else if (state == S_PRESENT_MODE_CHANGED) {
D3DPRESENT_ParaMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_disCARD;
d3dpp.hDeviceWindow = hWnd;
HRESULT resetRes = d3ddev->ResetEx(&d3dpp,NULL);
blue = 255;
}
d3ddev->Clear(0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,blue),1.0f,0);
HRESULT presentResult = d3ddev->Present(NULL,NULL); // displays the created frame on the screen
}
当我启动应用程序时,一切都按预期进行。当我合上笔记本电脑的盖子时,这会发生在 render_frame
函数中:
-
CheckDeviceState(NULL)
返回S_PRESENT_MODE_CHANGED
,所以我应该Reset()
设备(如 docs 中所述) -
Reset()
在设备上制作成功 -
Present()
返回S_OK
- 屏幕正确地涂上了蓝色
- 在下一帧渲染时,
CheckDeviceState(NULL)
仍然返回S_PRESENT_MODE_CHANGED
,因此生成了一个新的Reset()
。这不是预期的:Reset()
应该 .
一些进一步的信息:
我如何检测这种情况?我应该怎么做才能保持应用程序正常运行且无需每次都重置设备?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。