glGetError()中出现INVALID_ENUM错误.glGetError与glu、glew、glfw有关

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

本文关键字:glGetError glu glew 有关 glfw 错误 INVALID ENUM      更新时间:2023-10-16

每次调用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也不知道。。。

如果出于任何原因你想查看我的代码,我刚刚更新了我的git

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

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

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

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

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

  • GLEW:我想你通常不会在glewInit()之后从GLEW打任何电话。可能除了glewIsSupported()。无论如何,GLEW只是提供对OpenGL入口点的访问,我不相信它会让GL调用自己。所以我不认为在GLEW呼叫之后呼叫glGetError()是有用的。

  • GLU:这些调用肯定会调用OpenGL,所以在它们之后调用glGetError()是有意义的。请注意,GLU已被弃用,并且不再适用于OpenGL Core Profile。

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

这在一定程度上是一个偏好问题。我个人认为没有必要在每次通话后拨打glGetError()。由于错误是粘性的,所以您总是可以检测错误发生的时间,即使是来自以前的调用,并在必要时进行搜索。我主要只是在主绘图功能的末尾放一张这样的支票:

assert(glGetError() == GL_NO_ERROR);

然后,如果触发了这种情况,我会开始在代码中进行更多的检查,直到我将其缩小到一个特定的调用。一旦我发现并修复了错误,我就会再次删除那些额外的调用。

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