Opengl: Glgeterror() Returns Invalid Enum After Call to Glewinit()

OpenGL: glGetError() returns invalid enum after call to glewInit()

Did you see the comment on this wiki page?

http://www.opengl.org/wiki/OpenGL_Loading_Library

It mentions why this occurs, and it says "in some cases you may still get GL_INVALID_ENUM after specifying glewExperimental depending on your glew version".

It sounds like it might be safe to ignore as long as you're not seeing any other problems.

Why does glewInit() result in GL_INVALID_ENUM after making some calls to glfwWindowHint()

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.

INVALID_ENUM error from glGetError(). glGetError with glu, glew, glfw?

You have somewhat of a chicken and egg problem here. The arguments GL_MAJOR_VERSION and GL_MINOR_VERSION for glGetIntegerv() were only introduced in OpenGL 3.x (some spec information suggests 3.0, some 3.1). It looks like your context does not have at least this version, so you can't use this API to check the version.

If you need at least 3.x for your code to run, you should specify that on context creation. It looks like the glfwWindowHint() call is used for this purpose in GLFW.

To get the supported version across all OpenGL versions, you can use glGetString(GL_VERSION). This call has been available since OpenGL 1.0, so it will work in every possible context.

On when to call glGetError(): It can't really hurt to call it too much during development. You'll just want to make sure that you disable/remove the calls for release builds if you care about performance of your software. For the specific libraries you mention:

  • GLEW: I don't think you normally call anything from GLEW after glewInit(). Except maybe glewIsSupported(). In any case, GLEW just provides access to OpenGL entry points, I don't believe it makes an GL calls itself. So I don't think calling glGetError() after GLEW calls is useful.

  • GLU: These calls definitely make OpenGL calls, so calling glGetError() after them makes sense. Note that GLU is deprecated, and not available anymore with the OpenGL Core Profile.

  • GLFW: This provides an abstraction of the window system interface, so I wouldn't expect it to make OpenGL calls. In this case, calling glGetError() does not seem necessary. It has its own error handling (http://www.glfw.org/docs/latest/group__error.html).

This is partly a question of preference. I personally don't think that calling glGetError() after each call is necessary. Since the errors are sticky, you can always detect when an error happened, even if it was from an earlier call, and search back if necessary. I mostly just put a check like this at the end of the main draw function:

assert(glGetError() == GL_NO_ERROR);

Then if this triggers, I start spreading more of these checks across the code until I narrowed it down to a specific call. Once I found and fixed the errors, I remove those extra calls again.

Having the checks in place after each call all the time obviously tells you much more quickly where exactly the error happened. But I would find having the checks all over the place distracting when reading and maintaining the code. You really have to figure out what works best for you.

glGetError returns invalid operation - not within Begin/End

glGetError returns the error state of the currently bound OpenGL render context. If there is no context bound, the result of calling glGetError are undefined, i.e. it's a invalid operation at that point.

How to fix GL_INVALID_ENUM error in function call?

  • Do error = glGetError(); after each other call to the GL API for obvious reasons
  • Note, that glGetError() may return multiple error enumerators, so you'd need to call this function in a loop until it returns GL_NO_ERROR or the errors will remain. Clearing errors this way before calling another GL function is possibly also necessary (one does usually not want to clear errors after every single GL call). However, I encountered sort of a bug lately, which caused an endless loop because glGetError() continuously returned the same error.
  • Attach the gDEBugger, to avoid error check clutter
  • If available (at runtime), use ARB_debug_output in a debug mode of your program, for the same reason.

GL_INVALID_ENUM right after context initialization

Vertex array objects are not optional in the core profile. The GL_INVALID_ENUM error is probably coming from somewhere else; you should be getting GL_INVALID_OPERATION. Remember: OpenGL errors are buffered, so you have to keep fetching GL errors until you come back with GL_NO_ERROR.

glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);

Please stop doing this. Forward compatibility is virtually meaningless in a core profile.

glewinit() apparently successful, sets error flag anyway

I had this issue recently too so here is the answer:

OpenGL: glGetError() returns invalid enum after call to glewInit()

So you can discard that error .

Query for GL_MAJOR_VERSION throws invalid enumerant

glGetIntegerv with GL_MAJOR_VERSION or GL_MINOR_VERSION is only supported on GL contexts with version 3.0 and above. See https://www.opengl.org/wiki/Get_Context_Info. If you get an "invalid enum" in response to either of these, it is highly likely that the context you have created does not support OpenGL 3.0 or later.

glGenBuffers - GL_INVALID_OPERATION

It could very well be that the error you are getting is a residual error from GLFW or GLEW.

Try adding this after the library init code:

GLenum error;
while ((error = glGetError()) != GL_NO_ERROR)
{
// print(error), etc...
}

and before you attempt to call any OpenGL function, to clear the error cache.

If the error is indeed caused by GLEW, it may not necessarily be a dangerous one that stops the library from working. So I wouldn't drop the library just because of this issue, which will eventually be fixed. However, if you do decide to fetch the function pointers yourself, GLFW provides the glfwGetProcAddress function, which will allow you to do so in a portable manner.



Related Topics



Leave a reply



Submit