CraftedCart
CraftedCart

Reputation: 661

VAO renders fine on macOS, but INVALID_OPERATION on Linux

I have an application that uses OpenGL within a Qt Widgets application. I used to develop it on macOS where everything worked fine, before switching over to Linux. Now when I call glBindVertexArray(mesh->getVao());, OpenGL spits out INVALID_OPERATION.

Using AMD's CodeXL, I determined that mesh->getVao() retuened 2. I also used it to get a list of all OpenGL calls. Upon examining it, it seems to generate a VAO with the ID of 2, and there is no glDeleteVertexArrays within the call list. I even commented out the code that would delete the vertex array.

The call list, when it generates the VAO

The OpenGL docs state that the only reason glBindVertexArray could fail is if it is is not given zero, or a generated VAO.

Are there any other possible reasons why glBindVertexArray could spit out INVALID_OPERATION, despite the VAO existing, and why it could work on macOS but not on Linux?


A few code samples, if it helps

Mesh rendering

void renderMesh(const Resource::ResourceMesh *mesh) {
    //Set up textures
    for (unsigned int i = 0; i < mesh->getTextures().size(); i++) {
        glActiveTexture(GL_TEXTURE0 + i);
        mesh->getTextures().at(i)->getTexture()->bind();
    }
    static const int texIDs[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
    glUniform1iv(shaderTexID, MAX_SHADER_TEXTURES, texIDs);

    //Draw the mesh
    glBindVertexArray(mesh->getVao());
    qDebug() << "mesh == nullptr:" << (mesh == nullptr);
    glDrawElements(GL_TRIANGLES, mesh->getIndices().size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

VAO generation

//In ResourceMesh.hpp

protected:
    QVector<Model::Vertex> vertices;
    QVector<unsigned int> indices;
    QVector<Resource::ResourceTexture*> textures;

    GLuint vao;
    GLuint vbo;
    GLuint ebo;

//In ResourceMesh.cpp

void ResourceMesh::generateGlBuffers() {
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);

    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Model::Vertex), &vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    //Vertex positions
    glEnableVertexAttribArray(GLManager::VertexAttribs::VERTEX_POSITION);
    glVertexAttribPointer(GLManager::VertexAttribs::VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Model::Vertex), (void*) offsetof(Model::Vertex, position));

    //Vertex normals
    glEnableVertexAttribArray(GLManager::VertexAttribs::VERTEX_NORMAL);
    glVertexAttribPointer(GLManager::VertexAttribs::VERTEX_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Model::Vertex), (void*) offsetof(Model::Vertex, normal));

    //Vertex texture coordinates
    glEnableVertexAttribArray(GLManager::VertexAttribs::VERTEX_TEX_COORD);
    glVertexAttribPointer(GLManager::VertexAttribs::VERTEX_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(Model::Vertex), (void*) offsetof(Model::Vertex, texCoord));

    glBindVertexArray(0);
}

And if it helps, here's a screenshot of CodeXL, breaking at glBindVertexArray

AMD CodeXL

Upvotes: 0

Views: 81

Answers (1)

CraftedCart
CraftedCart

Reputation: 661

Solved in the comments - Turns out the VAO was being created on the wrong context. I guess the macOS implementation of Qt shares a context for everything, whereas on Linux, they're seperated.

Upvotes: 2

Related Questions