首页 > 解决方案 > 通过结构在 Rust 中使用 OpenGL 方法而不是全局访问它们有什么优势?

问题描述

我目前正在将一个用 C++ 编写的 OpenGL 应用程序移植到 Rust,并且遇到了一个可能有其他含义的设计问题,因为我对 Rust 还很陌生。

截至目前,我正在使用glutin和的组合gl_generator。在 bindings 模块中生成全局函数会产生以下 API:

gl::load_with(|symbol| context.get_proc_address(symbol));
// anywhere else since it's global
gl::CreateProgram();

这与我在 C++ 中用于访问全局方法的包装类的范例几乎相同:

// ...
FShader::~FShader() {
  if (Handle != 0) {
    glDeleteProgram(Handle);
  }
}

auto FShader::bind() const -> void { glUseProgram(Handle); }
// ...

在阅读了互联网上的更多帖子后,我注意到有些人建议使用结构生成器并使用对象而不是全局方法。

let gl = Rc::new(gl::Gl::load_with(|symbol| context.get_proc_address(symbol)));
// ...
pub struct Shader {
    gl: Rc<gl::Gl>,
    handle: u32,
}

impl Drop for Shader {
    fn drop(&mut self) {
        unsafe {
            self.gl.DeleteProgram(self.handle);
        }
    }
}

impl Shader {
    pub fn new(gl: Rc<gl::Gl>) -> Result<Shader, ()> {
        let handle = unsafe { gl.CreateProgram() };
        // ...
        Ok(Shader { gl, handle })
    }
}

这种方法肯定更冗长,因为所有包装类都必须存储gl::Gl对象的引用才能释放资源。的签名Drop::drop似乎是为什么需要跨对象共享引用的原因。这样做还有其他好处吗?使用Rc最佳方法还是使用常规参考更合理?

标签: c++openglrust

解决方案


推荐阅读