Reputation: 661
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 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
Upvotes: 0
Views: 81
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