OpenGL 不会使用着色器渲染 Mac

OpenGL Won't Render With Shaders Mac

我正在尝试让 OpenGL 在我配备 M1 芯片的较新 Macbook Pro 上渲染带有着色器的基本三角形。我也一直在使用 Qt Creator。

我能够设置它并获得基本的固定管道场景渲染,但是当我将版本更改为使用现代 OpenGL 时,我得到的版本是 4.1,即使我将它设置为 3.2。

以下是我设置版本的方法:

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setProfile(QSurfaceFormat::CoreProfile);
    format.setMajorVersion(3);
    format.setMinorVersion(2);
    QSurfaceFormat::setDefaultFormat(format);
    this->setFormat(format); // must be called before the widget or its parent window gets shown

当我打印出着色器源代码时,我可以看到我得到的正是我放入顶点着色器和片段着色器文件中的内容,因此我知道我正在正确加载文件。下面是我在着色器中使用它们的方式 class:

programID = glCreateProgram(); // Creates the program ID
vs = glCreateShader(GL_VERTEX_SHADER); // Creates the vertex shader
fs = glCreateShader(GL_FRAGMENT_SHADER); // Creates the fragment shader

// Shader reading code removed...

    const char* vSrc = vSource.c_str();
    int size = vSource.size();
    glShaderSource(vs, 1, &vSrc, &size);
    glCompileShader(vs);

    int result;
    glGetShaderiv(vs, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        int length;
        glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &length);
        char* msg = new char[length];
        glGetShaderInfoLog(vs, length, &length, msg);
        std::cout << "Vertex Shader Message:\n" << msg << std::endl;
        exit(1);
    }

    const char* fSrc = fSource.c_str();
    int size2 = fSource.size();
    glShaderSource(fs, 1, &fSrc, &size2);
    glCompileShader(fs);

    int result2;
    glGetShaderiv(fs, GL_COMPILE_STATUS, &result2);
    if (result2 == GL_FALSE)
    {
        int length;
        glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &length);
        char* msg = new char[length];
        glGetShaderInfoLog(fs, length, &length, msg);
        std::cout << "Fragment Shader Message:\n" << msg << std::endl;
        exit(1);
    }


    glAttachShader(programID, vs);
    glAttachShader(programID, fs);
    glLinkProgram(programID);
    glValidateProgram(programID);

然后在我的 initOpenGL 函数中我有:

    float positions[6] =
    {
        -0.5, -0.5,
         0.0,  0.5,
         0.5, -0.5
    };

    glGenBuffers(1, &currentBuffer); // Generates the buffer
    glBindBuffer(GL_ARRAY_BUFFER, currentBuffer); // Binds it before we use it
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); // Sends the data to OpenGL

    glEnableVertexAttribArray(0); // Enables the buffer layout
    glBindBuffer(GL_ARRAY_BUFFER, currentBuffer);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); // Tells OpenGL how we stored the data

    s = new Shader("main.vsh", "main.fsh");
    glUseProgram(s->getShaderID());

然后,我在渲染函数中使用以下调用渲染数据:

    glDrawArrays(GL_TRIANGLES, 0, 3);

这是顶点着色器代码:

#version 410 core
layout (location = 0) in vec4 position;
void main()
{
    gl_Position = position;
}

片段着色器代码如下:

#version 410 core
layout (location = 0) out vec4 color;
void main(void)
{
    color = vec4(1.0, 0.0, 0.0, 1.0);
}

这不是着色器的问题。但是在核心配置文件 OpenGL Context you have to create Vertex Array Object 中,因为默认的 VAO (0) 无效。这不是可选的:

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glEnableVertexAttribArray(0); // Enables the buffer layout
glBindBuffer(GL_ARRAY_BUFFER, currentBuffer);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0)

您必须在指定顶点之前绑定 VAO。顶点规范存储在 VAO 中。

绘制网格时使用存储在当前绑定的 VAO 中的顶点规范。因此,您也需要确保在绘图命令之前绑定了 VAO:

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