0

GLSL ES 2.0でブラーフィルターを作成しようとしていますが、gl_FragColorを割り当てる行でエラーが発生します。理由がわからない

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 textureCoordinate;
uniform samplerExternalOES s_texture;
void main() {
  float gaus[25] = float[25](0.01739, 0.03478, 0.04347, 0.03478, 0.01739,
                             0.03478, 0.07282, 0.10434, 0.07282, 0.03478,
                             0.04347, 0.10434, 0.13043, 0.10434, 0.04347,
                             0.03478, 0.07282, 0.10434, 0.07282, 0.03478,
                             0.01739, 0.03478, 0.04347, 0.03478, 0.01739);
  float offset[5] = float[5](-2.0, -1.0, 0.0, 1.0, 2.0);
  vec4 outSum = vec4(0.0);
  int rowi = 0;
  for(int i = 0; i < 5; i++){
    vec4 inSum = vec4(0.0);
    for(int j = 0; j < 5; j++){
      inSum += texture2D(s_texture, textureCoordinate + vec2(offset[i], offset[j]))*gaus[j*5+i];
    }
    outSum += inSum*gaus[rowi+i];
    rowi += 3;
  }
  gl_FragColor = outSum;
}

の割り当てによりgl_FragColor、呼び出しは。glUseProgramでエラーになりますGL_INVALID_OPERATION。私はそれなしでこれを試しました、そしてそれはエラーなしでコンパイルして動作します。少なくとも、これが機能していない理由がわからないので、誰かが私をまだ見ていない方向に向けてくれることを願っています。

編集:私はこれを解決しました。最善の方法として、AndroidのGLSL-ESでは、定数以外の変数を使用した配列のインデックス作成は許可されていません。GLSE-ES 2.0仕様97ページ10.25は、すべての実装で直接サポートされているわけではなく、109ページで、ループインデックスは定数式と見なすことができるが、必須ではないと述べています。ループをロールアウトしましたが、リンクは正常になりました。

回答してくださった皆様、ありがとうございました。洞察のおかげでこれを絞り込むことができました。

4

3 に答える 3

2

これらの行を削除するとどうなりますか?

uniform float gaus[25];
uniform float offset[5];

gausとoffsetは均一ではありません。main()内で定数値が割り当てられます。そして、ユニフォームと同じ名前の変数を宣言するべきではないと思います。

シェーダーをコンパイルすると、コンパイラーはシェーダーから不要なコードを取り除くのに非常に優れていることを読んだことを覚えています。あなたがラインを省くとき

gl_FragColor = outSum; 

または割り当てる

texture2D(s_texture, textureCoordinate) 

gl_FragColorに対して、gausとoffsetはgl_FragColorの最終値の計算に使用されないため、それらが削除され、変数の名前の衝突が発生しない可能性があります。outSumをgl_FragColorに割り当てると、gausとoffsetがoutSumの計算に使用されるため、これらが削除されたり、名前の衝突が発生したりして、エラーが発生することはありません。

于 2013-03-17T05:54:42.143 に答える
2

glUseProgram次の場合にのみスローGL_INVALID_OPERATIONできます。

  1. プログラムは有効なプログラムオブジェクトではありません。
  2. プログラムの最後のリンク操作は成功しませんでした。

明らかに、この変数への書き込みにより、検出されなかったシェーダーのコンパイルまたはリンクエラーが発生しました。したがって、コンパイラ/リンカのエラーを無視するのではなく、キャッチし始めてください。

于 2013-03-17T08:26:32.017 に答える
0

これは、ニコルの答えをさらに拡張したものです。

同じ問題が発生し、プログラムのリンクが失敗したことがわかりました。残念ながらglGetError、afterglLinkProgramはエラーを返さず、私はそれをキャッチすることになりませんでした。リンク後にエラーをログに記録するのに役立つ次のものを追加しました。これは非常に便利です。

GLint logLength;
glGetProgramiv( program_id, GL_INFO_LOG_LENGTH, &logLength );
if ( logLength > 0 )
{
    char* log = new char[ logLength + 1 ];
    log[ logLength ] = '\0';
    glGetProgramInfoLog( program_id, logLength, &logLength, log );
    Dbg_Printf( "OpenGL Program Link Log:\n%s\n", log );
    delete[] log;
}

ところで、私の場合、頂点シェーダーでサポートされている属性の数を超えていました。

于 2016-03-24T19:39:26.210 に答える