为什么对glfwWindowHint()进行了一些调用后glewInit()导致GL_INVALID_ENUM

Loc*_*yer 3 opengl glew glfw

由于某些原因,当我调用glfwWindowHint()时:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
Run Code Online (Sandbox Code Playgroud)

然后致电至:

glewInit()
Run Code Online (Sandbox Code Playgroud)

我最终遇到glError:GL_INVALID_ENUM。当我遗漏所有的glfwWindowHint()调用时,一切正常,并且没有设置glError。我使用这些库的方式有误吗?或者这是glfw中的错误,还是有问题?

请注意,我正在使用glew-1.10.0和glfw-3.0.3

这是一个简单的程序来说明我遇到的问题:

#include <iostream>

#include "GL/glew.h"
#include "GLFW/glfw3.h"

int main(char* argc, char* argv[])
{
    GLFWwindow* window;

    if (!glfwInit())
    {
        return -1;
    }

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

    window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    //glewExperimental = GL_TRUE; tried commenting this out but I still get the error
    if(glewInit() != GLEW_OK)
    {
        return -1;
    } 
    switch(glGetError())
    {
    case GL_INVALID_ENUM:
        std::cout << "why is this happening?";
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*man 5

因为在核心配置文件上下文中,使用来查询扩展字符串是无效的glGetString (...)。您必须glGetStringi (...)一个一个地使用和查询每个扩展。坦白地说,这是一个糟糕的设计,因为glGetStringi必须通过大多数平台上的扩展加载机制来加载。这是种鸡与蛋的情况,核心配置文件中的正确行为肯定是glewExperimental = TRUE在初始化之前使用,而忽略紧随其后的无效枚举错误glewInit (...)

我应该指出,这并不代表做错了。幕后如何实现GLEW以及OpenGL ARB的决策有些疑问是一个问题。我本来可以GL_EXTENSIONS查询有效的东西,glGetString (...)但定义了一些特殊的字符串(例如“ GL_CORE_PROFILE”)以返回核心配置文件。那么,按照我的看法,每个人都会赢。


顺便说一下,不是glfwWindowHintmajor.minor 3.3导致此问题出现。实际上是您对的使用GLFW_OPENGL_CORE_PROFILE。核心配置文件仅对OpenGL 3.2+有效,因此,仅当main.minor≥3.2 core 结合使用时,此问题才会显现出来。