首页 > 解决方案 > DirectX Resize 在边缘显示 win32 背景

问题描述

在 DirectX 中缩小尺寸时,我注意到底部/右侧边缘出现闪烁。

在此处输入图像描述

如果您修复了交换链的大小(红色),并将 win32 背景设置为绿色,您将在调整大小时获得以下信息:

在此处输入图像描述

看起来窗口大小落后于鼠标位置(“拖动矩形”),但 DirectX 填充的区域(红色和黑色)与拖动矩形匹配,其余部分将使用窗口背景颜色(绿色)进行绘制。

DirectX Utility Toolkit (DXUT) 没有这个问题。尝试使用他们的设置,我发现设置DXGI_SWAP_CHAIN_DESC::SwapEffect = DXGI_SWAP_EFFECT_DISCARD只会在 sizemove 期间将屏幕涂成绿色(窗口背景颜色)。我假设当 win32 进入模式 sizemove 循环以便在 sizemove 期间显示 DirectX 内容时,DXUT 有自己的特殊处理。

DXGI_SWAP_EFFECT_DISCARD旧的 blit 模式演示模型的一部分。值得注意的是,它不能DXGI_SWAP_CHAIN_DESC1::Scaling = DXGI_SCALING_NONE将缩放比例拉伸到窗口大小。所以我最好的猜测是这种行为是由于翻转演示模型的实现(它翻转了一个太小(黑色)的矩形,然后通过将其余部分涂成绿色来覆盖)。

有谁知道如何阻止win32背景显示?


编辑:

感谢 IInspectable!我可以确认WS_EX_NOREDIRECTIONBITMAP扩展样式的作品:它阻止了 win32 背景显示的工件

标签: winapiresizedirectxwindow-resizedxgi

解决方案


CreateSwapChainForComposition()在使用DirectComposition时,我重现了与使用CreateSwapChainForHwnd().

这意味着像素有两条路径到达屏幕。绿色像素正在通过重定向表面。因此,显式请求WS_EX_NOREDIRECTIONBITMAP可防止通过重定向表面停止显示 win32 背景的任何绘图。

另一条路径是翻转呈现行为,即如何显示红色和黑色像素。因此,在调整大小时不使用翻转演示也会停止显示 win32 背景。

DWM 一定有一个错误:当有一个重定向表面时,防止交换链的内容延伸到窗口之外的剪辑小于重定向表面,允许它沿着底部/右边缘看到。

有两个有趣的观察结果:

  1. 当使用WS_EX_LAYOUTRTL或手动将 a 定位IDCompositionVisual到屏幕的右边缘时GetClientRect(),交换链内容正确定位,但仍被剪裁。
  2. 当使用WS_EX_NOREDIRECTIONBITMAP窗口的非客户区时,与交换链的内容对齐,而不是被剪切的交换链内容

这些观察结果似乎暗示问题的原因是 DWM 有时使用它的首选大小作为窗口大小,有时使用重定向表面的大小。


推荐阅读