3

I have narrowed down the error to this OpenGL call:

glVertexAttribPointer(var.vertex, 4, GL_FLOAT, GL_FALSE, 0, 0);

there are no errors before it, and there is a GL_INVALID_OPERATION error after it. The output to my console is:

Error in Shader.cpp : bindMesh : 294
        OpenGL Error: Invalid Operation
        (0x502)
        Bound Buffer: 1
        var.vertex = 1

According to this, the only GL_INVALID_OPERATION condition that could apply is a bound buffer ID of 0. But the bound buffer ID is 1.

I'm checking (and printing) the error with:

printErrors();
int i = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &i);
printf("\tBound Buffer: %i\n", i);
printf("\tvar.vertex = %i\n", var.vertex);

where printErrors() is defined as

void PrintErrors(const char* file, const char* func, int line);
#define printErrors() PrintErrors(__BASE_FILE__,__func__,__LINE__)

void PrintErrors(const char* file, const char* func, int line)
{
    const char* errors[] = {
        "OpenGL Error: Invalid Enumeration\n",
        "OpenGL Error: Invalid Value\n",
        "OpenGL Error: Invalid Operation\n",
        "OpenGL Error: Invalid Frame-Buffer Operation\n",
        "OpenGL Error: Out of Memory\n",
        "OpenGL Error: Stack Underflow\n",
        "OpenGL Error: Stack Overflow\n",
    };

    uint32 i = glGetError();
    while (i != GL_NO_ERROR)
    {
        printf("Error in %s : %s : %i\n\t%s\t(0x%x)\n", file, func, line, errors[i - GL_INVALID_ENUM], i);
        i = glGetError();
    }
}

What's going wrong?

Edit:

var.vertex is found with:

var.vertex = glGetAttribLocation(programID, "Vertex");

and there is a check to ensure that var.vertex was found in the bound shader by an if-statement:

if (var.vertex != INVALID_SHADER_VARIABLE) // INVALID_SHADER_VARIABLE = 0xFFFFFFFF (-1 if it where a signed int)
{
    glBindBuffer(...);
    glBuffferData(...);
    glEnableVertexAttribArray(var.vertex);
    glVertexAttribPointer(var.vertex, 4, GL_FLOAT, GL_FALSE, 0, 0);
}
Wolfgang Skyler
  • 1,338
  • 1
  • 13
  • 26
  • You probably have a core profile context and no VAO bound. That is one of the "impossible" conditions that will generate this error. The manual pages are far from complete when it comes to errors like `GL_INVALID_OPERATION` or `GL_OUT_OF_MEMORY`. – Andon M. Coleman Feb 14 '14 at 03:01
  • check your shader_inputs are they correct... and check you're shader is compiling without linking errors – jpm Feb 14 '14 at 06:53
  • @AndonM.Coleman: I'm pretty sure it's a compatibility context right now. (OpenGL 3.0) Dang, has a complete list been composed, or is it just learned from experience? @whiteFang: Yes, shader inputs are correct, and shaders compile/link correctly. `glEnableVertexAttribArray` has been called aswell. – Wolfgang Skyler Feb 14 '14 at 15:24
  • 1
    @Wolfgang Skyler: can you check what ``glGetString(GL_VERSION)`` says? – Sergey K. Feb 14 '14 at 15:26
  • 1
    `OpenGL version: 3.0.10750 Core Profile Forward-Compatible ContextCreating node` (woops, that is core.) - ATI Radeon HD 4xxx – Wolfgang Skyler Feb 14 '14 at 15:44
  • 1
    @Wolfgang Skyler: then my answer is perfectly valid. – Sergey K. Feb 14 '14 at 17:07
  • "if zero is bound to the `GL_ARRAY_BUFFER` buffer object ...", the if condition checks for zero. The bound buffer is 1 (as stated in my question, with provided code checking it), thus passing the condition. – Wolfgang Skyler Feb 14 '14 at 17:17

1 Answers1

6

You must have a non-zero Vertex Array Object bound in an OpenGL 3.1 context without the extension GL_ARB_compatibility or a core profile context. This is one of the hidden conditions that will generate a GL_INVALID_OPERATION whenever you attempt to do anything related to vertex arrays (e.g. draw, setup vertex pointers, etc.)

The good news is this is a trivial issue to fix.

At minimum, all you need to do is generate (glGenVertexArrays (...)) and bind (glBindVertexArray (...)) a vertex array object when you initialize your program.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • I thought glBindBuffer(GL_ARRAY_BUFFER, ...) was all you needed. I guess you need a VAO too. – Wolfgang Skyler Feb 14 '14 at 17:34
  • Yeah, this changed with OpenGL 3.1. Vertex Array Objects are what actually store the vertex array pointers, if you do not have one active in newer versions of GL there is therefore no place to store this state. Thus, trying to set the state is an invalid operation. In compatibility profiles this is not an issue, vertex array state still exists as a part of the normal state machine. – Andon M. Coleman Feb 14 '14 at 17:36
  • Wow, I spent 2h with the same impossible GL_INVALID_OPERATION and it was exactly the missing VAO. Thanks, buddy! – fegemo Dec 28 '15 at 20:40