原文见:
http://www.kdab.com/opengl-in-qt-5-1-part-2/?utm_source=rss&utm_medium=rss&utm_campaign=opengl-in-qt-5-1-part-2 OpenGL in Qt 5.1 – Part 2Published: March 15, 2013 by Sean Harmer
Vertex Array ObjectsQt has
QOpenGLBuffer (and before that
QGLBuffer)to help manage various types of OpenGL buffer objects such asper-vertex attribute data and element index buffers. OpenGL also has asimple related container type call
Vertex Array Objects (VAOs) to help with managing sets of vertex buffer objects.
KDAB has added code to Qt 5.1 that encapsulates VAOs with the
QOpenGLVertexArrayObjectclass. Binding an instance of this class causes OpenGL to "remember"any vertex specification state that you then set up. We can laterrestore this vertex specification state very quickly by simplyre-binding the VAO itself. This allows us to very rapidly switch betweenvertex states for "objects" that we wish to draw in our renderingfunction:
- void Scene::initialize()
- {
- // Assumes we have a current QOpenGLContext and that
- // m_shaderProgram is a QOpenGLShaderProgram
-
- // Create VAO for first object to render
- m_vao1 = new QOpenGLVertexArrayObject( this );
- m_vao1->create();
- m_vao1->bind();
-
- // Setup VBOs and IBO (use QOpenGLBuffer to buffer data,
- // specify format, usage hint etc). These will be
- // remembered by the currently bound VAO
- m_positionBuffer.create();
- m_positionBuffer.setUsagePattern( QOpenGLBuffer::StreamDraw );
- m_positionBuffer.bind();
- m_positionBuffer.allocate( positionData,
- vertexCount * 3 * sizeof( float ) );
- m_shaderProgram.enableAttributeArray( "vertexPosition" );
- m_shaderProgram.setAttributeBuffer( "vertexPosition", GL_FLOAT, 0, 3 );
-
- m_colorBuffer.create();
- m_colorBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
- m_colorBuffer.bind();
- m_colorBuffer.allocate( colorData,
- vertexCount * 3 * sizeof( float ) );
- m_shaderProgram.enableAttributeArray( "vertexColor" );
- m_shaderProgram.setAttributeBuffer( "vertexColor", GL_FLOAT, 0, 3 );
-
- // Repeat for buffers of normals, texture coordinates,
- // tangents, ...
- ...
-
- // Create VAO for second object to render
- m_vao2 = new QOpenGLVertexArrayObject( this );
- m_vao2->create();
- m_vao2->bind();
-
- // Setup VBOs and IBO for next object
- ...
-
- // Rinse and repeat for other objects
- m_skyBoxVAO = new QOpenGLVertexArrayObject( this );
- ...
- }
-
- void Scene::render()
- {
- // Clear buffers
- m_funcs->glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- // Bind shader program, textures for first set of objects
- m_phongShaderProgram->bind();
- ...
-
- // Switch to the vertex data for first object and draw it
- m_vao1->bind();
- m_funcs->glDrawElements(...);
-
- // Switch to the vertex data for second object and draw it
- m_vao2->bind();
- m_funcs->glDrawElements(...);
-
- // Maybe change shader program, textures etc
- // and draw other objects
- m_skyboxShaderProgram->bind();
- ...
- m_skyboxVAO->bind();
- m_funcs->glDrawElements(...);
- ...
- }
VAOs were introduced with OpenGL 3 but are required for OpenGL 3.1and for OpenGL >=3.2 with the Core profile. In addition, VAOs areavailable via the GL_ARB_vertex_array_object orGL_OES_vertex_array_object extensions on OpenGL 2 and OpenGL ES 2respectively. The
QOpenGLVertexArrayObject will use the core feature if available or fall-back to the appropriate extension if available.
The use of VAOs can greatly simplify your rendering code and
make itfaster due to the OpenGL driver having to potentially do less sanitychecking than if doing more buffer operations.