title: VAO renders fine on macOS, but INVALID_OPERATION on Linux
body: <p>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 <code>glBindVertexArray(mesh-&gt;getVao());</code>, OpenGL spits out INVALID_OPERATION.</p>
  
  <p>Using AMD's CodeXL, I determined that <code>mesh-&gt;getVao()</code> retuened <code>2</code>. 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 <code>glDeleteVertexArrays</code> within the call list. I even commented out the code that would delete the vertex array.</p>
  
  <p><a href="https://i.stack.imgur.com/XKSj7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XKSj7.png" alt="The call list, when it generates the VAO"></a></p>
  
  <p>The OpenGL docs state that the only reason <code>glBindVertexArray</code> could fail is if it is is not given zero, or a generated VAO.</p>
  
  <p>Are there any other possible reasons why <code>glBindVertexArray</code> could spit out INVALID_OPERATION, despite the VAO existing, and why it could work on macOS but not on Linux?</p>
  
  <hr>
  
  <p>A few code samples, if it helps</p>
  
  <p>Mesh rendering</p>
  
  <pre class="lang-cpp prettyprint-override"><code>void renderMesh(const Resource::ResourceMesh *mesh) {
      //Set up textures
      for (unsigned int i = 0; i &lt; mesh-&gt;getTextures().size(); i++) {
          glActiveTexture(GL_TEXTURE0 + i);
          mesh-&gt;getTextures().at(i)-&gt;getTexture()-&gt;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-&gt;getVao());
      qDebug() &lt;&lt; "mesh == nullptr:" &lt;&lt; (mesh == nullptr);
      glDrawElements(GL_TRIANGLES, mesh-&gt;getIndices().size(), GL_UNSIGNED_INT, 0);
      glBindVertexArray(0);
  }
  </code></pre>
  
  <p>VAO generation</p>
  
  <pre class="lang-cpp prettyprint-override"><code>//In ResourceMesh.hpp
  
  protected:
      QVector&lt;Model::Vertex&gt; vertices;
      QVector&lt;unsigned int&gt; indices;
      QVector&lt;Resource::ResourceTexture*&gt; textures;
  
      GLuint vao;
      GLuint vbo;
      GLuint ebo;
  
  //In ResourceMesh.cpp
  
  void ResourceMesh::generateGlBuffers() {
      glGenVertexArrays(1, &amp;vao);
      glGenBuffers(1, &amp;vbo);
      glGenBuffers(1, &amp;ebo);
  
      glBindVertexArray(vao);
  
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Model::Vertex), &amp;vertices[0], GL_STATIC_DRAW);
  
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &amp;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);
  }
  </code></pre>
  
  <p>And if it helps, here's a screenshot of CodeXL, breaking at <code>glBindVertexArray</code></p>
  
  <p><a href="https://i.stack.imgur.com/LAGrz.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/LAGrz.png" alt="AMD CodeXL"></a></p>