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は、glBeginが先行せずにglEndが実行された場合に生成されます。

これは私のコードには当てはまりません。では、なぜこのコードがエラーメッセージを表示するのか、誰にもわかりませんか?

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

いくつかのテストの結果、プログラムに2つの簡単な問題があることがわかりました。

  1. glBegin/glEndブロック内でglGetErrorを使用しないでください。APIはそれについて厳格です。ただし、エラーはglEndの後でのみ発生します。APIを読むと、エラーが伝播する可能性があることがわかります。これは、glEndの後でのみ発生します。
  2. 表示機能内でexit(0)を使用すると、セグメンテーション違反が発生します(これは、Intelドライバーでのみ発生します)。これは、GLコンテキストがまだ解放されておらず、ドライバーのバグが発生したために発生します。したがって、表示機能内での終了は避けてください。
于 2012-11-18T16:25:11.970 に答える