来自 glGetError() 的 INVALID_ENUM 错误。 glGetError 与 glu、glew、glfw?

Posted

技术标签:

【中文标题】来自 glGetError() 的 INVALID_ENUM 错误。 glGetError 与 glu、glew、glfw?【英文标题】:INVALID_ENUM error from glGetError(). glGetError with glu, glew, glfw? 【发布时间】:2014-09-01 19:27:47 【问题描述】:

每次调用 OpenGL 函数后,我都会在代码中添加 glGetError()

实际上我没有调用glGetError(),而是我编写的一个函数(DisplayGlErrors())在控制台中打印所有错误(通过循环)。所以现在我想,每次我在(例如)gluLookAt() 之后立即调用我的函数时,我应该能够通过该函数获取由 openGL 引起的所有错误。

现在谈谈我的问题。从这段代码:

GL_engine::GL_engine(Application* appli):engine(appli), width(get_parent()->getWidth()), height(get_parent()->getHeight())

  if (GLEW_OK != glewInit()) // glew needs to be initialised, otherwise we get an error, AFTER a windows has been created BUT BEFORE using buffers
  
    std::cout << "glewInit() failed" << std::endl;
    exit(EXIT_FAILURE);
  
  DisplayGlErrors(__FILE__, __LINE__);
  glGetIntegerv( GL_MAJOR_VERSION, &contextMajor );                     DisplayGlErrors(__FILE__, __LINE__);
  glGetIntegerv( GL_MINOR_VERSION, &contextMinor );                     DisplayGlErrors(__FILE__, __LINE__);
  std::cout << "Created OpenGL " << contextMajor <<"."<< contextMinor << " context" << std::endl;
  glClearColor(0.25f, 0.25f, 0.25f, 1.0f);                              DisplayGlErrors(__FILE__, __LINE__);
  cam = Camera();                                                       DisplayGlErrors(__FILE__, __LINE__);
  worldAxis.initialise(); DisplayGlErrors(__FILE__, __LINE__);          DisplayGlErrors(__FILE__, __LINE__);
  worldGrid.initialise(); DisplayGlErrors(__FILE__, __LINE__);          DisplayGlErrors(__FILE__, __LINE__);

我得到了(在控制台中):

OpenGL error #1: INVALID_ENUM(/WelcomeToYourPersonalComputerInferno/666/src/GL_engine.cc, 40)
OpenGL error #1: INVALID_ENUM(/WelcomeToYourPersonalComputerInferno/666/src/GL_engine.cc, 41)
Created OpenGL 0.0 context

n.b. : contextMajorcontextMinorGLint 变量。

我不知道这些 INVALID_ENUM 是什么意思...我什至认为 OpenGL 也不知道...

if for any reason you want to look inside my code, I just updated my git

最后,因为我在我的程序中使用 GLFW、GLU、GLEW。我想知道在我从这些库中调用一个函数之后调用glGetError()(仍然是DisplayGlErrors())是否有意义。

【问题讨论】:

【参考方案1】:

这里有点鸡和蛋的问题。 glGetIntegerv() 的参数 GL_MAJOR_VERSIONGL_MINOR_VERSION 仅在 OpenGL 3.x 中引入(一些规范信息建议 3.0,一些 3.1)。您的上下文似乎至少没有此版本,因此您无法使用此 API 来检查版本。

如果您的代码至少需要 3.x 才能运行,您应该在创建上下文时指定它。在 GLFW 中,glfwWindowHint() 调用似乎用于此目的。

要获得所有 OpenGL 版本支持的版本,您可以使用glGetString(GL_VERSION)。这个调用从 OpenGL 1.0 开始就可用,所以它可以在所有可能的上下文中工作。

关于何时调用glGetError():在开发过程中调用它并没有什么坏处。如果您关心软件的性能,您只需确保禁用/删除对发布版本的调用。对于您提到的特定库:

GLEW:我认为您通常不会在 glewInit() 之后从 GLEW 调用任何内容。除了glewIsSupported()。无论如何,GLEW 只是提供对 OpenGL 入口点的访问,我不相信它会自己调用 GL。所以我认为在 GLEW 调用后调用 glGetError() 没有用。

GLU:这些调用肯定会调用 OpenGL,因此在它们之后调用 glGetError() 是有意义的。请注意,GLU 已被弃用,并且不再适用于 OpenGL 核心配置文件。

GLFW:它提供了窗口系统接口的抽象,所以我不希望它进行 OpenGL 调用。在这种情况下,调用glGetError() 似乎没有必要。它有自己的错误处理 (http://www.glfw.org/docs/latest/group__error.html)。

这部分是偏好问题。我个人认为没有必要在每次通话后拨打glGetError()。由于错误具有粘性,因此您始终可以检测到错误何时发生,即使它来自较早的调用,并在必要时进行搜索。我大多只是在主绘图功能的末尾放了一个这样的检查:

assert(glGetError() == GL_NO_ERROR);

如果这触发了,我开始在代码中传播更多这些检查,直到我将其缩小到特定调用。找到并修复错误后,我会再次删除这些额外的调用。

在每次通话后始终进行检查显然可以更快地告诉您错误发生的确切位置。但是在阅读和维护代码时,我会发现到处都是检查会分散注意力。你真的必须弄清楚什么最适合你。

【讨论】:

感谢您的回答,非常完美!我知道 GLU 已被弃用,我想将其删除,但有很多事情要做...实际上我在很多地方添加了glGetError() 调用,只是为了检查一切是否正常,如果有问题直接拨打电话.我将来会删除它们。再次感谢您

以上是关于来自 glGetError() 的 INVALID_ENUM 错误。 glGetError 与 glu、glew、glfw?的主要内容,如果未能解决你的问题,请参考以下文章

我的OpenGL学习进阶之旅解决OpenGL在使用glUniform系列api时出现了 GL_INVALID_OPERATION 1282错误

OpenGL:glGetError() 没有重置它的标志?

OpenGL glGetError 1281 错误值

glCheckFramebufferStatus 返回 0 并且 glGetError 中没有错误 [关闭]

调试OpenGL比在每个命令后调用glGetError有更好的方法吗?

Discord bot 来自 PC 的普通用户名,但来自手机的 @invalid-user