9

我已经在一个 GL 程序上工作了一段时间,突然它开始出现错误。在尝试解决这些问题一段时间后,我编写了一个生成相同行为的简短测试程序:

#include <GL/glut.h>
#include <iostream>

#define CHECK_GL_ERR() printError(__LINE__)

void printError(int line)
{
        GLenum err = glGetError();
        if(err != GL_NO_ERROR)
        {
                std::cerr << "GL error on line " << line << ": " << gluErrorString(err) << std::endl;
        }
}

void displayFunc()
{
        CHECK_GL_ERR();
        glBegin(GL_POINTS);
        CHECK_GL_ERR();
        glVertex3f(0, 0, 0);
        CHECK_GL_ERR();
        glEnd();
        CHECK_GL_ERR(); //line 23
        exit(0);
}

int main(int argc, char **argv)
{
        glutInit(&argc, argv);
        glutInitWindowSize(300, 300);
        glutCreateWindow("Test");

        glutDisplayFunc(displayFunc);

        glutMainLoop();
}

当我运行这个程序时,它会给出输出:

GL error on line 23: invalid operation

所以似乎glEnd();导致错误。文档说:

GL_INVALID_OPERATION 如果执行 glEnd 而前面没有 glBegin 则生成。

在我的代码中不是这种情况。那么有没有人看到,为什么这段代码会给出错误消息?

PS:当然我知道 glBegin/End 已经被弃用/删除了很长时间,但是将一些少量代码组合在一起非常方便。在 GL 决定脾气暴躁之前,该程序也可以正常运行。

编辑

我刚刚用 glslDevil 做了一个跟踪,它给出了:

W! Program Start
|  glXQueryExtension(0x1ab03f0, (nil), (nil))
|  glXChooseFBConfig(0x1ab03f0, 0, 0x7fffb8fcf8b0, 0x7fffb8fcf8a4)
|  glXGetVisualFromFBConfig(0x1ab03f0, 0x111)
|  glXGetProcAddressARB(0x7f93c37526e5)
|  glXCreateNewContext(0x1ab03f0, 0x111, 32788, (nil), 1)
|  glXIsDirect(0x1ab03f0, 0x1ac8de8)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glDrawBuffer(GL_FRONT)
|  glReadBuffer(GL_FRONT)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glViewport(0, 0, 300, 300)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glGetError()
|  glBegin(GL_POINTS)
|  glGetError()
|  glVertex3f(0,000000, 0,000000, 0,000000)
|  glGetError()
|  glEnd()
W! OpenGL error GL_INVALID_OPERATION detected
|  glGetError()
|  glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8)
|  glXDestroyContext(0x1ab03f0, 0x1ac8de8)
E! Child process exited
W! Program termination forced!
4

1 回答 1

15

经过一些测试,我发现你的程序有两个简单的问题:

  1. 不得在 glBegin/glEnd 块内使用 glGetError。API对此很严格。但是错误只发生glEnd 之后。如果您阅读 API,您会发现错误可能会传播:它只发生在 glEnd 之后。
  2. 当您在显示函数中使用 exit(0) 时会发生分段错误这只发生在 Intel 驱动程序中。)这是因为 GL 上下文尚未被释放,并且出现了驱动程序错误。所以你应该避免退出显示功能。
于 2012-11-18T16:25:11.970 回答