glVertexAttribPointer raise GL_INVALID_OPERATION version 330

1

I am trying to simplify my example to show exact abnormal case. I am running this example on MacOS 10.14.6, compiling clang LLVM compiler, using GLFW3. Also I am trying to run same example on Windows 10/64 using SFML and got same error, therefore the problem is not in the environment

OpenGL version 4.1 ATI-2.11.20 
Shading language version 4.10

Exact code where problem is

glUseProgram(id_shader);
glEnableVertexAttribArray(param_Position);
//HERE IS ERROR "OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION" RAISED
glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, vertices);

Here is source full code

#include <stdlib.h>
#include <OpenGL/gl3.h>
#include <GLFW/glfw3.h>

#include "engine/Camera.h"

static const char *get_error_string_by_enum(GLenum err)
{
    switch (err) {
        case GL_INVALID_ENUM :
            return "GL_INVALID_ENUM";
        case GL_INVALID_VALUE :
            return "GL_INVALID_VALUE";
        case GL_INVALID_OPERATION :
            return "GL_INVALID_OPERATION";
        case GL_STACK_OVERFLOW :
            return "GL_STACK_OVERFLOW";
        case GL_STACK_UNDERFLOW :
            return "GL_STACK_UNDERFLOW";
        case GL_OUT_OF_MEMORY :
            return "GL_OUT_OF_MEMORY";
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION
        case GL_INVALID_FRAMEBUFFER_OPERATION :
            return "GL_INVALID_FRAMEBUFFER_OPERATION";
#endif
        default: {
            return "UNKNOWN";
        }
    }
}

static void check_gl()
{
    char line[300];
    GLenum err;

    err = glGetError();
    if (err != GL_NO_ERROR) {
        sprintf(line, "OpenGL ERROR: 0x%.8X %s", err, get_error_string_by_enum(err));
        printf("%s\n", line);
        exit(-1);
    }
}

int main()
{
    char line[2000];
    unsigned int windowWidth = 1024;
    unsigned int windowHeight = 1024;

    GLFWwindow* window;

    //SETUP WINDOW AND CONTEXT
    if (!glfwInit()){
        fprintf(stdout, "ERROR on glfwInit");
        return -1;
    }
    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    window = glfwCreateWindow(windowWidth, windowHeight, "OpenGL", NULL, NULL);
    if (!window)
    {
        fprintf(stderr, "Unable to create window.");
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    sprintf(line, "OpenGL version %s\n", (const char *) glGetString(GL_VERSION));
    fprintf(stdout, line);
    sprintf(line, "Shading language version %s\n", (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION));
    fprintf(stdout, line);

    //SETUP OPENGL
    glViewport(0, 0, windowWidth, windowHeight);
    glEnable(GL_BLEND);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glDepthMask(true);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //SETUP SHADER PROGRAM
    GLint success;
    GLuint id_v = glCreateShader(GL_VERTEX_SHADER);
    GLuint id_f = glCreateShader(GL_FRAGMENT_SHADER);

    const char *vertex_shader_source = "#version 330\n"
                                       "precision mediump float;\n"
                                       "\n"
                                       "in vec4 Position;\n"
                                       "uniform mat4 MVPMatrix;\n"
                                       "\n"
                                       "void main()\n"
                                       "{\n"
                                       "\tgl_Position = MVPMatrix * Position;\n"
                                       "\tgl_PointSize = 10.0;\n"
                                       "}";
    const char *fragment_shader_source = "#version 330\n"
                                         "precision mediump float;\n"
                                         "\n"
                                         "uniform vec4 Color;\n"
                                         "out vec4 FragCoord;\n"
                                         "\n"
                                         "void main()\n"
                                         "{\n"
                                         "  FragCoord = Color;\n"
                                         "}";

    glShaderSource(id_v, 1, &vertex_shader_source, NULL);
    glCompileShader(id_v);
    glGetShaderiv(id_v, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(id_v, 2000, NULL, line);
        fprintf(stderr, line);
        exit(-1);
    }

    glShaderSource(id_f, 1, &fragment_shader_source, NULL);
    glCompileShader(id_f);
    glGetShaderiv(id_f, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(id_f, 2000, NULL, line);
        fprintf(stderr, line);
        exit(-1);
    }

    GLuint id_shader = glCreateProgram();
    glAttachShader(id_shader, id_v);
    glAttachShader(id_shader, id_f);
    glLinkProgram(id_shader);
    glGetProgramiv(id_shader, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(id_shader, 2000, NULL, line);

        fprintf(stderr, "program link error");
        fprintf(stderr, line);
        exit(-1);
    }
    GLuint param_Position = glGetAttribLocation(id_shader, "Position");
    GLuint param_MVPMatrix = glGetUniformLocation(id_shader, "MVPMatrix");
    GLuint param_Color = glGetUniformLocation(id_shader, "Color");
    sprintf(line, "Params: param_Position=%d param_MVPMatrix=%d param_Color=%d\n", param_Position, param_MVPMatrix, param_Color);
    fprintf(stdout, line);

    //SETUP MATRIX
    Camera *c = new Camera();
    c->setCameraType(CameraType::PERSPECTIVE);
    c->setWorldSize(100, 100);
    c->lookFrom(5, 5, 5);
    c->lookAt(0, 0, 0);
    c->setFOV(100);
    c->setUp(0, 0, 1);
    c->calc();
    c->getResultMatrix().dump();

    //SETUP TRIANGLE
    float vertices[] = {
            0, 0, 0,
            1, 0, 0,
            1, 1, 0
    };

    while (!glfwWindowShouldClose(window))
    {
        //CLEAR FRAME
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.3f, 0.3f, 0.3f, 1.0f);

        //RENDER TRIANGLE
        glUseProgram(id_shader);
        glUniformMatrix4fv(param_MVPMatrix, 1, (GLboolean) false, c->getResultMatrix().data);
        glUniform4f(param_Color, 1.0f, 0.5f, 0.0f, 1.0f);
        glEnableVertexAttribArray(param_Position);
        check_gl();
        //HERE IS ERROR "OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION" RAISED
        glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, vertices);
        check_gl();
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);

        glfwPollEvents();
    }

    glfwTerminate();

    return 0;
}

Before line

glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, vertices);

No errors detected before and just after this line GL_INVALID_OPERATION raised.

Program output is:

Environment versions:

OpenGL version 4.1 ATI-2.11.20
Shading language version 4.10

Shader param names:

Params: param_Position=0 param_MVPMatrix=1 param_Color=0

Matrix

-0.593333 -0.342561 -0.577350 -0.577350 
0.593333 -0.342561 -0.577350 -0.577350 
0.000000 0.685122 -0.577350 -0.577350 
0.000000 0.000000 8.640252 8.660253 

Error

OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION

I already spent few days on that problem and have no more idea to put it on. I would be grateful for any advice and clarifications.

P.S. Here is glfwinfo output for my system

/glfwinfo -m3 -n2 --profile=compat
GLFW header version: 3.4.0
GLFW library version: 3.4.0
GLFW library version string: "3.4.0 Cocoa NSGL EGL OSMesa"
OpenGL context version string: "4.1 ATI-2.11.20"
OpenGL context version parsed by GLFW: 4.1.0
OpenGL context flags (0x00000001): forward-compatible
OpenGL context flags parsed by GLFW: forward-compatible
OpenGL profile mask (0x00000001): core
OpenGL profile mask parsed by GLFW: core
OpenGL context renderer string: "AMD Radeon R9 M370X OpenGL Engine"
OpenGL context vendor string: "ATI Technologies Inc."
OpenGL context shading language version: "4.10"
OpenGL framebuffer:
 red: 8 green: 8 blue: 8 alpha: 8 depth: 24 stencil: 8
 samples: 0 sample buffers: 0
Vulkan loader: missing
opengl
glfw
asked on Stack Overflow Sep 20, 2019 by IPMan82 • edited Sep 20, 2019 by IPMan82

1 Answer

1

Since you use a core profile context (GLFW_OPENGL_CORE_PROFILE), the default Vertex Array Object 0 is not valid further you've to use Vertex Buffer Object.

When glVertexAttribPointer is called, then the vertex array specification is stored in the state vector of the currently bound vertex array object. The buffer which is currently bound to the target ARRAY_BUFFER is associated to the attribute and the name (value) of the object is stored in the state vector of the VAO.
In compatibility profile there exists the default vertex array object 0, which can be used at any time but this is not valid in a core profile context. Further it is not necessary in a compatibility profile to use a VBO, the last parameter of glVertexAttribPointer can be a pointer to the vertex data.

The easiest solution is to switch to a compatibility profile GLFW_OPENGL_COMPAT_PROFILE:

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

If you don't want to do that or your system doesn't provide that, then you've to read about Vertex Specification. Create a vertex buffer object a vertex array object before the program loop:

// vertex buffer object
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

// vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo); // this is not necessary, because "vbo" is still bound 
glVertexAttribPointer(param_Position, 3, GL_FLOAT, (GLboolean) false, 0, nullptr);

// the following is not necessary, you can let them bound
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

And use it in the loop to draw the mesh:

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
answered on Stack Overflow Sep 20, 2019 by Rabbid76 • edited Sep 20, 2019 by BDL

User contributions licensed under CC BY-SA 3.0