QOpenGLVertexArrayObject 的用法

m47*_*47h 5 c++ opengl qt

我有一个关于 QT 中 VAO 的问题。正如这里所假设的,我编写了以下代码用于初始化:

void GLWidget::initializeGL() {
    vao.create();
    vao.bind();
    // setting up buffers
    buffer.create();
    buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    buffer.bind();
    buffer.allocate(vertices.data(), 3 * vertices.size() * sizeof(float));
    vao.release();

}
Run Code Online (Sandbox Code Playgroud)

在绘画阶段,我只需执行以下操作:

void GLWidget::paintGL() {
  // some other code
  vao.bind();
  if(shader_program->isLinked()) {
    shader_program->setUniformValue("mvpMatrix", p_matrix * v_matrix * m_matrix);
    // the interesting part about the buffer:
    shader_program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
    shader_program->enableAttributeArray("vertex");
    // the drawing
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());
    shader_program->disableAttributeArray("vertex");
  } 
  vao.release();
} 
Run Code Online (Sandbox Code Playgroud)

就我只处理一个 VAO 而言,这是有效的。但是,当使用多个 VAO 时,不会绘制任何内容或仅绘制一个“对象”(缓冲区)。每个对象的代码完全相同,因此绘图始终是

  1. 绑定VAO
  2. 将变量分配给着色器程序
  3. 画三角形
  4. 发布VAO

所以问题是如何使用包括不同缓冲区的多个 vao。

And*_*man 3

您错误地抽象了 GLSL 程序类。

程序本身不存储顶点数组指针和数组启用/禁用状态,而 VAO 则存储顶点数组指针和数组启用/禁用状态。您需要将代码直接移到注释:“关于缓冲区的有趣部分:”下面initializeGL (...),但是由于您的 GLSL 程序类当前设置的方式,您还需要重构它以及您的 VAO 类。

目前,没有任何命令initializeGL (...)实际上影响您的 VAO 的状态 - 您正在绑定和取消绑定 VAO,中间有一些不相关的命令(我将在下面解释)。


请注意,VAO 不会显式存储顶点缓冲区绑定,但数组指针与调用函数时绑定的任何 VBO 相关。然而, VAO确实存储元素缓冲区绑定(例如glDrawElements (...))。当您重新调整 VAO 课程时,这可能会成为重要的知识。

使用 VAO 时,您也不应该在绘制之前和之后启用和禁用数组,这是创建 VAO 的部分原因。您在绘制之前绑定一个 VAO,它负责启用它需要的所有数组并禁用它不需要的数组(应在您的initializeGL (...)函数中建立)。