JustinB
JustinB

Reputation: 1572

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.

Upvotes: 3

Views: 1687

Answers (3)

Ngo Phuong Le
Ngo Phuong Le

Reputation: 440

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.

Upvotes: 1

Jerry
Jerry

Reputation: 1

Have you tried the IDirect3DDevice9::SetSamplerState?

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

Actually I was searching around for a similar issue I had. I used D3D9 texture to render some images. On Vista, the SetSamplerState plus Linear Texture Filtering helps reducing the artifacts caused by resizing windows a lot. But this is not the case on Windows7. I'm not sure how this is handled differently in the 2 platforms.

Upvotes: 0

holtavolt
holtavolt

Reputation: 4458

It would be helpful if you posted some code fragments of the specific operations you're asking about, however if you are using the GDI (Unmanaged Win32) StretchBlt function, you can get better resizing behavior with HALFTONE, as per this post: Is StretchBlt HALFTONE == BILINEAR for all scaling?

If you are using GDI+ (WinForms/C#), you can get Bilinear (or better) interpolation using g.InterpolationMode = InterpolationMode.Bilinear (look at MSDN for all options). Be warned that GDI+ is typically slower than GDI (or DX)

(Somewhat related info in this post: Bilinear interpolation - DirectX vs. GDI+)

Upvotes: 0

Related Questions