Windows在从DirectX BackBuffer拉伸到WIndow时使用点采样

Windows uses Point sampling when stretching from a DirectX BackBuffer to the WIndow

本文关键字:采样 WIndow DirectX 在从 BackBuffer Windows      更新时间:2023-10-16

Windows7正在使用点过滤将DirectX9后台缓冲区扩展到窗口客户端区域。调整窗口大小时,拉伸产生的瑕疵看起来非常糟糕。我们可以通过更改后台缓冲区大小来避免这种情况,但这需要调用IDirect3DDevice9::Reset()。这会导致在调整大小时出现黑屏和小延迟。

有什么方法可以改进windows使用的过滤方法吗?或者,是否有任何方法可以从不同的DirectX曲面(如渲染目标)更新窗口?


我正在使用非托管的C++DirectX代码。假设我有一个1280 x 720的后缓冲表面:

D3DPRESENT_PARAMETERS  presentParams;
presentParams.BackBufferWidth  = 1280;
presentParams.BackBufferHeight = 720;
gD3D->CreateDevice(
    0, D3DDEVTYPE_HAL, hWnd,               
    D3DCREATE_HARDWARE_VERTEXPROCESSING,
    &presentParams,
    &pD3D9Device);

然而,我有一个1920 x 1080的窗口:

hWnd = CreateWindowExA(NULL, "WindowClass", winName,
                flags, 0, 0, 1920, 1080,
                NULL, NULL, hInstance, NULL);

当我调用Present()时,窗口会将DirectX后台缓冲区扩展到该窗口。然而,它们的拉伸似乎不会执行任何过滤。

pD3D9Device->Present(NULL, NULL, NULL, NULL);

我可以调整后缓冲区的大小,但这需要调用Reset(),而Reset()会导致视频内存表面丢失。

当我尝试在窗口中播放视频时遇到了这个问题,并且希望在不需要重置设备的情况下调整窗口大小。

我从mpc-hc源代码中找到了一个解决方案:https://github.com/mpc-hc/mpc-hc/blob/develop/src/filters/renderer/VideoRenderers/SyncRenderer.cpp

1) 使后台缓冲区变大(您期望窗口的最大大小)->我选择了屏幕大小

2) 只在一个矩形上绘制,该矩形的大小等于窗口

3) 使用Device.Present(srcrect,destrect)。srcrect和destrect是相同的矩形,并且是窗口大小。

我是directX的新手,但这个解决方案对我来说很有效。

如果您发布了您询问的特定操作的一些代码片段,这将很有帮助,但是,如果您使用GDI(非托管Win32)StretchBlt函数,您可以使用HALFTONE获得更好的调整大小行为,如本文所述:StretchBltHALFTONE==BILINAR适用于所有缩放吗?

如果您使用的是GDI+(WinForms/C#),您可以使用g.InterpolationMode=InterpolationMode.Bilinear(查看MSDN中的所有选项)获得双线性(或更好)插值。请注意,GDI+通常比GDI(或DX)慢

(本文中的一些相关信息:双线性插值-DirectX与GDI+)

您尝试过IDirect3DDevice9::SetSamplerState吗?

http://msdn.microsoft.com/en-us/library/windows/desktop/bb174698(v=vs.85).aspx

事实上,我一直在四处寻找类似的问题。我使用D3D9纹理来渲染一些图像。在Vista上,SetSamplerState加上线性纹理过滤有助于大量减少因调整窗口大小而导致的瑕疵。但Windows7上的情况并非如此。我不确定这两个平台是如何处理的。