我有一个关于 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 时,不会绘制任何内容或仅绘制一个“对象”(缓冲区)。每个对象的代码完全相同,因此绘图始终是
所以问题是如何使用包括不同缓冲区的多个 vao。
您错误地抽象了 GLSL 程序类。
程序本身不存储顶点数组指针和数组启用/禁用状态,而 VAO 则存储顶点数组指针和数组启用/禁用状态。您需要将代码直接移到注释:“关于缓冲区的有趣部分:”下面initializeGL (...),但是由于您的 GLSL 程序类当前设置的方式,您还需要重构它以及您的 VAO 类。
目前,没有任何命令initializeGL (...)实际上影响您的 VAO 的状态 - 您正在绑定和取消绑定 VAO,中间有一些不相关的命令(我将在下面解释)。
glDrawElements (...))。当您重新调整 VAO 课程时,这可能会成为重要的知识。
使用 VAO 时,您也不应该在绘制之前和之后启用和禁用数组,这是创建 VAO 的部分原因。您在绘制之前绑定一个 VAO,它负责启用它需要的所有数组并禁用它不需要的数组(应在您的initializeGL (...)函数中建立)。