QOpenGL error : “Invalid VAO/VBO/pointer usage” “Array object is not active”

0

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 array 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.

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. and GL_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 the drawCubeGeometry method in the GeometryEngine class, where the position attribute are sent to the shaders and the draw call is issued. there seems to be a problem with the setAttributeBuffer and glDrawElements 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);
}

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 (in the fragment shader) to see if it works. I will focus on applying the texture later.