Search code examples
c++directxdirectx-9

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


Windows7 is using point filtering to stretch from my DirectX9 back-buffer to the window client area. When the window is resized the artifacts from the stretching look very bad. We can avoid this by changing the back buffer size, but that requires calling IDirect3DDevice9::Reset(). This results in a black screen and a small delay while resizing is happening.

Is there any way to improve the filtering method windows uses? Or, Is there any way to update the window from a different DirectX surface such as a Render Target?


Im using unmanaged C++ DirectX code. Say I have a 1280 x 720 back buffer surface:

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

Yet I have a 1920 x 1080 window:

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

When I call Present() windows will stretch my DirectX back buffer to the window. However their stretch doesn't appear to perform any filtering.

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

I can resize the backbuffer, but that requires a call to Reset() and Reset() causes video memory surfaces to be lost.


Solution

  • I bump to this problem when I try to play video in window, and want to resize window without the need to reset device.

    I found a solution from mpc-hc source code: https://github.com/mpc-hc/mpc-hc/blob/develop/src/filters/renderer/VideoRenderers/SyncRenderer.cpp

    1) Make backbuffer big (biggest size that you expect the window would be)-> I chose screen size

    2) Draw only on a rectangle, that size equal to the window

    3) use Device.Present(srcrect, destrect). srcrect and destrect are the same rectangle and are window size.

    I am new to directX and all, but this solution works for me.