关于VAO和VBO创建和更新的问题

最近在做一个opengl的项目,我需要实现的是打开一个mesh数据然后经过opengl进行渲染。发现一个问题,当我先加载网格的顶点数据到array中,然后再调用初始化initializeGL(), 然后paintGL() 这个流程没问题。但是由于我自己重写了openglwidget,所以控件加载完毕之后肯定会调用initializeGL,但是intializeGL的代码如下

void ViewGLWidget::initializeGL()
{

    initializeOpenGLFunctions();
    //set the background color of the opengl window
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

    initShader();

    m_vao.create();
    m_vao.bind();
    m_vbo = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
    m_vbo.create();
    m_vbo.bind();

    //m_meshVertxArray stores all the vertices, one vertex 
    m_vbo.allocate((void *)m_meshVertxArray.data(), sizeof(GLfloat) * m_meshVertxArray.size()*3);
    m_shader.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(GLfloat)* 3);
    m_shader.enableAttributeArray(0);
    m_vbo.release();
    m_vao.release();
}

这里已经绑定了顶点数据,但是由于我开始没有加载模型数据,因此这个m_meshVertxArray是空的。那么我们就需要加载完毕之后进行更新数据。试了很多次,把initializeGL代码放到updateVertices之后也不行。一直没有图像或者崩溃,后来我读了 Qt官方关于opengl的例子的helloQt 里面有一个函数

void GLWidget::setupVertexAttribs()
{
    m_logoVbo.bind();
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    f->glEnableVertexAttribArray(0);
    f->glEnableVertexAttribArray(1);
    f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
                             nullptr);
    f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
                             reinterpret_cast(3 * sizeof(GLfloat)));
    m_logoVbo.release();
}

我在想他为什么要单独写成一个函数,读一下逻辑就是再更新vbo的操作。因此我测试了一下,在更新完顶点数据之后更新vbo的数据,果然可以显示了。
结论:vao和vbo的创建必须要在opengl的上下文中进行,我找资料又看到,后面可以更新一下链接,因此vao和vbo的创建需要在initializeGL函数里面,而不能再别的地方。其他地方需要更新vbo的数据即可,不能再次创建

你可能感兴趣的:(关于VAO和VBO创建和更新的问题)