OpenGLES混合bug,alpha正在积累

时间:2014-12-07 22:16:48

标签: java android opengl-es live-wallpaper blending

我正在为Android制作动态壁纸,我将解释它是如何工作的,因为我相信它与问题有关,我很抱歉这个长期的问题,但我需要解释一切因为这个问题很难描述。

我使用的是OpenGLES 2.0,我有一个GLSurfaceView和一个壁纸服务实现,我将它传递给我的渲染器来调用绘图方法,就像大多数OpenGL动态壁纸一样。

我实现渲染器的方式是:在壁纸服务中我有一个独立的线程,每隔X秒调用一次draw方法,GLSurfaceView设置为RENDERMODE_WHEN_DIRTY,所以这个更新线程是绘制时决定的发生。

此外,在服务中,当可见性发生变化时,会有暂停和恢复方法。因此,即使我退出壁纸,服务也会运行,保留所有内容的状态,直到它恢复。

现在针对这个问题,我已经开始透明了,你可以在这里看到:first time rendering

但是当我失去焦点并重新获得壁纸时,我按下Android的壁纸选择器上的后退按钮,或者更改壁纸然后再回到它。事物的阿尔法值会上升。

这是2个网格,左边的那个网格的初始alpha值为0.1,右边的值为0.5。 Initial setup, no focus is lost yet

现在当我离开并回来时,GLSurfaceView onVisibilityChanged方法将被调用,它按预期工作但你可以看到alpha值会因某种原因而增加,并且随着我离开并继续增加:

Exited and went back 1 time 1次 Exited and went back 2 times 2次

我设置网格绘图的方法是在我的片段着色器中,我将在绘制网格之前设置制服的值,并且该制服将乘以纹理颜色。

这是片段着色器:

precision mediump float;

uniform vec4 u_color;       
uniform sampler2D u_texture;
varying vec2 v_textcoord;

void main()
{
    gl_FragColor = u_color * texture2D(u_texture, v_textcoord); 
}  

当然在绘制网格之前,我设置了blend和blendfunc:

GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

GLES20.glUniform4f(DayAndNightRenderer.BaseShader.GetUniform("u_color"), color.r, color.g, color.b, 0.5f);      

texture.Bind();

mesh.Draw(GLES20.GL_TRIANGLE_FAN, DayAndNightRenderer.BaseShader);

GLES20.glDisable(GLES20.GL_BLEND);

和网格绘图,即使在绘图之前设置了颜色均匀:

GLES20.glUniformMatrix4fv(shader.GetUniform("u_transmat"), 1, false, Transform.GetProjectedTransformationMatrix().ToFloatBuffer());     

GLES20.glEnableVertexAttribArray(shader.GetAttribute("a_pos"));
GLES20.glEnableVertexAttribArray(shader.GetAttribute("a_textcoord"));

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[0]);

GLES20.glVertexAttribPointer(shader.GetAttribute("a_pos"), 3, GLES20.GL_FLOAT, false, Vertex.SIZE, 0);
GLES20.glVertexAttribPointer(shader.GetAttribute("a_textcoord"), 3, GLES20.GL_FLOAT, false, Vertex.SIZE, Vertex.POS_SIZE);

GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, IBO[0]);    

GLES20.glDrawElements(primitive, size, GLES20.GL_UNSIGNED_INT, 0);      

GLES20.glDisableVertexAttribArray(shader.GetAttribute("a_textcoord"));
GLES20.glDisableVertexAttribArray(shader.GetAttribute("a_pos"));

到目前为止我尝试过的事情:

  • 更改混合功能,似乎不会影响添加到Alpha值的错误
  • 在焦点丢失之间重新加载着色器
  • 清除帧缓冲区,设置GLES20.glClearColor(0f,0f,0f,0f);启动并调用GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);每一帧

以上都没有工作,并且它不是我用来设置累积的alpha的变量,事物的alpha设置为常量,如我在代码中所见设置颜色均匀。

我对导致这种情况的原因一无所知,它实际上只是失去了壁纸的焦点并重新回到原点,在第一次运行时没有回头,它完全吸引了一切。

顺便说一下,这是onVisibilityChanged方法:

@Override
public void onVisibilityChanged(boolean visible) 
{
    super.onVisibilityChanged(visible);

    if (hassetrenderer) 
    {
        if (visible) 
        {                       
            OpenGLES2WallpaperService.updatehandler.Start();
            glsurfaceview.onResume();                               
            Log.i("DN", "State: running");

        }
        else
        {
            OpenGLES2WallpaperService.updatehandler.Stop();
            glsurfaceview.onPause();
            Log.i("DN", "State: not running");
        }
    }
}       

1 个答案:

答案 0 :(得分:0)

嗯,我通过在销毁GLSurfaceView时杀死壁纸的过程来修复它(android.os.Process.killProcess(android.os.Process.myPid()))。

效果很好,但是我不是很满意,即使在片段着色器中将gl_FragColor.a设置为0.5之后它也不会出现,所以我仍然有不知道是什么导致了它。

从来没有把我作为解决方案杀死这个过程。