繁体   English   中英

Glium的高效2D渲染

[英]Efficient 2D rendering with Glium

我正在使用Glium为正在编写的仿真器进行渲染。 我拼凑了一些可行的方法(基于此示例 ),但我怀疑它的效率很低。 相关功能如下:

fn update_screen(display: &Display, screen: &Rc<RefCell<NesScreen>>) {
    let target = display.draw();

    // Write screen buffer
    let borrowed_scr = screen.borrow();
    let mut buf = vec![0_u8; 256 * 240 * 3];
    buf.clone_from_slice(&borrowed_scr.screen_buffer[..]);
    let screen = RawImage2d::from_raw_rgb_reversed(buf, SCREEN_DIMENSIONS);
    glium::Texture2d::new(display, screen)
        .unwrap()
        .as_surface()
        .fill(&target, MagnifySamplerFilter::Nearest);

    target.finish().unwrap();
}

在高层次上,这就是我正在做的:

  • 借用NesScreen ,它包含屏幕缓冲区,它是一个数组。
  • 将屏幕缓冲区克隆到向量中
  • 从矢量数据创建纹理并将其渲染

我的怀疑是,通过clone_from_slice克隆整个屏幕缓冲区确实效率很低。 RawImage2d::from_raw_rgb_reversed函数获取传递给它的向量的所有权,所以我不确定如何避免克隆该如何做。

因此,有两个问题:

  • 实际上效率低下吗? 我没有足够的渲染知识来直觉了解。

  • 如果是这样,是否有更有效的方法来做到这一点? 我已经对Glium进行了很多搜索,但是2D渲染并没有太多特定之处。

这将不是一个很好的答案,但是这里的一些内容可能会对您有所帮助。


首先:这真的效率低下吗? 这真的很难说,尤其是OpenGL部分,因为OpenGL性能在很大程度上取决于何时需要/请求同步。

至于屏幕缓冲区的克隆:您仅复制180kb,这并不过分。 我很快在计算机上对其进行了基准测试,克隆一个180kb的向量大约需要5µs,这的确不是很多。

请注意,您可以不使用任何方法来创建RawImage2d ,因为所有字段都是公共的。 这意味着,如果您自己创建反向矢量,则可以避免简单的5µs克隆。 但是使用glium使用的方法反转向量比克隆向量要慢得多。 在我的机器上,相同长度的向量需要170µs。 如果您只想达到60fps = 17ms每帧,这可能仍然可以忍受 ,但仍然不是很好。

您可以考虑在原始数组中使用正确的行顺序来避免此问题。 或者,您可以直接在其上绘制带有纹理的全屏四边形(每个屏幕角一个顶点),而不是直接将纹理复制到帧缓冲区。 当然,您需要一个网格,一个着色器以及所有这些东西,但是您可以通过调整纹理坐标来“反转”图像。

最后,不幸的是,我对GPU执行OpenGL命令所需的时间并不了解。 这不是最佳选择,因为OpenGL没有太多时间来安排您的命令,而是必须立即执行它们(强制同步)。 但这也许在您的情况下是无法避免的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM