Question

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.

Was it helpful?

Solution

What happens if you remove these lines?

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

gaus and offset are not uniforms. They are assigned constant values inside main(). And I don't think you should declare variables with the same names as uniforms.

I remember reading that when a shader is compiled, the compiler is really good at stripping unnecessary code from the shader. When you leave out the line

gl_FragColor = outSum; 

or assign

texture2D(s_texture, textureCoordinate) 

to gl_FragColor, gaus and offset are not used to calculate the final value of gl_FragColor, so it is possible that they are being stripped out and the variable naming collisions don't occur. When you assign outSum to gl_FragColor, gaus and offset are used to calculate outSum, so they are not stripped and naming collisions occur, causing errors.

OTHER TIPS

glUseProgram can only throw GL_INVALID_OPERATION if:

  1. the program is not a valid program object.
  2. the program's last link operation was not successful.

Obviously your writing to this variable caused a shader compilation or linking error which you did not detect. So start catching your compiler/linker errors instead of ignoring them.

This is more of an extension to Nicol's answer.

I ran into the same issue and turns out that the link for the program failed. Unfortunately glGetError after glLinkProgram does not return an error, and I did not end up catching it. I added the following that helped me log errors after the link, and has been very useful.

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

BTW, in my case I was exceeding the number of supported attributes in the vertex shader.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top