为什么我无法通过 GLFW 获得向前兼容的 OpenGL 上下文?

Why am I not getting a forward compatible OpenGL context with GLFW?

据我所知,当我在 GLFW 上设置这些上下文约束时:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

我应该在运行的机器上获得最大可用的 OpenGL 上下文,前提是它高于 OpenGL 3.3。但是,通过使用 glGetString 获取 OpenGL 上下文版本,我发现情况并非如此。每次我查询 glGetString 上下文版本时,我只会得到我用 glfwWindowHint 设置的主要版本和次要版本,上面没有。请记住,我的 GPU 支持 OpenGL 4.5。

还有一点要注意,当我不设置任何约束时,我实际上得到了一个 OpenGL 4.5 上下文。

这是完整的源代码,它似乎复制了问题:

#define GLEW_STATIC

#include <iostream>

#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <glm\glm.hpp>

int main(int argc, char argv[])
{

    if (!glfwInit())
    {
        std::cerr  << "Failed to initialize GLFW 3.0.4" << std::endl;
        getchar();

        glfwTerminate();
        return -1;
    }

    std::cout << "Initialized GLFW 3.0.4" << std::endl;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* m_window = glfwCreateWindow(640, 480, "Koala", NULL, NULL);

    if (!m_window)
    {
        std::cerr  << "Failed to create OpenGL 3.3+ context" << std::endl;
        getchar();
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(m_window);

    std::cout << "Created OpenGL 3.3+ context" << std::endl;

    glewExperimental = GL_TRUE;

    if (glewInit() != GLEW_OK)
    {
        std::cerr << "Failed to initialize GLEW 1.11.0" << std::endl;
        getchar();
        glfwTerminate();
        return -1;
    }

    std::cout << "Initialized GLEW 1.11.0" << std::endl;

    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);

    std::cout << "GPU: " << renderer << std::endl;
    std::cout << "OpenGL Version: " << version << std::endl;

    while (!glfwWindowShouldClose(m_window))
    {
        glfwSwapBuffers(m_window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;

}

I should get the maximum available OpenGL context on the running machine, provided that it's above OpenGL 3.3.

这不是它的定义方式。来自 GLFW documentation:

The GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR hints specify the client API version that the created context must be compatible with.

For OpenGL, these hints are not hard constraints, as they don't have to match exactly, but glfwCreateWindow will still fail if the resulting OpenGL version is less than the one requested.

While there is no way to ask the driver for a context of the highest supported version, most drivers provide this when you ask GLFW for a version 1.0 context.

所以“大多数驱动程序”会给你所期望的,但这并不能保证。

典型的用法是您指定支持您的代码使用的所有功能的最低版本。然后你不在乎你是否得到了那个版本,或者可能是更高的版本。但是你知道如果不支持最低版本你会失败。

如果您想动态测试支持哪个版本,最好的办法可能是首先指定您可以利用的最高版本,然后测试 return 值 glfwCreateWindow()。如果失败,只要失败就降低版本,然后再次调用glfwCreateWindow(),直到达到可以运行的最低版本。然后您可以跟踪哪个版本成功,或 glGetString(GL_VERSION) 报告的版本,并使用它来决定在 运行 时间可以使用哪些功能。

您从 glGetString 收到的版本并不意味着该版本的功能有上限。根据我们的经验,我们收到一个 3.3 上下文,它可以执行该驱动程序的任何上下文可以执行的所有操作(我的意思是 4.2+ 版本功能)。您只需要担心您需要的驱动程序的最低版本。