Reputation: 90
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.
Upvotes: 0
Views: 2119
Reputation: 500
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.
Upvotes: 0
Reputation: 473447
glUseProgram
can only throw GL_INVALID_OPERATION
if:
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.
Upvotes: 2
Reputation: 5459
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.
Upvotes: 2