POINT
簡単なものから順番にして, 正しく Rendeing されているか確認すること
追加して問題がおきれば, そこが原因
DESC
OpenGL のエラーを取得するには glGetError() を利用する。
POINT
OpenGL はエラーを起こすような命令がくると、その処理を実行しないでエラーフラグを立てる。
アプリケーションは継続するためアプリケーション側はチェックをする必要がある。
WARNING
コンパイルエラーにはならないが、OpenGL への命令としてはエラーになるケースがあるため
エラーチェックをする必要がある。
無効なマクロ定数の指定はコンパイルエラーにならないが、
OpenGL はエラーを発生させて命令を実行しない。
// これは Compile ERROR ではないが、OpenGL への命令としてはエラー
glTexEnvi( GL_S, GL_TEXTURE_ENV_MODE, GL_OBJECT_PLANE );
POINT
常に Error Check する習慣をつけること
ただし Cost は 0 ではないので , Release 時は消す。
Error の仕様は変更されるため, Error 内容に依存した Code はかかない
Error が発生する場合, GL は Command を無視する
マクロを利用して, リリース時はオフになる仕組みを用意しておく。
#ifdef _DEBUG
# define CHECK_ERROR checkError()
#else
# define CHECK_ERROR
#endif
void checkError() {
GLenum err = glGetError();
if ( err != GL_NO_ERROR ) {
printf( "OpenGL ERROR code %d: %s\n", err, (const char *)gluErrorString( err ) );
}
}
App::init() 時に一度. App::onDraw() の最後でするのがコツ。
正しく描画されない場合は, エラーが発生している可能性があるので
チェックをしておくの無難。
App::init() {
// 初期化時に 1 度チェック
// Error は Debug のみ有効にする
assert( glGetError() == GL_NO_ERROR );
}
App::update() {
// 各フレームでも 一度処理をする
assert( glGetError() == GL_NO_ERROR );
}
// もうはいらない.
行列スタックが一杯のときに, glPushMatrix が呼ばれる場合、GL_STACK_OVERFLOW が発生
// もう空っぽ.
行列スタックがひとつのときに, glPopMatrix が呼ばれる場合、GL_STACK_UNDERFLOW が発生.
// ここで補足する
{
static struct Tbl{
int id;
char *msg;
}tbl[]=
{
GL_NO_ERROR, "エラーなし",
GL_INVALID_ENUM, "Enum 型の引数が範囲外"
GL_INVALID_VALUE, "数値の引数が範囲外"
// size が同じでない Cube Texture
glTexImage2D( GL_CUBE, 32, 64 )
GL_INVALID_OPERATION, "カレントのステートではできない Command を発行した"
GL_OUT_OF_MEMORY, "コマンドを実行するメモリが不足",
GL_STACK_OVERFLOW, "コマンドがスタックのオーバーフローをおこしている"
GL_STACK_UNDERFLOW, "コマンドがスタックのアンダーフローをおこしている"
Stack の Push, Pop がペアになってない
Stack Size の最大数を超えた Push
};
unsigned int err = glGetError();
for( int i=0; i< NROF(tbl); i++ ){
if ( err == tbl[i].id ) {
printf( "ERROR CHECK: %s\n", tbl[i].msg );
break;
}
}
assert( err == GL_NO_ERROR );
}
■ glGetError
SYNTAX
GLenum glGetError();
DESC
エラーコードを返す。
POINT
glGetError() で取得するまで, 新たな ErrorCode は記録されない。
また, glGetError() で取得すると, エラー状態は GL_NO_ERROR にリセットされる。
glGetError() は glBegin() - glEnd() 内でコールするとエラー扱いになる。( GL_INVALID_OPERATION )
■ gluErrorString
SYNTAX
const GLubyte * gluErrorString( GLenum error);
DESC
GL, GLU エラーコードからエラー文字列を取得する。
■ Error
■ デバッグツール
DESC
OpenGL Command 列 の Capture , State をチェックできる
"OpenGL Debugger", "OpenGL Tool" で検索すること
■ ErrorCode
DESC
GL_INVALID_ENUM 0x0500 GLenum型引数が範囲外
GL_INVALID_VALUE 0x0501 数値の引数が範囲外
GL_INVALID_OPERATION 0x0502 カレントのステートでの操作が不適切
// StkMtx の問題.
GL_STACK_OVERFLOW 0x0503 コマンドがスタックのオーバーフローを起こしている
GL_STACK_UNDERFLOW 0x0504 コマンドがスタックのアンダーフローを起こしている
GL_OUT_OF_MEMORY 0x0505 コマンドを実行するメモリが不足
■ glBegin(); glEnd(); の不一致
#if 0
glBegin();
...
#endif
glEnd();
■ texture 初期設定の不一致
初期値が環境によって異なる
初期化のときにすべてのパラメータを明示すること
// mipmap を利用しないことを明示する
// ON
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// OFF
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);