glDrawElements invalid operation

Started by
4 comments, last by ATEFred 9 years, 10 months ago

Hello everyone. Need your help, because I'm already out of ideas.

While rendering my 3D scene, I'm getting the following error within my logging system:


OpenGL error in 'glDrawElements ( GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0 )' - 'Mesh.cpp:27' - invalid operation

Where Mesh.cpp:27 is the call to glDrawElements:


    void Mesh::Draw() {
        GL_CHECK ( glBindVertexArray ( vao ) );
        GL_CHECK ( glDrawElements ( GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0 ) );
        GL_CHECK ( glBindVertexArray ( 0 ) );
    }

GL_CHECK is a macro for digging all the OpenGL errors ( if any ).

VAO, VBO and IBO are created like that:


   void Mesh::PopulateBuffers () {
// --- create buffers
        if ( vao )
            GL_CHECK ( glDeleteVertexArrays ( 1, &vao ) );
        if ( vbo )
            GL_CHECK ( glDeleteBuffers ( 1, &vbo ) );
        if ( ibo )
            GL_CHECK ( glDeleteBuffers ( 1, & ibo ) );

        GL_CHECK ( glGenVertexArrays ( 1, &vao ) );
        GL_CHECK ( glBindVertexArray ( vao ) );
        GL_CHECK ( glGenBuffers ( 1, &vbo ) );
        GL_CHECK ( glGenBuffers ( 1, &ibo ) );
// --- layout setup BEGIN
        GL_CHECK ( glEnableVertexAttribArray ( 0 ) ); // vertices
        GL_CHECK ( glEnableVertexAttribArray ( 1 ) ); // texture coords
        GL_CHECK ( glEnableVertexAttribArray ( 2 ) ); // normals
        GL_CHECK ( glEnableVertexAttribArray ( 3 ) ); // tangents
        GL_CHECK ( glEnableVertexAttribArray ( 4 ) ); // bitangents
// --- layout setup END
        GL_CHECK ( glBindBuffer ( GL_ARRAY_BUFFER, vbo ) );

        GL_CHECK ( glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE,
                                           VERTEX_ELEMENTS_COUNT * sizeof ( float ), 0 ) ); // vert coords
        GL_CHECK ( glVertexAttribPointer ( 1, 2, GL_FLOAT, GL_FALSE,
                                           VERTEX_ELEMENTS_COUNT * sizeof ( float ), ( GLvoid* ) ( 3 * sizeof ( float ) ) ) ); // tex coords
        GL_CHECK ( glVertexAttribPointer ( 2, 3, GL_FLOAT, GL_FALSE,
                                           VERTEX_ELEMENTS_COUNT * sizeof ( float ), ( GLvoid* ) ( ( 3 + 2 ) * sizeof ( float ) ) ) ); // normals
        GL_CHECK ( glVertexAttribPointer ( 3, 3, GL_FLOAT, GL_FALSE,
                                           VERTEX_ELEMENTS_COUNT * sizeof ( float ), ( GLvoid* ) ( ( 3 + 2 + 3 ) * sizeof ( float ) ) ) ); // tangents
        GL_CHECK ( glVertexAttribPointer ( 4, 3, GL_FLOAT, GL_FALSE,
                                           VERTEX_ELEMENTS_COUNT * sizeof ( float ), ( GLvoid* ) ( ( 3 + 2 + 3 + 3 ) * sizeof ( float ) ) ) ); // bitangents
// ---- populate buffer with vertices
        GL_CHECK ( glBufferData ( GL_ARRAY_BUFFER,
                                  core::VERTEX_ELEMENTS_COUNT * vertices.size() * sizeof ( float ),
                                  &bufferData[ 0 ],
                                  GL_STATIC_DRAW ) );
// ---- populate another buffer with indices
        GL_CHECK ( glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, ibo ) );
        GL_CHECK ( glBufferData ( GL_ELEMENT_ARRAY_BUFFER,
                                  indices.size() * sizeof ( GLuint ),
                                  &indices[ 0 ],
                                  GL_STATIC_DRAW ) );
// ---- unbind VAO
        GL_CHECK ( glBindVertexArray ( 0 ) );
// ---- recalculate box
        RecalcAABB();
    }

I'm working with 3.3 core profile, all shaders are OK ( as for it could be one of the reasons for such errors ).

Must mention that everything is being rendered just fine, but in the same time I'm getting the storm of errors, and each one is pointing to the code above ( the glDrawElements call ).

Could anybody help? Or should I just ignore these error messages ?

Advertisement

Well, if you look at the documentation, there are only two conditions that produce a invalid operation.

Yes, you are right:

GL_INVALID_OPERATION is generated if a geometry shader is active and mode
is incompatible with the input primitive type of the geometry shader in the currently installed program object.
GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to an
enabled array or the element array and the buffer object's data store is currently mapped.

First one could be excluded, because non of the geometry shaders are used in here.

And the second one confuses me a bit.

How do I know that something is bound to an enabled array? What is the buffer object name here ? What is an enabled array? It's a vertex attrib array?

And how do I know that ' element array and the buffer object's data store is currently mapped.' ?

Upon creation, my VBOs and IBOs are only bound to the VAO and that's it. I never used them anywhere else.

Try adding an assert(vao && numIndices >= 0 && numIndices % 3 == 0); in 'void Mesh::Draw()'. If everything is drawing ok, but the error is being spammed, I assume it's something like you have one or two Meshes in the scene for which vao is null or similar.

If that doesn't help, I'd spin up AMD CodeXL (works on all GPUs, not just AMD) and take a trace of the GL calls with that. It will show the stream clearly and the state of the GL context at the time of the error.

Thank you, clb, that was really helpful.

I've checked for NULL VAOs and incorrect indices count and figured out that meshes like that are really presented within the scene.

Furthermore, I've disabled rendering for them and still every object in the scene is in it's place, which is verty strange. I assume that on the asset loading stage I'm getting some garbage or I'm creating some invalid objects without graphics component and trying to render them.

Another strange ( but not suprising ) thing is that on different GPUs I am getting different quantity of spam error messages. The maximum of verbosity is achieved on AMD HD6670, nVidia GT630 goes pretty the same, but nVidia GT740M is a silent dude :)

Will try my best with AMD CodeXL, thank you for advice.

P.S.

As for GPUs I've mentioned one interesting thing: the GT740M ( on which I am now ) is the only one, who refused to initialize the exact profile and version I demanded.

GT630 and HD6670 giving me 3.3 core profile, while the 740M gives 4.3 core ( I'm initializing with SDL2 and GLEW ).

Latest version of NV Nsight also supports ogl 4.x ( 4.2/4.3? can't remember exactly ). Was really helpful figuring these kind of errors out ( gl event list with highlighting for the dodgy calls ). Highly recommended if you have the required hardware.

This topic is closed to new replies.

Advertisement