3
\$\begingroup\$

so I've been trying to create a simpler way to draw polygons and and have come across the following issue:

When I call glBindVertexArray(m_VAO); it throws a GL_INVALID_OPERATION even though I have previously called these functions:

glGenVertexArrays(1, &m_VAO);
glBindVertexArray(m_VAO);

Why does this happen? The only description for this error officially is that I failed to call the lines above.

Here is the source with any relevant parts. Please note that I have the error pop up the line after this one, but it might be because of this current error.

Polygon::Polygon(const std::vector<GLfloat>& vertexArray,
         const char* vertShaderPath,
         const char* fragShaderPath)
    :m_vertexArray(vertexArray)
{
    // Created and linked shaders here...
    // ...
    // ...

    // Generate and bind vertex array object.
    glGenVertexArrays(1, &m_VAO);
    glBindVertexArray(m_VAO);

    // Generate and bind vertex buffer object.
    glGenBuffers(1, &m_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);

    //Send verticies to buffer's memory.
    glBufferData(GL_ARRAY_BUFFER,
         m_vertexArray.size() * sizeof(GLfloat),
         &m_vertexArray[0],
         GL_STATIC_DRAW);

    // Set up vertex attributes.
    glVertexAttribPointer(0,
              3,
              GL_FLOAT,
              GL_FALSE,
              3 * sizeof(GLfloat),
              (GLvoid*)0);

    // Enable the attributes at layout position 0.
    glEnableVertexAttribArray(0);

    //Unbind VBO and VAO.
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
};

// Destructor
Polygon::~Polygon()
{
    // De-allocated resources
    glDeleteVertexArrays(1, &m_VAO);
    glDeleteBuffers(1, &m_VBO);
}

void Polygon::draw()
{
    glUseProgram(m_shaderProgram);
    check_gl_error();
    glBindVertexArray(m_VAO); // GL_INVALID_OPERATION here
    check_gl_error();
    glDrawArrays(GL_TRIANGLES, 0, m_vertexArray.size()); // GL_INVALID_OPERATION here
    check_gl_error();
    glBindVertexArray(0);
    check_gl_error();
}

Let me know if you need any more info. Thanks!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Did you check that glGenVertexArrays succeeds and what's in m_VAO after the call? Also, do you have a GL3+ context? And how do you get your GL extension functions (like glBindVertexArray)? \$\endgroup\$
    – snake5
    Jul 2, 2015 at 8:28
  • \$\begingroup\$ There is no error output if I call check_gl_error(); after I create/bind it. Yes, my context is 3+(3.3). I get my functions with #include <GL/glew.h>. Thanks \$\endgroup\$
    – Moo
    Jul 2, 2015 at 18:58
  • 1
    \$\begingroup\$ Could it be that you're calling the destructor before "draw", perhaps by copying the instance of Polygon class? \$\endgroup\$
    – snake5
    Jul 2, 2015 at 19:30
  • \$\begingroup\$ That was exactly it. Do you want to post an answer so you can get credit? \$\endgroup\$
    – Moo
    Jul 2, 2015 at 20:30

2 Answers 2

5
\$\begingroup\$

Since m_VAO is valid in constructor but not in draw(), it seems that the destructor was called before draw(), perhaps by copying an instance of the Polygon class.

P.S. Errors like these could be prevented by following the Rule of three.

\$\endgroup\$
1
  • \$\begingroup\$ Using a debugger is also really helpful here - setting a breakpoint on the line that's causing the error and examining the values of variables would have shown the OP that the value of m_VAO was bad. \$\endgroup\$ Jul 9, 2018 at 15:41
5
\$\begingroup\$

There is another way this can happen (I just ran into this one myself); VAOs are like FBOs; they aren't shared between shared OpenGL contexts. That if, if you call glGenVertexArrays() from one shared context, you can't use those VAOs from other shared contexts. Unlike texture objects, VBOs, and a bunch of other OpenGL data, you need to create VAOs within the context that will be binding them.

(Of course, people generally advise against using shared contexts in the first place. But if you're using them anyway, this is something that can bite you!)

\$\endgroup\$
1
  • \$\begingroup\$ In my case, the different context was not intentional: I was loading a mesh from a "importFile" callback, which resulted to be in a different context. Thank you. \$\endgroup\$ Jan 20 at 16:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .