mousebird-consulting-inc / WhirlyGlobe

WhirlyGlobe Development
Other
828 stars 255 forks source link

Changing color of a MaplyQuadImageTilesLayer without flickering #443

Closed JesseCrocker closed 8 years ago

JesseCrocker commented 8 years ago

Im trying to implement changing the opacity of a MaplyQuadImageTilesLayer when a UISlider is changed. To set the opacity im setting the color property of the layer. Changing the color does not take effect immediately, and the only way i have found to get it to take effect is by calling [imageLayer reset] which has an unwanted side effect of unloading all the tiles, and reloading them with the new color. The images are coming from a cache, so it doesn't take long to reload them, but it still results in the map flickering as the tiles are all removed and readded.

Is there any way to get the change in color to take effect without all the tiles in the layer being removed and reloaded?

mousebird commented 8 years ago

Well, this ought to just work. Can you give me a simple repo case? I'll just fix this under support.

JesseCrocker commented 8 years ago

https://github.com/trailbehind/WhirlyGlobe/tree/testcase/layer-alpha https://github.com/trailbehind/WhirlyGlobe/blob/testcase/layer-alpha/WhirlyGlobeSrc/WhirlyGlobeComponentTester/WhirlyGlobeComponentTester/TestViewController.m#L2557

mousebird commented 8 years ago

Ah, turns out I was wrong: // Note: We can't change the color of existing drawables. The color is in the data itself.

You just want to change the alpha? We could do that with small shader change.

mousebird commented 8 years ago

You can't do it with the default shader, but a small tweak makes it work just fine.

NSString vertexShaderNoLightTri = @"uniform mat4 u_mvpMatrix; \n" "uniform float u_fade; \n" "uniform float u_fadeOverride;\n" "attribute vec3 a_position; \n" "attribute vec2 a_texCoord0; \n" "attribute vec4 a_color; \n" "attribute vec3 a_normal; \n" "\n" "varying vec2 v_texCoord; \n" "varying vec4 v_color; \n" "\n" "void main() \n" "{ \n" " v_texCoord = a_texCoord0; \n" " v_color = a_color * u_fade * u_fadeOverride;\n" "\n" " gl_Position = u_mvpMatrix \ vec4(a_position,1.0); \n" "} \n" ;

NSString fragmentShaderNoLightTri = @"precision mediump float; \n" "\n" "uniform sampler2D s_baseMap0; \n" "uniform bool u_hasTexture; \n" "\n" "varying vec2 v_texCoord; \n" "varying vec4 v_color; \n" "\n" "void main() \n" "{ \n" " vec4 baseColor = u_hasTexture ? texture2D(s_baseMap0, v_texCoord) : vec4(1.0,1.0,1.0,1.0); \n" " gl_FragColor = v_color \ baseColor; \n" "} \n" ;

JesseCrocker commented 8 years ago

Wow, that works great! Is there a method to remove the shader program when it is no longer in use?

mousebird commented 8 years ago

No, though there probably should be.