■
OpenGL のエラーハンドリングは、ときに非常に重要である。シェーダ関連の拡張を使用する際には、死活的に重要である。SIGGRAPH 2001 の Course 03 "Performance OpenGL: Platform Independent Techniques" では、次のマクロが紹介されている。
#define CHECK_OPENGL_ERROR( cmd ) \
cmd; \
{ GLenum error; \
while ( (error = glGetError()) != GL_NO_ERROR) { \
printf( "[%s:%d] ’%s’ failed with error %s?n", __FILE__, \
__LINE__, #cmd, gluErrorString(error) ); \
}
デバッグモードではこのマクロを使用して、エラーハンドリングをするべきである。リリースモードでは、もちろん、パフォーマンスと相談することになる。
注意するべきことがひとつある。glBegin と glEnd の間では特定の OpenGL 関数以外は使用してはならない。glBegin のマニュアルには以下のように書かれている。
GL_INVALID_OPERATION is generated if a command other than glVertex, glColor, glIndex, glNormal, glTexCoord, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, glEdgeFlag, glCallList, or glCallLists is executed between the execution of glBegin and the corresponding execution glEnd.
すなわち、glGetError を呼ぶこと自体がエラーを発生させる。glBegin と glEnd の間では上記のマクロは使ってはならない。
さて、まだ、これくらいでは変態が足りないと思わないだろうか。もちろん、変態はこれからである。OpenGL 関数には値を返すものがあることを思い出してほしい。たとえば、
GLboolean enabled(glIsEnable(GL_LIGHTING));
これに、上記のマクロを使用するとしたら、
CHECK_OPENGL_ERROR( GLboolean enabled(glIsEnable(GL_LIGHTING)) );
なんてコードを書く羽目になる。こんなコードを世界の涯てに追いやるために、俺たちは変態になった。さあ、ぷるぷるを始めよう。