c++ - 调用 glBindVertexArray(vao) : what does it do if 'vao' is already bound, 以及如何相应地设计形状类?

标签 c++ opengl vertex-array-object

我正在再次尝试 OpenGL,我想知道如何设计稍后呈现的类。现在,只有一种类型的形状,所以我创建了一个 Shape 类,它有一个静态 VAO 成员,当第一个时调用 glGenVertexArrays(1, &vao) Shape 实例被创建。现在有一个方法void Shape::render():

void Shape::render()
{
  glBindVertexArray(vao);
  glDrawArrays(GL_TRIANGLES, foo, bar);
}

这是个好方法吗?我的意思是,当 Shape 的所有实例都在实际程序中绘制时,会重复调用绑定(bind) Shape::vao,但我猜它不会如果 vao 当前已经绑定(bind),则实际上不执行任何操作。猜对了吗?

另外,前段时间看到一个教程,在render()的最后调用了glBindVertexArray(0)。当有很多形状时,这不是潜在的性能损失吗?

最佳答案

but my guess would be that it doesn't actually do anything if vao is already bound currently. Is that guess correct?

是的。就正确性而言,重新绑定(bind)已经绑定(bind)的东西不是问题。

不过,它可能会增加一点性能损失。在这种情况下,一个合理的 GL 实现可能不会做太多事情,但是您仍然可以调用 GL 库,它必须在它有机会什么都不做之前找到线程的当前上下文。因此,可能如果您将当前的 VAO 缓存在您身边并且只在它实际发生变化时才调用 GL,您的情况可能会更好。但这是只有分析/基准测试才能告诉您的事情。如果您有数千甚至数百万个实例,那可能会成为一个真正的问题 - OTOH,如果每个实例都有一个单独的绘制调用,那么无论如何你都会被搞砸 - 在这种情况下你应该研究实例化渲染。

Also, I saw a tutorial some time ago that used to call glBindVertexArray(0) at the end of render(). Wouldn't that be a potential performance loss when there are many shapes?

是的。大多数教程这样做是为了一些“清洁”,但在大多数情况下这确实是在浪费时间。如果您可以(并且实际上打算)在“未绑定(bind)”状态下执行某些操作,则取消绑定(bind)某些 GL 对象只是一个有用的操作——比如 FBO 0,它只是默认的帧缓冲区。对于 VAO,在核心配置文件中,VAO 0 完全没用,无论如何你都必须在绘制之前绑定(bind)一个 - 所以你通过取消绑定(bind)中间的任何其他 VAO 没有任何好处。

关于c++ - 调用 glBindVertexArray(vao) : what does it do if 'vao' is already bound, 以及如何相应地设计形状类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25099253/

相关文章:

c++ - 设置每个像素的最快方法

c++ - 为什么这个 C++/OpenGL 程序运行两次?

c++ - 在类修改器中使用 assert() 是好的做法吗?

c++ - equal_to<key> boost::无序 multimap

c++ - vector 引用 C++

c - OpenGL - glVertex2f(x, y) 中的 x 和 y 之间的映射到屏幕整数坐标

c++ - 无法通过glGetBufferSubData获取缓冲区对象数据

c++ - 在 OpenGL 中设置 VAO 的过程

opengl-es - 如何将 GLSL #version 330 核心转换为 GLSL ES #version 100?

c++ - 隐藏基类中的所有重载方法