glVertexAttribPointer提高GL_INVALID_OPERATION版本330

时间:2019-09-20 06:14:16

标签: opengl glfw

我正在尝试简化示例以显示确切的异常情况。我在MacOS 10.14.6上运行此示例,使用GLFW3编译clang LLVM编译器。另外,我试图在Windows 10/64上使用SFML运行相同的示例,并得到相同的错误,因此问题不在环境中

{first_name: "Firts Name", last_name: "Last Name", email: "a@gmail.com", phone: "+923045203200", password: "03045203200", …}
    accounting_method: "Cash"
    business_location: [{…}]
    business_location_name: "myLegalBusiness"
    business_name: "myLegalBusiness"
    business_phone: "0304520320055"
    business_system_name: "tradeName"
    confirm_p: "03045203200"
    currency: "ALL"
    currency_id: 1
    ein_ssn: "EIN34"
    email: "asad@gmail.com"
    first_name: "Firts Name"
    fy_end_month: "MARCH"
    last_name: "Last Name"
    logo: File {name: "users.png", lastModified: 1561615773639, lastModifiedDate: Thu Jun 27 2019 11:09:33 GMT+0500 (Pakistan Standard Time), webkitRelativePath: "", size: 2550, …}
    number_of_stores: 1
    password: "03045203200"
    phone: "+923045203200"
    store_name: "store"
    store_type: "Franchise"
    unique_code: "145dd" }

问题所在的确切代码

OpenGL version 4.1 ATI-2.11.20 
Shading language version 4.10

这是源代码完整

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);

在行

之前
#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;
}

在此行GL_INVALID_OPERATION之前和之后均未检测到错误。

程序输出为:

环境版本:

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

着色器参数名称:

OpenGL version 4.1 ATI-2.11.20
Shading language version 4.10

矩阵

Params: param_Position=0 param_MVPMatrix=1 param_Color=0

错误

-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 

我已经在这个问题上花了几天时间,没有更多的想法要穿上它。如有任何建议和澄清,我将不胜感激。

P.S。这是我系统的glfwinfo输出

OpenGL ERROR: 0x00000502 GL_INVALID_OPERATION

1 个答案:

答案 0 :(得分:1)

由于您使用的是核心配置文件上下文(GLFW_OPENGL_CORE_PROFILE),因此,如果您必须使用Vertex Array Object,则默认的Vertex Buffer Object 0无效。

当调用glVertexAttribPointer时,顶点数组规范存储在当前绑定的顶点数组对象的状态向量中。当前绑定到目标ARRAY_BUFFER的缓冲区与属性关联,并且对象的名称(值)存储在VAO的状态向量中。
在兼容性配置文件中,存在默认的顶点数组对象0,该对象可以随时使用,但这在核心配置文件上下文中无效。此外,在兼容性配置文件中不必使用VBO,glVertexAttribPointer的最后一个参数可以是指向顶点数据的指针。

最简单的解决方案是切换到兼容性配置文件GLFW_OPENGL_COMPAT_PROFILE

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

如果您不想这样做或您的系统不提供该功能,那么您必须阅读有关Vertex Specification的信息。在程序循环之前,创建一个顶点缓冲区对象和一个顶点数组对象:

// 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);

并在循环中使用它来绘制网格:

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);