最近在做一個opengl的項目,我需要實現(xiàn)的是打開一個mesh數(shù)據(jù)然后經(jīng)過opengl進(jìn)行渲染。發(fā)現(xiàn)一個問題,當(dāng)我先加載網(wǎng)格的頂點數(shù)據(jù)到array中,然后再調(diào)用初始化initializeGL(), 然后paintGL() 這個流程沒問題。但是由于我自己重寫了openglwidget,所以控件加載完畢之后肯定會調(diào)用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();
}
這里已經(jīng)綁定了頂點數(shù)據(jù),但是由于我開始沒有加載模型數(shù)據(jù),因此這個m_meshVertxArray是空的。那么我們就需要加載完畢之后進(jìn)行更新數(shù)據(jù)。試了很多次,把initializeGL代碼放到updateVertices之后也不行。一直沒有圖像或者崩潰,后來我讀了 Qt官方關(guān)于opengl的例子的helloQt 里面有一個函數(shù)
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<void *>(3 * sizeof(GLfloat)));
m_logoVbo.release();
}
我在想他為什么要單獨寫成一個函數(shù),讀一下邏輯就是再更新vbo的操作。因此我測試了一下,在更新完頂點數(shù)據(jù)之后更新vbo的數(shù)據(jù),果然可以顯示了。
結(jié)論:vao和vbo的創(chuàng)建必須要在opengl的上下文中進(jìn)行,我找資料又看到,后面可以更新一下鏈接,因此vao和vbo的創(chuàng)建需要在initializeGL函數(shù)里面,而不能再別的地方。其他地方需要更新vbo的數(shù)據(jù)即可,不能再次創(chuàng)建