我已经按照本教程完成了所有工作:http://www.braynzarsoft.net/index.php?p=InitDX11
结果是一个不断变化的背景颜色的窗口。问题是当窗口被拖动时颜色停止变化。我尝试将以下案例陈述(以各种组合方式)添加到WndProc
回调中,但无效:
case WM_ENTERSIZEMOVE:
SetTimer(hwnd, 1, USER_TIMER_MINIMUM, NULL);
return 0;
case WM_EXITSIZEMOVE:
KillTimer(hwnd, 1);
return 0;
case WM_TIMER:
RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
return 0;
case WM_PAINT:
UpdateScene();
DrawScene();
return 0;
上述情况导致d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor)
发生异常,但我也尝试将WM_PAINT
案例合并到WM_TIMER
案例中,而我所得到的只是在自然窗口之间闪烁背景颜色和DX场景的当前颜色(闪烁的DX部分的颜色从未进化过,无论我拖动窗口多长时间,它都保持不变。)
任何提示?
答案 0 :(得分:1)
更好的选择是在调整大小时不绘制。将后备缓冲区一次又一次地重新调整大小通常没什么价值。只需等到调整大小完成就可以调整缓冲区的大小。
static bool s_in_sizemove = false;
static bool s_in_suspend = false;
static bool s_minimized = false;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
if (!s_minimized)
{
s_minimized = true;
if (!s_in_suspend)
OnSuspending();
s_in_suspend = true;
}
}
else if (s_minimized)
{
s_minimized = false;
if (s_in_suspend)
OnResuming();
s_in_suspend = false;
}
else if ( !s_in_sizemove )
OnWindowSizeChanged();
break;
case WM_ENTERSIZEMOVE:
s_in_sizemove = true;
break;
case WM_EXITSIZEMOVE:
s_in_sizemove = false;
OnWindowSizeChanged();
break;
case WM_GETMINMAXINFO:
{
auto info = reinterpret_cast<MINMAXINFO*>(lParam);
info->ptMinTrackSize.x = 320;
info->ptMinTrackSize.y = 200;
}
break;
您必须释放所有后备缓冲区和深度缓冲区引用,并在OnWindowSizedChange
中重新创建它们。
实际渲染是大多数“实时”图形应用的消息泵的一部分:
// Main message loop
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Tick();
}
}
此处Tick
处理计时器更新和渲染。
有关完整示例,请参阅Direct3D Win32 Game Visual Studio template。
更新:如果在调整大小期间'空白窗口'让您烦恼,但在调整大小期间您可以使用DXGI_SCALING_STRETCH
的默认行为,则可以替换{{1}上面用:
WM_PAINT
答案 1 :(得分:0)
我有同样的问题。我认为解决方案会很复杂。但是,没有。那是关于消息池。 DX应该使用相同的线程,实际上您在该循环中使用了渲染(例如:myRender(){..})。在我的情况下, Frame(); 是我用于渲染的布尔可返回值,其中包含所有操作:
MSG msg;
bool done, result;
// Initialize the message structure.
ZeroMemory(&msg, sizeof(MSG));
// Loop until there is a quit message from the window or the user.
done = false;
while (!done)
{
// Handle the windows messages.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// If windows signals to end the application then exit out.
if (msg.message == WM_QUIT)
{
done = true;
}
else
{
// Otherwise do the frame processing.
result = Frame();
if (!result)
{
done = true;
}
}
}
调整大小后,您可以处理一些 WM_SIZE 或 WM_MOVE 消息。在您的LRESULT CALLBACK句柄中:
LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) {
//...OTHERS...
if (umessage == WM_MOVE) {
/*Dont be confused ApplicationHandle is pointer of my SystemClass
which set ApplicationHandle = this in SystemClass.
to create a window/s and Graphics (contains all DirectX related operations).
Here GraphicsClass (contains all DX calls) initialized in
SystemClass as new class and SystemClass initialized as
new class at main.cpp in WINAPI. That makes a lot easier
for handling this kind of issues for me
In your case you will call your rendering loop instead Frame();*/
if (ApplicationHandle -> m_Graphics) {
RECT r;
GetClientRect(ApplicationHandle -> m_hwnd, & r);
ApplicationHandle -> m_Graphics -> clientSize = {
r.right - r.left,
r.bottom - r.top
};
//frame processing.
ApplicationHandle -> m_Graphics -> Frame();
}
if (umessage == WM_SIZING) {
if ((wparam == WMSZ_BOTTOM || wparam == WMSZ_RIGHT || wparam == WMSZ_BOTTOMRIGHT) && ApplicationHandle -> m_Graphics) {
/*IF WE DO NOT HANDLE wparam resize will be very laggy.*/
GetClientRect(ApplicationHandle -> m_hwndOWNER, & clientRect);
ApplicationHandle -> m_Graphics -> clientSize = {
clientRect.right - clientRect.left,
clientRect.bottom - clientRect.top
};
ApplicationHandle -> m_Graphics -> Frame();
}
}
}
//...OTHERS...
}
这里是结果的视频:https://www.youtube.com/watch?v=vN_XPVRHuiw&feature=youtu.be
即使您正在使用Desktop Window Manager(WDM)绘制自定义窗口,您也可以处理 WM_NCHITTEST ,因为其他点击情况只有在调整大小后才会更新并移动,但如果您单击并按住标题或仅保留边框,则不会移动。
此外,如果您已经使用DirectX,我不明白为什么您要处理 WM_PAINT 。