首页 > 解决方案 > 使用 wgpu-ris 和 winit 调整窗口大小“抖动”

问题描述

我正在尝试一些 rust 代码,这些代码是对Learn WGPU 教程中所示代码的轻微重构,包括添加统一变换以在固定(像素)位置和大小处绘制对象。

我注意到,当我调整窗口大小时,我的框会急剧拉伸、挤压和抖动。

调整抖动大小

拉伸/变形遵循增量的大小和方向,一旦调整大小完成,盒子总是固定在正确的位置和大小

在此处输入图像描述

GifCam 的帧差异视图显示移动期间的拉伸程度

在此处输入图像描述

为了排除我对教程代码所做的任何更改,我克隆了存储库,构建并运行了“tutorial6-uniforms”,它显示了与调整大小相同的行为,在它们发生时拉伸和挤压形状。

在此处输入图像描述

将 println 添加到我的调整大小和渲染函数(并在 MainEventsCleared 上禁用重绘)甚至显示成对的调整大小事件和重绘

redraw called PhysicalSize { width: 800, height: 600 } // initial draw
resize called PhysicalSize { width: 799, height: 600 } // resize begins
redraw called PhysicalSize { width: 799, height: 600 }
resize called PhysicalSize { width: 774, height: 589 }
redraw called PhysicalSize { width: 774, height: 589 }

这一切都让我相信幕后发生了一些事情,也许在重绘完成之前首先拉伸框架以匹配窗口的新大小?有没有办法防止这种情况?当屏幕上有很多元素时,尤其是文本,这种效果会变得非常刺耳。更不用说大多数应用程序都不会受此影响,因此它看起来不专业且丑陋。

这是我的事件循环,我省略了其他代码以减小帖子大小,但如果有助于解决问题,我会添加更多代码,或者参考教程中的代码

event_loop.run(move |event, _, control_flow| {
    match event {
        Event::WindowEvent {
            ref event,
            window_id,
        } if window_id  == window.id() => {
            match event {
                // ...
                WindowEvent::Resized(physical_size) => {
                    renderer.resize(*physical_size);
                },
                _ => {}
            }
        },
        Event::RedrawRequested(_) => {
            match renderer.render() {
                Ok(_) => {},
                Err(e) => eprintln!("{:?}", e),
            }
        },
        // no change in observed resizing behavior with or without
        /*Event::MainEventsCleared => {
            window.request_redraw();
        },*/
        // ...
        _ => {}
    }
})

标签: rustgraphicsresizewgpu-rs

解决方案


我相信这是一个winit问题,它既将视图设置为自动调整大小,又不给应用程序在操作系统重绘调整大小的窗口之前重绘的机会。我还没有找到一个好的解决方法,所以我想唯一的途径是有人潜入winit代码。


推荐阅读