【问题标题】:How to Change Window Size in DirectX 11 Desktop Application如何在 DirectX 11 桌面应用程序中更改窗口大小
【发布时间】:2015-01-22 18:09:38
【问题描述】:

我正在根据这个 msdn 链接中的教程编写 DirectX 11 着色器程序:

https://msdn.microsoft.com/en-us/library/windows/desktop/jj552952.aspx

当我运行它时,它是全屏的。更改交换链大小不会按预期更改窗口大小。有没有办法改变窗口大小?我只是想以固定大小创建窗口,如果它恰好覆盖整个屏幕,我确实希望它是独占全屏。

我可以使用 IDXGISwapChain1::GetHwnd 方法从交换链中获取 HWND。这个句柄对调整窗口大小有用吗?

对应的代码可以在这里找到:

https://code.msdn.microsoft.com/windowsdesktop/Direct3D-Tutorial-Win32-829979ef

【问题讨论】:

    标签: c++ windows direct3d directx-11 hlsl


    【解决方案1】:

    您应该查看处理窗口大小调整的Direct3D Win32 Game VS 2013 Win32 桌面应用程序模板,尽管它不支持全屏独占模式转换。

    在 Win32 桌面应用程序中为 Direct3D 11 调整窗口大小的基本处理是更新您的窗口过程以处理 WM_SIZE,但您需要应对许多情况。

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static bool s_in_sizemove = false;
        static bool s_minimized = false;
    
        switch (message)
        {
    
    ...
    
        case WM_SIZE:
            if (wParam == SIZE_MINIMIZED)
            {
    // The window was minimized (you should probably suspend the application)
                if (!s_minimized)
                {
                    s_minimized = true;
                }
            }
            else if (s_minimized)
            {
    // The window was minimized and is now restored (resume from suspend)
                s_minimized = false;
            }
            else if ( !s_in_sizemove )
            {
    // Here is where you handle the swapchain resize for maximize or unmaximize
            }
            break;
    
        case WM_ENTERSIZEMOVE:
    // We want to avoid trying to resizing the swapchain as the user does the 'rubber band' resize
            s_in_sizemove = true;
            break;
    
        case WM_EXITSIZEMOVE:
            s_in_sizemove = false;
    // Here is the other place where you handle the swapchain resize after the user stops using the 'rubber-band' 
            break;
    
        case WM_GETMINMAXINFO:
            {
    // We want to prevent the window from being set too tiny
                auto info = reinterpret_cast<MINMAXINFO*>(lParam);
                info->ptMinTrackSize.x = 320;
                info->ptMinTrackSize.y = 200;
            }
            break;
    
    ...
    

    执行 Direct3D 交换链调整大小:

    • 使用 null 调用 ID3D11DeviceContext::OMSetRenderTargets 以取消绑定渲染目标和任何深度/模板缓冲区。
    • 释放您的渲染目标视图和深度/模板视图,以及对原始后台缓冲区或深度/模板缓冲区的任何其他引用。
    • 致电D3D11DeviceContext::Flush 让这些更改完成
    • 调用IDXGISwapChain::ResizeBuffers 将后台缓冲区调整为新的大小。请务必回复 DXGI_ERROR_DEVICE_REMOVEDDXGI_ERROR_DEVICE_RESET 失败。
    • 对新大​​小再次执行与最初相同的设置:为新后备缓冲区创建渲染目标视图,为深度/模板缓冲区创建与新后备缓冲区大小匹配的新深度模板视图(可选) ,并重置视口大小。

    由于此过程对应用程序做了一些假设,为简单起见,Win32 桌面教程中省略了它。此案例针对 Direct3D Win32 游戏模板、Windows Store DirectX 应用模板和 Windows phone DirectX 应用模板进行处理。

    对于 Windows 应用商店应用或 Windows 手机应用,没有“全屏独占模式”之类的东西,因此这些模板没有实现它。对于 Win32 桌面教程和 Direct3D Win32 游戏模板,我使用以下内容来确保我不必应付它:

    dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
    

    我希望重新研究如何扩展 Direct3D Win32 游戏模板以支持全屏独占模式,但我还没有开始。

    【讨论】:

    • 我不认为 ResizeBuffers 会改变窗口大小?您链接中的模板没有着色器代码,我确实需要独家全屏模式。其实我只是想创建一个固定大小的窗口,如果它恰好覆盖整个屏幕,我需要独占全屏。
    • 共有三种选择:(1) 固定大小的全屏窗口,不包含移动/调整大小的控件,(2) 固定大小的全屏窗口,不包含任何控件或边框(有时称为“假全屏”),(3)实际使用 DXGI 将其强制为专有全屏模式。
    • 这个问题已经很老了,但是作为刚刚研究过这个问题的人,在官方 DXGI 编程指南中有一段代码可以处理调整大小:docs.microsoft.com/en-gb/windows/win32/direct3ddxgi/…
    猜你喜欢
    • 2020-10-14
    • 1970-01-01
    • 2015-10-04
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多