为啥我没有使用 GLFW 获得向前兼容的 OpenGL 上下文?

Posted

技术标签:

【中文标题】为啥我没有使用 GLFW 获得向前兼容的 OpenGL 上下文?【英文标题】:Why am I not getting a forward compatible OpenGL context with GLFW?为什么我没有使用 GLFW 获得向前兼容的 OpenGL 上下文? 【发布时间】:2015-01-04 04:24:10 【问题描述】:

据我所知,当我在 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;


【问题讨论】:

您是否尝试过任何其他个人资料window hints,例如GLFW_OPENGL_ANY_PROFILEGLFW_OPENGL_COMPAT_PROFILE @JoachimPileborg 将此设置为 GLFW_OPENGL_COMPAT_PROFILE 似乎已修复它,但为什么呢?它应该以任何一种方式工作,此外,我想要一个核心配置文件。有什么办法可以获得最大的核心配置文件? 您为什么想要支持的最高版本?如果他们稍后删除您的代码使用的函数怎么办? 【参考方案1】:

我应该在正在运行的机器上获得最大可用的 OpenGL 上下文,前提是它高于 OpenGL 3.3。

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

GLFW_CONTEXT_VERSION_MAJOR 和 GLFW_CONTEXT_VERSION_MINOR 提示指定创建的上下文必须兼容的客户端 API 版本。

对于 OpenGL,这些提示不是硬约束,因为它们不必完全匹配,但如果生成的 OpenGL 版本低于请求的版本,glfwCreateWindow 仍然会失败。

虽然无法向驱动程序询问受支持的最高版本的上下文,但当您向 GLFW 询问 1.0 版上下文时,大多数驱动程序都会提供此信息。

所以“大多数司机”会给你你所期望的,但这并不能保证。

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

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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于为啥我没有使用 GLFW 获得向前兼容的 OpenGL 上下文?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 glfw 窗口上没有使用 opengl 显示位图图像?在 C++ 中读取位图图像文件时出现问题

简单 VBO 示例的问题

OpenGL/GLFW:为啥将电视用作笔记本电脑的主显示器时检测到的鼠标位置不正确?

我的渲染技术进阶之旅glfw库简单介绍

我的渲染技术进阶之旅glfw库简单介绍

我的渲染技术进阶之旅glfw库简单介绍