LoginSignup
1
5

More than 3 years have passed since last update.

【OpenGL】OpenGL APIのエラーチェック

Posted at

OpenGL APIには戻り値がvoidなものが多い問題

ほとんどのOpenGLのAPIでは戻り値がvoidであり、成功/失敗の判定が出来ない。
例え失敗していたとしても、あたかもAPIが呼び出されていないかの様な挙動となる。

エラーチェックするには?

そこでエラーチェックは、以下のAPIを使う事により確認が可能である。

GLenum glGetError();

OpenGLにおいてエラーは、上記API呼び出しによりエラーが実際に処理されるまでキューに格納される。
つまり、 定期的に上記APIを使って確認してないと、どのAPI呼び出し時にどの様なエラーを引き起こしたのかを知るすべがない。

エラーキューが空の場合、 GL_NO_ERROR を返す。
それ以外の場合は、エラー列挙子が返され、そのエラーがキューから削除される。

エラーチェック処理をしていないをしていない箇所があることも想定し、
各OpenGL API をコールした前 or 後に現在キューにある全てのエラーを破棄 or 取得する様にするのが良い。

以下の様な処理となります。

GLenum err;
while ((err = glGetError ()) != GL_NO_ERROR )
{ 
    ;//エラーを処理/ロギング
}

エラーコードについて

glGetError()によって返却されるエラーコードとそれが指す状態については以下を参照してください。

エラーコード 説明
GL_NO_ERROR 0x0000 エラーキューが空の場合
GL_INVALID_ENUM 0x0500 呼んだ関数の列挙型の引数がその関数で使えない場合
GL_INVALID_VALUE 0x0501 呼んだ関数の引数の値が無効な値もしくは範囲外の場合
GL_INVALID_OPERATION 0x0502 現在のステートで無効な操作をしている場合、もしくは廃止された関数を呼び出した場合(*1)
GL_STACK_OVERFLOW 0x0503 スタックのプッシュ操作がスタックのサイズの上限を超える場合
GL_STACK_UNDERFLOW 0x0504 スタックがすでに最下点にあるため、スタックのポッピング操作を実行できない場合
GL_OUT_OF_MEMORY 0x0505 実行するのにメモリが足りない場合(このエラーを返した場合そのOpenGL関数の動作は未定義)
GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 完了していないフレームバッファから読み込みまたは書き込みをしようとした場合
GL_CONTEXT_LOST 0x0507 グラフィックカードがリセットされたためにOpenGLのコンテキストが失われた場合

(*1) 例えば、廃止されたAPIを呼び出した場合。

エラー処理時の注意点

しかし、上記の通り各OpenGL API のコール前後に現在キューにある全てのエラーを処理すると パフォーマンスが大幅に低下する。

その理由は以下の二点。

  • エラー状態をチェックして返すだけでなく、OpenGL API コール自体のオーバーヘッドも発生する。
  • マルチスレッドを使用するドライバの場合、glGetError()をコールする事によりドライバ内のスレッド間で同期が発生する。

その為、 glGetError()のコール自体をデバッグビルドに限定した方が良い。

参考

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetError.xhtml
https://www.khronos.org/opengl/wiki/Common_Mistakes#Checking_for_OpenGL_Errors

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5