• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Android [SOLVED] Shader stops working on Android after using Home/Recent

C

Charyb

Guest
Using GMS v1.99.505

On Android my shader works perfectly fine until I use the "Home" button or the "Recent Apps" button.
Afterwards when I return to my app, it's as if the shader has turned off completely, not sure why.

Here's my shader fragment (shd_overlay):
Code:
//
// Overlay Shader
//

varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform sampler2D texStage;

void main()
{
    vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
    vec4 outColor = vec4(0.0, 0.0, 0.0, inColor.a);
    vec4 overlay = texture2D(texStage, v_vTexcoord);
    
    if (inColor.r > 0.5)
    {
        outColor.r = (1.0 - (1.0 - 2.0 * (inColor.r - 0.5)) * (1.0 - overlay.r));
    }
    else
    { 
        outColor.r = ((2.0 * inColor.r) * overlay.r);
    }

    if (inColor.g > 0.5)
    {
        outColor.g = (1.0 - (1.0 - 2.0 * (inColor.g - 0.5)) * (1.0 - overlay.g));
    }
    else
    { 
        outColor.g = ((2.0 * inColor.g) * overlay.g);
    }

    if (inColor.b > 0.5)
    {
        outColor.b = (1.0 - (1.0 - 2.0 * (inColor.b - 0.5)) * (1.0 - overlay.b));
    }
    else
    { 
        outColor.b = ((2.0 * inColor.b) * overlay.b);
    }
    gl_FragColor = mix(outColor, inColor,1.0 - overlay.a);
}
And the Draw GUI Event of my shader object:
Code:
    if(shader_is_compiled(shader)){
        shader_set(shader);
        texture_set_stage(stage, surface_get_texture(surface_bg));
        //if(surface_get_width(application_surface) != idealWidth)
            //surface_resize(application_surface, idealWidth, idealHeight);

        draw_surface(application_surface, 0, 0);
        shader_reset();
    }
And the logs from the console (I marked where I went home / resumed the app):
 
Have you tried adding a check to make sure the surface exists before you try to use it? Surfaces are destroyed when you exit / suspend the app.

Check that surface_bg exists, not sure about application_surface, I think game maker recreates that itself, but you might want to check that exists as well.

Docs : surface_exists
 
C

Charyb

Guest
Have you tried adding a check to make sure the surface exists before you try to use it? Surfaces are destroyed when you exit / suspend the app.

Check that surface_bg exists, not sure about application_surface, I think game maker recreates that itself, but you might want to check that exists as well.

Docs : surface_exists
Yup I was already doing this. If it doesn't exist it automatically re-creates it.

However on Android when you suspend the app and come back, the surface still exists but something weird happens to it, not sure what.

I drew it on the screen directly before and after suspending the app. When I came back to the app, it was drawing in all black (image 2 of the image gallery down below) which is weird because it's supposed to be drawing a rectangle in a purple hue color. So it didn't get destroyed since the game thought it existed still. So I free'd it anyways and re-created it and the surface re-appears fine and everything seems to be okay. If I free it and re-create it a second time, the shader / surface_bg seems to break (I honestly don't know which one is breaking). The surface itself when I reset it a second time seems fine because it's drawing the correct color, but the shader is messed up after resetting the surface_bg surface a second time.

It's hard to explain what exactly happens so I tried different shaders just to see if it was indeed the shader. Same results, something breaks.

Here's screenshots of another shader I'm using that clearly shows something is messed up:
http://imgur.com/a/5KKC3

This is not the shader I want to use (it looks horrible on this game haha) but just to demonstrate that something is messing up.

So the first image, everything is great. I suspend the app and come back to it, the shader isn't working nor is the surface (second image). I then free the surface_bg surface, re-create it, and then we come to the third image which puts it all back to normal, great. Then, say I were to re-create the surface_bg surface a second time, the fourth image shows what happens when I do this. The fourth image in that gallery is essentially what I mean by the shader 'breaking'.

It seems that shaders that use this uniform:
Code:
uniform sampler2D texStage;
are affected by this in that way. So I honestly don't know if it's the shader or the surface_bg surface that's causing this problem on Android. On Windows it works perfectly fine.
I tried another shader that's very similar to the one I used in my first post (that also uses the stage / sample2D / surface_bg) and the same results happen.

I've also tried resetting the texStage uniform, which I set like so:
Code:
stage = shader_get_sampler_index(shader, "texStage");
Still the same results. I even just destroyed and re-created the entire shader object (making sure to free the surface_bg before I re-create it). Same results.
 
C

Charyb

Guest
Do you clear the surface after recreating it?
Code:
if (!surface_exists(surface_bg)){
    surface_bg = surface_create(idealWidth, idealHeight);
    surface_set_target(surface_bg);
    draw_clear_alpha(c_white, 0);
    draw_set_color(shaderColor);
    draw_rectangle(0, 0, surface_get_width(surface_bg), surface_get_height(surface_bg), 0);
    draw_set_color(c_white);
    surface_reset_target();
}
Yes. That's in the step event.

Create Event:
Code:
shader = shd_overlay2;
stage = shader_get_sampler_index(shader, "texStage");
shaderColor = pscolor($18206c); //Converts Photoshop Color values to RGB values
surface_bg = -4;
idealWidth = view_wview[0];
idealHeight = view_hview[0];
EDIT:

Extracted the code from my project and placed it into a .gmz for testing, same results:
http://s000.tinyupload.com/index.php?file_id=58264128976219462574

Run the project on Android. The shader should work fine, you should see a fairly blue looking background image. Hit the 'Home' button or the 'Recent Apps' button and come back.

The blue coloration that shd_overlay had done previously is now clearly not working properly. Double tap the screen (right mouse press) to re-create the surface and reset the shader stage. Nothing will happen, shader/surface_overlay will still produce the same broken image.

Here's images of what it looks like on Android:
 
Last edited by a moderator:
C

Charyb

Guest
I've solved the problem, however there is still an issue with surfaces it seems on Android.

Basically what I did was instead of creating a surface and blitting a color to the screen and extracting the texture from the surface to use with the shader, I instead just make a small background image, filled it with the color I want to be blit to the screen, and extracted the texture from the background and used that with the shader.

So yeah, I've posted a bug report because something seems to be completely broken with surfaces regarding Android devices. Possibly iOS as well so this is not a 100% solution for shaders that require surfaces on mobile.
 
That's good to hear. You seem to be doing everything right as far as I can tell. Could be a bug. Sorry I didn't have a chance to test it on my end. Out of curiosity, did you have a chance to test this on different android hardware to see if it also occurs on other devices?
 
C

Charyb

Guest
That's good to hear. You seem to be doing everything right as far as I can tell. Could be a bug. Sorry I didn't have a chance to test it on my end. Out of curiosity, did you have a chance to test this on different android hardware to see if it also occurs on other devices?
Yeah I did. It occurred on the two devices I have available: Nexus 4 and Nexus 7 (2012).

I would honestly love to know if this breaks on any other newer devices though such as the Nexus 5 or Nexus 6P.
 
Top