GLSL:エラーハンドリング

glsl-error-handling.png

便利コード

public void GetProgramInfo(int _param){
    int[] ok = new int[1];
    GLES20.glGetProgramiv(mProgram,_param, ok,0);
    if(ok[0]==0){
        Log.e(TAG,"error ");
        Log.e(TAG,GLES20.glGetProgramInfoLog(mProgram));
    }
 
}

glGetShaderiv

glGetShaderiv(GLuint shader,GLenum pname,GLint *params);

glGetShaderiv(shader,GL_SHADER_TYPE...);

return s GL_VERTEX_SHADER,or GL_FRAGMENT_SHADER
  • GL_SHADER_TYPE
  • GL_DELETE_STATUS
  • GL_COMPILE_STATUS….ちゃんとシェーダがコンパイルできたらparamsにはGL_TRUEが返る。失敗したらGL_FALSEが返る。
  • GL_INFO_LOG_LENGTH
  • GL_SHADER_SOURCE_LENGTH

glGetProgramiv

  • GL_DELETE_STATUS
  • GL_LINK_STATUS
  • GL_VALIDATE_STATUS
  • GL_INFO_LOG_LENGTH
  • GL_ATTACHED_SHADERS
  • GL_ACTIVE_ATTRIBUTES
  • GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
  • GL_ACTIVE_UNIFORMS
GL_ACTIVE_UNIFORM_MAX_LENGTH
現在アクティブなユニフォーム変数の名前の最大文字数。なんでこれを知る必要が???

ちゃんとリンクできたかチェックする

bool checklinkstatus(GLuint _program){
        GLint linkStatus = GL_FALSE;
            glGetProgramiv(_program, GL_LINK_STATUS, &linkStatus);
            if (linkStatus != GL_TRUE) {
                GLint bufLength = 0;
                glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &bufLength);
                if (bufLength) {
                    char* buf = (char*) malloc(bufLength);
                    if (buf) {
                        glGetProgramInfoLog(_program, bufLength, NULL, buf);
                        printf("error=%s",buf);
                        free(buf);
                    }
                }
                glDeleteProgram(_program);
                _program = 0;
                return false;
            }
            return true;
    }

glGetShaderSource

glGetShaderInfoLog

シェーダにスペルミスがないかチェック

このコードは埋め込むタイミングに注意!
埋め込んでも良いタイミング

  • glCompileShaderの後
void GetShaderInfoLog(GLuint shader)
{
    GLsizei bufSize;
 
    /* シェーダのコンパイル時のログの長さを取得する */
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &bufSize);
 
    if (bufSize > 1) {
        GLchar *infoLog = (GLchar *)malloc(bufSize);
 
        if (infoLog != NULL) {
            GLsizei length;
 
            /* シェーダのコンパイル時のログの内容を取得する */
            glGetShaderInfoLog(shader, bufSize, &length, infoLog);
            TRACE("InfoLog:\n%s\n\n", infoLog);
            free(infoLog);
        }
        else
            TRACE("Could not allocate InfoLog buffer.\n");
    }
}

これを書くと、このように
warning C7502: OpenGL does not allow type suffix 'f' on constant literals
0(8) : warning C7503: OpenGL does not allow C-style casts
0(8) : warning C7503: OpenGL does not allow C-style casts
0(8) : warning C7503: OpenGL does not allow C-style casts
0(12) : warning C7011: implicit cast from "float" to "vec4"
0(13) : error C0000: syntax error, unexpected '}', expecting ',' or ';' at token "}"
0(4) : error C1068: too much data in type constructor

埋め込む位置としてはglCompileShaderの後
[[code type="Cpp"]]
glCompileShader(shader);シェーダをコンパイルする。
GLint compiled = 0;
//コンパイルチェック
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GetShaderInfoLog(shader);
シェーダのコードにミスがないかチェック
glDeleteShader(shader);
}
何行目がエラーなのか教えてくれる。

glGetProgramInfoLog

glGetAttachedShaders

glIsShader

glIsProgram


opengl-es2-error

サポートサイト Wikidot.com opengl-es2-error