如果我在调用 present 之前将 vew_port 更改为 canvas,为什么旧​​图像会闪烁?

why there is a flickering of old image if I change vew_port for canvas before calling present?

我在 Rust/SDL 中写了一个小演示,它可以实现图像的淡入和淡出,以及一些偶尔的随机规范。它超级流畅而且非常好,最高可达 250 fps。

我决定在每个具有随机尺寸的帧上添加 canvas.set_viewport 的更改。基本上,在随机位置以随机大小绘制相同的流纹理(在每一帧上填充新的色调或噪声)。

我发现已渲染的矩形存在(无法解释的)闪烁。

我试过截屏,但在视频上没有闪烁。我使用的是普通相机 (60fps),没有闪烁。我在我的 phone 中使用了高速模式并记录了闪烁,但它看起来与我看到的非常不同。

这是什么?

代码:https://github.com/amarao/sdl_random/tree/c4757190712f0a996c2aba88b105462942d4ca27/src

非闪烁屏幕截图:https://www.youtube.com/watch?v=Zud9Hjwltxk

闪烁视频(高速):https://youtu.be/rVZki9COuZ0

第二个问题:如果这是来自我的 GPU (nvidia) 的某种 'underfined behaviour',为什么会这样?是否支持动态更改视口?

编辑:我将对 set_viewport 的调用更改为 canvas.copyrect 参数:

canvas.copy(
   &texture, None,
   sdl2::rect::Rect::new(
      new_x as i32,
      new_y as i32,
      new_width,
      new_height
  )
).unwrap();

但结果完全一样。

这是由于双缓冲 (wikipedia). The render system uses two buffers in-tandem: one is being presented while the other is being written to. You can verify that this is enabled in SDL2 by checking video_system.gl_attrs().double_buffer().

您正在相同的缓冲区上迭代绘制,而没有清除或重新绘制它们。因此,一个缓冲区将绘制偶数帧的所有内容,而另一个缓冲区将绘制奇数帧。所以,闪烁是由于它们之间的内容大相径庭时交换造成的。