c++ - QOpenGLVertexArrayObject 的使用

标签 c++ qt opengl

我有一个关于 QT 中 VAO 的问题。按理说here ,我写了下面一段代码用于初始化:

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();

}

在绘画阶段,我简单的做了以下几件事:

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();
} 

就我只处理一个 VAO 而言,这是可行的。但是,在使用多个 VAO 时,不会绘制任何内容或仅绘制一个“对象”(缓冲区)。每个对象的代码完全相同,所以绘图总是

  1. 绑定(bind)VAO
  2. 为着色器程序分配变量
  3. 画三角形
  4. 发布 VAO

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

最佳答案

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

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

目前 none initializeGL (...) 中的命令实际上会影响您的 VAO 的状态 - 您正在绑定(bind)和解除绑定(bind)VAO 中间有一些不相关的命令(我将在下面解释)。


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

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

关于c++ - QOpenGLVertexArrayObject 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20634627/

相关文章:

C++ copy c'tor 现在开始行动了。不清楚为什么

c++ - 如何在 Debian 上安装 Clang 11

python - 旋转 glViewport?

c++ - 头文件中的类定义 C++

c++ - 使用 Qpr​​ocess 或系统调用 R 时如何获取输出

python - 从 QNetworkCookie、PyQt4 打印 cookie

c++ - 如何在 C++/QT 中创建 Windows 服务?

ios - 面向 iPhone 开发人员的 Mac OS X 上的 OpenGL

java - 绘制没有纹理的第二个对象时出现问题

C++ new int[0]——它会分配内存吗?