DirectX 调整大小在边缘处显示 win32 背景
DirectX Resize shows win32 background at Edges
在 DirectX 中缩小尺寸时,我注意到 bottom/right 边缘有闪烁。
如果您固定交换链的大小(红色),并将 win32 背景设置为绿色,您将在调整大小时得到以下结果:
看起来 window 大小滞后于鼠标位置(“拖动矩形”),但 DirectX 填充的区域(红色和黑色)与拖动矩形匹配,其余部分用window 背景颜色(绿色)。
DirectX Utility Toolkit (DXUT) 没有这个问题。试验他们的设置我发现设置 DXGI_SWAP_CHAIN_DESC::SwapEffect = DXGI_SWAP_EFFECT_DISCARD
只会在 sizemove 期间将屏幕涂成绿色(window 背景颜色)。我假设当 win32 进入 modal sizemove loop 以便在 sizemove 期间显示 DirectX 内容时,DXUT 有自己的特殊处理。
DXGI_SWAP_EFFECT_DISCARD
是 old blit mode presentation model 的一部分。值得注意的是,它不能 DXGI_SWAP_CHAIN_DESC1::Scaling = DXGI_SCALING_NONE
缩放必须拉伸到 window 大小。所以我最好的猜测是这种行为是由于翻转演示模型的实现(它翻转了一个太小的矩形(黑色)然后通过将其余部分涂成绿色来覆盖)。
有谁知道如何停止显示 win32 背景?
编辑:
感谢 IInspectable!我可以确认 WS_EX_NOREDIRECTIONBITMAP
扩展样式有效:它停止显示
的 win32 背景中的工件
当我使用 CreateSwapChainForComposition()
和 DirectComposition 时,我重现了与我使用 CreateSwapChainForHwnd()
.
完全相同的行为
这意味着像素到达屏幕有两条路径。绿色像素穿过重定向表面。因此,显式请求 WS_EX_NOREDIRECTIONBITMAP
会阻止通过重定向表面进行的任何绘制,从而阻止 win32 背景的显示。
另一个路径是翻转呈现行为,即红色和黑色像素的显示方式。因此,在调整大小时不使用翻转显示也会停止显示 win32 背景。
DWM 一定有一个错误:当存在重定向表面时,防止交换链内容延伸超过 window 的剪裁小于重定向表面,允许它沿 bottom/right 边。
有两个有趣的观察结果:
- 当使用
WS_EX_LAYOUTRTL
或使用 GetClientRect()
手动将 IDCompositionVisual
定位到屏幕的右边缘时,交换链内容位置正确,但仍被剪裁。
- 当使用
WS_EX_NOREDIRECTIONBITMAP
时,window 的非客户区与交换链的内容对齐,而不是被剪裁的交换链内容
这些观察结果暗示问题的原因是 DWM 有时使用它的首选大小 window 大小,有时使用重定向表面的大小。
在 DirectX 中缩小尺寸时,我注意到 bottom/right 边缘有闪烁。
如果您固定交换链的大小(红色),并将 win32 背景设置为绿色,您将在调整大小时得到以下结果:
看起来 window 大小滞后于鼠标位置(“拖动矩形”),但 DirectX 填充的区域(红色和黑色)与拖动矩形匹配,其余部分用window 背景颜色(绿色)。
DirectX Utility Toolkit (DXUT) 没有这个问题。试验他们的设置我发现设置 DXGI_SWAP_CHAIN_DESC::SwapEffect = DXGI_SWAP_EFFECT_DISCARD
只会在 sizemove 期间将屏幕涂成绿色(window 背景颜色)。我假设当 win32 进入 modal sizemove loop 以便在 sizemove 期间显示 DirectX 内容时,DXUT 有自己的特殊处理。
DXGI_SWAP_EFFECT_DISCARD
是 old blit mode presentation model 的一部分。值得注意的是,它不能 DXGI_SWAP_CHAIN_DESC1::Scaling = DXGI_SCALING_NONE
缩放必须拉伸到 window 大小。所以我最好的猜测是这种行为是由于翻转演示模型的实现(它翻转了一个太小的矩形(黑色)然后通过将其余部分涂成绿色来覆盖)。
有谁知道如何停止显示 win32 背景?
编辑:
感谢 IInspectable!我可以确认 WS_EX_NOREDIRECTIONBITMAP
扩展样式有效:它停止显示
当我使用 CreateSwapChainForComposition()
和 DirectComposition 时,我重现了与我使用 CreateSwapChainForHwnd()
.
这意味着像素到达屏幕有两条路径。绿色像素穿过重定向表面。因此,显式请求 WS_EX_NOREDIRECTIONBITMAP
会阻止通过重定向表面进行的任何绘制,从而阻止 win32 背景的显示。
另一个路径是翻转呈现行为,即红色和黑色像素的显示方式。因此,在调整大小时不使用翻转显示也会停止显示 win32 背景。
DWM 一定有一个错误:当存在重定向表面时,防止交换链内容延伸超过 window 的剪裁小于重定向表面,允许它沿 bottom/right 边。
有两个有趣的观察结果:
- 当使用
WS_EX_LAYOUTRTL
或使用GetClientRect()
手动将IDCompositionVisual
定位到屏幕的右边缘时,交换链内容位置正确,但仍被剪裁。 - 当使用
WS_EX_NOREDIRECTIONBITMAP
时,window 的非客户区与交换链的内容对齐,而不是被剪裁的交换链内容
这些观察结果暗示问题的原因是 DWM 有时使用它的首选大小 window 大小,有时使用重定向表面的大小。