Why does glewInit() result in GL_INVALID_ENUM after making some calls to glfwWindowHint()
Question
For some reason when I call glfwWindowHint():
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
and later make a call to:
glewInit()
I end up getting a glError: GL_INVALID_ENUM. When I leave out all of the glfwWindowHint() calls everything works fine and no glError is set. Am I using these libraries incorrectly, or if this is a bug in glfw, or glew?
Note that I'm using glew-1.10.0 and glfw-3.0.3
Here's a simple program to illustrate the issue I'm seeing:
#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?";
}
}
Solution
Because in a core profile context, it is invalid to query the extension string using glGetString (...)
. You have to use glGetStringi (...)
and query each extension one-by-one. Frankly this is terrible design, since glGetStringi
has to be loaded through the extension loading mechanism on most platforms. It is a chicken and egg sort of situation, the proper behavior in a core profile is definitely to use glewExperimental = TRUE
before initialization and ignore an invalid enum error immediately following glewInit (...)
.
I should point out that this is nothing that you are doing wrong. It is a problem with how GLEW is implemented behind the scenes and a somewhat questionable decision by the OpenGL ARB. I would have left GL_EXTENSIONS
a valid thing to query with glGetString (...)
but defined some special string (e.g. "GL_CORE_PROFILE") to return in a core profile. Everybody wins then, the way I see it.
Incidentally, it is not theglfwWindowHint
for major.minor 3.3 that causes this issue to show up. It is actually your use of GLFW_OPENGL_CORE_PROFILE
. Core profiles are only valid for OpenGL 3.2+, so this issue will only manifest itself with a combination of major.minor ≥ 3.2 and core.