0

I'm trying to write a blur filter in GLSL ES 2.0 and I'm getting an Error with the line assigning gl_FragColor. I've not been able to figure out why

#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;
}

The assignment of gl_FragColor causes calls to glUseProgram to error with GL_INVALID_OPERATION. I've tried this without it and it compiles and operates without the error. I'm hoping someone can point me in a direction i haven't looked yet at least because I can't see any reason this isn't working.

EDIT: I solved this. As best I can tell the GLSL-ES on android doesn't allow indexing arrays with non-constant variables. GLSE-ES 2.0 specification page 97 10.25 states it's not directly supported by all implementations and on page 109 it states that loop indices can be considered constant-expressions but not must. I rolled out my loop and it's linking fine now.

Thank you everyone who responded, I was able to narrow this down thanks to your insight.

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

这更像是对尼科尔答案的延伸。

我遇到了同样的问题,结果发现程序的链接失败了。不幸的是glGetErrorafterglLinkProgram没有返回错误,我最终没有抓住它。我添加了以下内容,帮助我在链接后记录错误,并且非常有用。

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 回答