1
votes

I have a fragment shader in an android app using GLES 2.0 which works fine on the emulator but crashes with a "Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1)" on a Nexus 4 when I try to link the shader program.

I basically started from Google's tutorial (http://developer.android.com/training/graphics/opengl/draw.html) and took it from there.

This is the vertex shader:

uniform mat4 uMVPMatrix;
varying vec2 vTexcoord;
attribute vec4 vPosition;
void main() {
  gl_Position = uMVPMatrix * vPosition;
  vTexcoord = vPosition.xy * vec2(0.5) + vec2(0.5);
}

This is the fragment shader:

precision mediump float;
uniform sampler2D uTexture1;
uniform sampler2D uTexture2;
uniform float pointX;
uniform float pointY;
uniform float opening;
uniform float openingBufferZone;
uniform vec4 aColor;
varying vec2 vTexcoord;
float sizeX = 2048.0;
float sizeY = 512.0;
void main() {
  float x = (vTexcoord.x * sizeX) - pointX;
  float y = (vTexcoord.y * sizeY) - pointY;
  float distance = x * x + y * y;
  if (distance < opening) {
    gl_FragColor = texture2D(uTexture2, vTexcoord) * aColor;
  } else {
    if (distance >= opening && distance < opening + openingBufferZone) {
      float inner = (distance-opening)/openingBufferZone;
      vec4 c1 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture1, vTexcoord) * aColor);
      vec4 c2 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture2, vTexcoord) * aColor);
      gl_FragColor = c1 + c2;
    } else {
      gl_FragColor = texture2D(uTexture1, vTexcoord) * aColor;
    }
  }
}

This is how I load the shaders:

int vertexShader = GLActivity.loadShader(GLES20.GL_VERTEX_SHADER,
                                                   vertexShaderCode);
int fragmentShader = GLActivity.loadShader(GLES20.GL_FRAGMENT_SHADER,
                                                     fragmentShaderCode);
mProgram = GLES20.glCreateProgram();             
GLES20.glAttachShader(mProgram, vertexShader);   
GLES20.glAttachShader(mProgram, fragmentShader); 
GLES20.glLinkProgram(mProgram);                  

The error occurs when trying to execute that last line GLES20.glLinkProgram(mProgram);.

For some reason these 2 lines in the vertex shader seem to cause the trouble:

vec4 c1 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture1, vTexcoord) * aColor);
vec4 c2 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture2, vTexcoord) * aColor);

If I simply change them to

vec4 c1 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture1, vTexcoord) * aColor);
vec4 c2 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture1, vTexcoord) * aColor);

or

vec4 c1 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture2, vTexcoord) * aColor);
vec4 c2 = (vec4(inner,inner,inner,1.0) * texture2D(uTexture2, vTexcoord) * aColor);

and leave everything else as it is, the program runs fine (though obviously not as intended).

3
Since it is probably not the shader itself that causes the problem but the code that uses and interfaces it, we need to see more code. I would suspect you of not properly setting those sampler2D uniforms from your application code or something similar.Christian Rau
Thanks for the quick reply. I added some (hopefully relevant) parts of the code.icke
Hmm, looks quite good everything. What you could do is check if the returned uniform locations are not -1 (which means the GLSL compiler cannot find them), because in this case glGetUniformLocation would not throw a GL error. But I don't have any idea why they would not be existent (though the shader code might also help).Christian Rau
I added the complete shader code. I will check the return values, too.icke
I tried to check the return values, but found that the error already occurs much earlier when trying to link the shader program. I'm editing the question to reflect that. Thanks for your ideas already!icke

3 Answers

1
votes

Had the same affect by using this line.

gl_FragColor = vec4(float(i) / 100.0,0.0,0.0,1.0);

looks like opengles doesn't like it when you embed operations within a function.

0
votes

Going to post this as an answer, as the workaround may not be seen in the comments.

Changing one of the lines to (e.g.) vec4 c1 = (texture2D(uTexture1, vTexcoord) * aColor * vec4(inner,inner,inner,1.0));, i.e. simply changing the order of the operands makes the shader work again.