QOpenGL "Cube" example error : “Invalid VAO/VBO/pointer usage” “Array object is not active”
-
Hello everyone,
I'm currently trying to render a skybox using the QOpenGL library of Qt. For that, I tried to modify the QOpenGL "cube" example that is provided by Qt (I'm using the latest Qt 5.13 version).
The vertex and index buffers are initialized in a class called
GeometryEngine
, in which vertex and index arrays are defined as well. In the example, the vertex array has texture coordinates, so I got rid of those and kept only the position coordinates, because every operation regarding the skybox texture will be done in the shaders.There's also a function called
initTextures
in the window class that I modified to load the textures of the 6 faces of the cube (I don't know if this part is correct though).I also set up an OpenGL debug Logger using this example : https://www.trentreed.net/blog/qt5-opengl-part-5-debug-logging/.
When I execute the code, I only get a window with a black screen and nothing rendered and the following error messages :
GL_INVALID_OPERATION error generated. Invalid VAO/VBO/pointer usage.
andGL_INVALID_OPERATION error generated. Array object is not active.
Has anynone encountered this issue before and fixed it ? Because I don't think I forgot any part of the rendering process. I only modified the input data and the shaders (but I got no error from that part).
First, I thought the core of the problem was due to the vertex and index array, so I tried to use only a vertex buffer by repeating the vertices for each triangle in the vertex array, but I got the same error messages.
Since I got no compile error, I tried to locate the problem by using the
#if 0 [...] #endif
on each functions until I got no OpenGL error messages. I finally isolated the origin in thedrawCubeGeometry
method in theGeometryEngine
class, where the position attribute are sent to the shaders and the draw call is issued. there seems to be a problem with thesetAttributeBuffer
andglDrawElements
calls, but I can't figure it out.I tried looking for solutions online but there is so little questions asked about QOpenGL.
In
GeometryEngine.cpp
:void GeometryEngine::initCubeGeometry() { QVector3D vertices[] = { // Vertex data for face 0 QVector3D(-1.0f, -1.0f, 1.0f), // v0 QVector3D( 1.0f, -1.0f, 1.0f), // v1 QVector3D(-1.0f, 1.0f, 1.0f), // v2 QVector3D( 1.0f, 1.0f, 1.0f), // v3 // Vertex data for face 1 QVector3D( 1.0f, -1.0f, 1.0f), // v4 QVector3D( 1.0f, -1.0f, -1.0f), // v5 QVector3D( 1.0f, 1.0f, 1.0f), // v6 QVector3D( 1.0f, 1.0f, -1.0f), // v7 // Vertex data for face 2 QVector3D( 1.0f, -1.0f, -1.0f), // v8 QVector3D(-1.0f, -1.0f, -1.0f), // v9 QVector3D( 1.0f, 1.0f, -1.0f), // v10 QVector3D(-1.0f, 1.0f, -1.0f), // v11 // Vertex data for face 3 QVector3D(-1.0f, -1.0f, -1.0f), // v12 QVector3D(-1.0f, -1.0f, 1.0f), // v13 QVector3D(-1.0f, 1.0f, -1.0f), // v14 QVector3D(-1.0f, 1.0f, 1.0f), // v15 // Vertex data for face 4 QVector3D(-1.0f, -1.0f, -1.0f), // v16 QVector3D( 1.0f, -1.0f, -1.0f), // v17 QVector3D(-1.0f, -1.0f, 1.0f), // v18 QVector3D( 1.0f, -1.0f, 1.0f), // v19 // Vertex data for face 5 QVector3D(-1.0f, 1.0f, 1.0f), // v20 QVector3D( 1.0f, 1.0f, 1.0f), // v21 QVector3D(-1.0f, 1.0f, -1.0f), // v22 QVector3D( 1.0f, 1.0f, -1.0f) // v23 }; GLushort indices[] = { 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16, 16, 17, 18, 19, 19, 20, 20, 21, 22, 23 }; // Transfer vertex data to VBO 0 arrayBuf.bind(); arrayBuf.allocate(vertices, 24 * sizeof(QVector3D)); // Transfer index data to VBO 1 indexBuf.bind(); indexBuf.allocate(indices, 34 * sizeof(GLushort)); } void GeometryEngine::drawCubeGeometry(QOpenGLShaderProgram *program) { // Tell OpenGL which VBOs to use arrayBuf.bind(); indexBuf.bind(); // Offset for position quintptr offset = 0; // Tell OpenGL programmable pipeline how to locate vertex position data int vertexLocation = program->attributeLocation("a_position"); program->enableAttributeArray(vertexLocation); program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(QVector3D)); // Draw cube geometry using indices from VBO 1 glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0); }
In
GLWidget.cpp
:void GLWidget::paintGL() { // Clear color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); texture->bind(); // Calculate model view transformation QMatrix4x4 matrix; matrix.translate(0.0, 0.0, 0.0); matrix.rotate(rotation); // Set modelview-projection matrix program.setUniformValue("mvp_matrix", projection * matrix); // Use texture unit 0 which contains cube.png program.setUniformValue("texture", 0); // Draw cube geometry geometries->drawCubeGeometry(&program); }
For now I only try to display a red cube (with the fragment shader) to see if it works. I will focus on applying the texture once I get this fixed.