Debug(デバッグ)

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);