LoginSignup
4

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

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
What you can do with signing up
4